From 92ea23a837e66f46ac9e7d04fa826602b7b0a42d Mon Sep 17 00:00:00 2001 From: Eric Paris Date: Thu, 23 Feb 2017 08:12:51 -0500 Subject: [PATCH] Fix subcommand locations with NoOptDefValue flags (#391) If one ran a command like ./root --boolFlag subcmd1 subcmd2 Thing worked fine. The code recognized that --boolFlag followed by a space meant the next word was not the argument to --boolFlag. But other flag types with a NoOptDefValue (like a Count flag) would not ignore the "argument". On a command like: ./root --countflag subcmd1 subcmd2 The processor, when looking for a subcommand, would first throw out the `--countflag subcmd1` and then look for subcmd2 under root. The fix is to ignore the next word after any NoOptDefVal flag, not just boolean flags. --- command.go | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/command.go b/command.go index 5c1c3a0..0394e43 100644 --- a/command.go +++ b/command.go @@ -384,20 +384,18 @@ func (c *Command) resetChildrensParents() { } } -// Test if the named flag is a boolean flag. -func isBooleanFlag(name string, f *flag.FlagSet) bool { +func hasNoOptDefVal(name string, f *flag.FlagSet) bool { flag := f.Lookup(name) if flag == nil { return false } - return flag.Value.Type() == "bool" + return len(flag.NoOptDefVal) > 0 } -// Test if the named flag is a boolean flag. -func isBooleanShortFlag(name string, f *flag.FlagSet) bool { +func shortHasNoOptDefVal(name string, fs *flag.FlagSet) bool { result := false - f.VisitAll(func(f *flag.Flag) { - if f.Shorthand == name && f.Value.Type() == "bool" { + fs.VisitAll(func(flag *flag.Flag) { + if flag.Shorthand == name && len(flag.NoOptDefVal) > 0 { result = true } }) @@ -423,8 +421,8 @@ func stripFlags(args []string, c *Command) []string { inQuote = true case strings.HasPrefix(y, "--") && !strings.Contains(y, "="): // TODO: this isn't quite right, we should really check ahead for 'true' or 'false' - inFlag = !isBooleanFlag(y[2:], c.Flags()) - case strings.HasPrefix(y, "-") && !strings.Contains(y, "=") && len(y) == 2 && !isBooleanShortFlag(y[1:], c.Flags()): + inFlag = !hasNoOptDefVal(y[2:], c.Flags()) + case strings.HasPrefix(y, "-") && !strings.Contains(y, "=") && len(y) == 2 && !shortHasNoOptDefVal(y[1:], c.Flags()): inFlag = true case inFlag: inFlag = false