mirror of
https://github.com/spf13/cobra
synced 2025-04-27 09:07:19 +00:00
Merge f5b399336d
into ceb39aba25
This commit is contained in:
commit
528c709800
2 changed files with 65 additions and 13 deletions
50
command.go
50
command.go
|
@ -671,14 +671,33 @@ func shortHasNoOptDefVal(name string, fs *flag.FlagSet) bool {
|
||||||
return flag.NoOptDefVal != ""
|
return flag.NoOptDefVal != ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func addFlagSet(dest *flag.FlagSet, src *flag.FlagSet) {
|
||||||
|
if src == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
src.VisitAll(func(f *flag.Flag) {
|
||||||
|
if dest.Lookup(f.Name) == nil && dest.ShorthandLookup(f.Shorthand) == nil {
|
||||||
|
dest.AddFlag(f)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func mergeChildrenFlags(fs *flag.FlagSet, c *Command) {
|
||||||
|
addFlagSet(fs, c.flags)
|
||||||
|
addFlagSet(fs, c.pflags)
|
||||||
|
for _, subc := range c.commands {
|
||||||
|
mergeChildrenFlags(fs, subc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func stripFlags(args []string, c *Command) []string {
|
func stripFlags(args []string, c *Command) []string {
|
||||||
if len(args) == 0 {
|
if len(args) == 0 {
|
||||||
return args
|
return args
|
||||||
}
|
}
|
||||||
c.mergePersistentFlags()
|
|
||||||
|
|
||||||
commands := []string{}
|
commands := []string{}
|
||||||
flags := c.Flags()
|
flags := flag.NewFlagSet("", flag.ContinueOnError)
|
||||||
|
mergeChildrenFlags(flags, c)
|
||||||
|
|
||||||
Loop:
|
Loop:
|
||||||
for len(args) > 0 {
|
for len(args) > 0 {
|
||||||
|
@ -688,18 +707,23 @@ Loop:
|
||||||
case s == "--":
|
case s == "--":
|
||||||
// "--" terminates the flags
|
// "--" terminates the flags
|
||||||
break Loop
|
break Loop
|
||||||
case strings.HasPrefix(s, "--") && !strings.Contains(s, "=") && !hasNoOptDefVal(s[2:], flags):
|
case strings.HasPrefix(s, "-") && !strings.Contains(s, "=") && len(args) > 0:
|
||||||
// If '--flag arg' then
|
// If "--flag" or "-f" then strip leading dashes.
|
||||||
// delete arg from args.
|
s = s[1:]
|
||||||
fallthrough // (do the same as below)
|
hnodv := shortHasNoOptDefVal
|
||||||
case strings.HasPrefix(s, "-") && !strings.Contains(s, "=") && len(s) == 2 && !shortHasNoOptDefVal(s[1:], flags):
|
if len(s) > 1 {
|
||||||
// If '-f arg' then
|
if !strings.HasPrefix(s, "-") {
|
||||||
// delete 'arg' from args or break the loop if len(args) <= 1.
|
// "-i1"
|
||||||
if len(args) <= 1 {
|
continue
|
||||||
break Loop
|
}
|
||||||
} else {
|
// Long flag.
|
||||||
|
s = s[1:]
|
||||||
|
hnodv = hasNoOptDefVal
|
||||||
|
}
|
||||||
|
f := flags.Lookup(s)
|
||||||
|
if (f == nil || f.Value.Type() != "bool") && !hnodv(s, flags) {
|
||||||
|
// Delete the argument if '--flag arg'.
|
||||||
args = args[1:]
|
args = args[1:]
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
case s != "" && !strings.HasPrefix(s, "-"):
|
case s != "" && !strings.HasPrefix(s, "-"):
|
||||||
commands = append(commands, s)
|
commands = append(commands, s)
|
||||||
|
|
|
@ -640,6 +640,34 @@ func TestFlagBeforeCommand(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestBooleanFlagBeforeCommand(t *testing.T) {
|
||||||
|
rootCommand := &Command{SilenceUsage: true, Args: MaximumNArgs(0)}
|
||||||
|
var flagValue bool
|
||||||
|
rootCommand.PersistentFlags().BoolVar(&flagValue, "rootflag", false, "root boolean flag")
|
||||||
|
|
||||||
|
cmd := &Command{Use: "command", SilenceUsage: true, Args: MaximumNArgs(0)}
|
||||||
|
cmd.PersistentFlags().BoolVar(&flagValue, "cmdflag", false, "command boolean flag")
|
||||||
|
rootCommand.AddCommand(cmd)
|
||||||
|
|
||||||
|
for name, args := range map[string][]string{
|
||||||
|
"root flag before command": {"--rootflag", "command"},
|
||||||
|
"command flag before command": {"--cmdflag", "command"},
|
||||||
|
"command flag with =value before command": {"--cmdflag=true", "command"},
|
||||||
|
// Not supported:
|
||||||
|
// "command flag with value before command": {"--cmdflag", "true", "command"},
|
||||||
|
} {
|
||||||
|
t.Run(name, func(t *testing.T) {
|
||||||
|
flagValue = false
|
||||||
|
rootCommand.SetArgs(args)
|
||||||
|
if err := rootCommand.Execute(); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
} else if !flagValue {
|
||||||
|
t.Errorf("flag is false")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestStripFlags(t *testing.T) {
|
func TestStripFlags(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
input []string
|
input []string
|
||||||
|
|
Loading…
Add table
Reference in a new issue