cli
cli copied to clipboard
flag for -h does not work after set HelpFlag to something else
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!
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!
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)
}
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.
I am facing the same problem. Has this problem been solved?
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.
@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 🙏
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.
This definitely seems like something we should consider fixing 👍 we're still waiting on someone who wants to contribute, though! 🙏
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.
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.
Closing this as it has become stale.
Wont fix in v1, v2 as it requires a rewrite of stdlib flag parser