cli icon indicating copy to clipboard operation
cli copied to clipboard

flag for -h does not work after set HelpFlag to something else

Open robin11 opened this issue 7 years ago • 11 comments

Hello! I need the "-h" flag for my command ,so I set the HelpFlag to "help",without "h".But it turned out that "-h" still show for help which is not I want! First I set helpFLag to "help"

cli.HelpFlag = cli.BoolFlag{
        Name:"help",
        Usage:"To show help for the tool",
    }

Then in my command "ls", I have a flag "h",but it still shows for help.Hope someone would help!

robin11 avatar Oct 19 '16 01:10 robin11

Hi @Robin11,

With

package main

import (
        "os"

        "github.com/urfave/cli"
)

func main() {
        cli.HelpFlag = cli.BoolFlag{
                Name:  "help",
                Usage: "To show help for the tool",
        }

        cli.NewApp().Run(os.Args)
}

You should see:

➜  cli git:(master) go run /tmp/tmp.go -h 
Incorrect Usage.

NAME:
   tmp - A new cli application

USAGE:
   tmp [global options] command [command options] [arguments...]

VERSION:
   0.0.0

COMMANDS:
     help, h  Shows a list of commands or help for one command

GLOBAL OPTIONS:
   --help         To show help for the tool
   --version, -v  print the version

As you can see, the help message does print, but that is because it considers the passed flag, -h, invalid. Is this the behavior you are describing?

You can override this behavior by setting OnUsageError, like the following:

package main

import (
        "fmt"
        "os"

        "github.com/urfave/cli"
)

func main() {
        cli.HelpFlag = cli.BoolFlag{
                Name:  "help",
                Usage: "To show help for the tool",
        }

        app := cli.NewApp()

        app.OnUsageError = func(context *cli.Context, err error, isSubcommand bool) error {
                fmt.Println("invalid usage")

                return nil
        }

        app.Run(os.Args)
}

Which will show:

➜  cli git:(master) go run /tmp/tmp.go -h
invalid usage

Let me know if this helps!

jszwedko avatar Oct 19 '16 03:10 jszwedko

thanks for your help!I have already see the situation you post,but this is not what i want.Below is the sample code I use.In the comand ls,I have a "-h " flag,but it does not work!

package main

import (
    "github.com/urfave/cli"
    "fmt"
    "os"
)

var Commands = []cli.Command{
    CommandDu,
    CommandMkdir,
    CommandRm,
    CommandCp,
    CommandList,
}
var CommandList = cli.Command{
    Name:"ls",
    Usage:"List information about the FILEs (the current directory by default).",
    Action:doList,
    Flags:[]cli.Flag{
        cli.BoolFlag{Name:"l,long"},
        cli.BoolFlag{Name:"h,human-readable"},
    },
}
var CommandDu = cli.Command{
    Name:"du",
    Usage:"Summarize disk usage of the set of FILEs, recursively for directories.",
    Action:doDu,
    Flags:[]cli.Flag{
        cli.BoolFlag{Name:"h"},
    },
}
var CommandMkdir = cli.Command{
    Name:"mkdir",
    Usage:"Create the DIRECTORY(ies), if they do not already exist.",
    Action:doMkdir,
}
var CommandRm = cli.Command{
    Name:"rm",
    Usage:"Remove (unlink) the FILE(s)",
    Action:doRm,
    Flags:[]cli.Flag{
        cli.BoolFlag{Name:"r,recursive"},
        cli.BoolFlag{Name:"f,force"},
    },
}
var CommandCp = cli.Command{
    Name:"cp",
    Usage:"Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.",
    Action:doCp,
    Flags:[]cli.Flag{
        cli.BoolFlag{Name:"R,recursive"},
    },
}

func doList(c *cli.Context) error {
    fmt.Println("list files")
    if c.Bool("l") {
        fmt.Println("long")
    }
    if c.Bool("h") {
        fmt.Println("human")
    }
    return nil
}
func doDu(c *cli.Context) error {
    fmt.Println("du")
    if c.Bool("h") {
        fmt.Println("human")
    }
    return nil
}
func doMkdir(c *cli.Context) error {
    fmt.Println("mkdir")
    return nil
}

func doRm(c *cli.Context) error {
    fmt.Println("rm")
    if c.Bool("r") {
        fmt.Println("recursive")
    }
    if c.Bool("f") {
        fmt.Println("force")
    }
    return nil

}
func doCp(c *cli.Context) error {
    fmt.Println("cp")
    if c.Bool("R") {
        fmt.Println("recursive")
    }
    return nil
}
func main() {
    cli.HelpFlag = cli.BoolFlag{
        Name:"help",
        Usage:"To show help for the tool",
    }
    app := cli.NewApp()
    app.OnUsageError = func(context *cli.Context, err error, isSubcommand bool) error {
        fmt.Println("invalid usage")

        return nil
    }
    app.Name = "app name"
    app.Commands = Commands
    app.Run(os.Args)
}

robin11 avatar Oct 19 '16 03:10 robin11

Aha, I see what you are saying now.

This actually appears to be because of special handling of -h by the stdlib flag library (which we use under the hood for frag parsing in urfave/cli: https://golang.org/src/flag/flag.go?#L869

I unfortunately don't see an easy workaround without replacing the parser or vendoring it and patching, but this is definitely a bug. I'd lean towards the latter in the short term.

jszwedko avatar Oct 19 '16 04:10 jszwedko

I am facing the same problem. Has this problem been solved?

chensongz avatar Apr 13 '17 01:04 chensongz

I checked the source code. I found the key problem is at command.go line 173. Function checkCommandHelp is called. The function is defined at help.go line 237.

func checkCommandHelp(c *Context, name string) bool {
	if c.Bool("h") || c.Bool("help") {
		ShowCommandHelp(c, name)
		return true
	}
	return false
}

Every command run will call this function, and check flag -h & --help first. So user-defined flag -h will not work.

The solution can be removing c.Bool("h") or checking command help later.

chensongz avatar Apr 13 '17 12:04 chensongz

@asahasrabuddhe I'm un-assigning this since there's hasn't been any movement on it recently!

@ everyone else, please feel free to help with this 🙏

coilysiren avatar Nov 27 '19 07:11 coilysiren

This issue or PR has been automatically marked as stale because it has not had recent activity. Please add a comment bumping this if you're still interested in it's resolution! Thanks for your help, please let us know if you need anything else.

stale[bot] avatar Feb 25 '20 08:02 stale[bot]

This definitely seems like something we should consider fixing 👍 we're still waiting on someone who wants to contribute, though! 🙏

coilysiren avatar Feb 26 '20 05:02 coilysiren

This issue or PR has been bumped and is no longer marked as stale! Feel free to bump it again in the future, if it's still relevant.

stale[bot] avatar Feb 26 '20 05:02 stale[bot]

This issue or PR has been automatically marked as stale because it has not had recent activity. Please add a comment bumping this if you're still interested in it's resolution! Thanks for your help, please let us know if you need anything else.

stale[bot] avatar May 26 '20 05:05 stale[bot]

Closing this as it has become stale.

stale[bot] avatar Jun 25 '20 09:06 stale[bot]

Wont fix in v1, v2 as it requires a rewrite of stdlib flag parser

dearchap avatar Dec 18 '22 16:12 dearchap