diff options
Diffstat (limited to 'vendor/github.com/spf13/cobra/command.go')
-rw-r--r-- | vendor/github.com/spf13/cobra/command.go | 272 |
1 files changed, 100 insertions, 172 deletions
diff --git a/vendor/github.com/spf13/cobra/command.go b/vendor/github.com/spf13/cobra/command.go index 664bf5aa5..f4705f970 100644 --- a/vendor/github.com/spf13/cobra/command.go +++ b/vendor/github.com/spf13/cobra/command.go @@ -66,6 +66,10 @@ type Command struct { pflags *flag.FlagSet // Flags that are declared specifically by this command (not inherited). lflags *flag.FlagSet + // Inherited flags. + iflags *flag.FlagSet + // All persistent flags of cmd's parents. + parentsPflags *flag.FlagSet // SilenceErrors is an option to quiet errors down stream SilenceErrors bool // Silence Usage is an option to silence usage when an error occurs. @@ -110,10 +114,8 @@ type Command struct { // is commands slice are sorted or not commandsAreSorted bool - flagErrorBuf *bytes.Buffer - args []string // actual args parsed from flags - output *io.Writer // out writer if set in SetOutput(w) + output io.Writer // out writer if set in SetOutput(w) usageFunc func(*Command) error // Usage can be defined by application usageTemplate string // Can be defined by Application flagErrorFunc func(*Command, error) error @@ -141,7 +143,7 @@ func (c *Command) SetArgs(a []string) { // SetOutput sets the destination for usage and error messages. // If output is nil, os.Stderr is used. func (c *Command) SetOutput(output io.Writer) { - c.output = &output + c.output = output } // SetUsageFunc sets usage function. Usage can be defined by application. @@ -199,7 +201,7 @@ func (c *Command) OutOrStderr() io.Writer { func (c *Command) getOut(def io.Writer) io.Writer { if c.output != nil { - return *c.output + return c.output } if c.HasParent() { return c.parent.getOut(def) @@ -213,9 +215,8 @@ func (c *Command) UsageFunc() (f func(*Command) error) { if c.usageFunc != nil { return c.usageFunc } - if c.HasParent() { - return c.parent.UsageFunc() + return c.Parent().UsageFunc() } return func(c *Command) error { c.mergePersistentFlags() @@ -237,10 +238,13 @@ func (c *Command) Usage() error { // HelpFunc returns either the function set by SetHelpFunc for this command // or a parent, or it returns a function with default help behavior. func (c *Command) HelpFunc() func(*Command, []string) { - if helpFunc := c.checkHelpFunc(); helpFunc != nil { - return helpFunc + if c.helpFunc != nil { + return c.helpFunc + } + if c.HasParent() { + return c.Parent().HelpFunc() } - return func(*Command, []string) { + return func(c *Command, a []string) { c.mergePersistentFlags() err := tmpl(c.OutOrStdout(), c.HelpTemplate(), c) if err != nil { @@ -249,20 +253,6 @@ func (c *Command) HelpFunc() func(*Command, []string) { } } -// checkHelpFunc checks if there is helpFunc in ancestors of c. -func (c *Command) checkHelpFunc() func(*Command, []string) { - if c == nil { - return nil - } - if c.helpFunc != nil { - return c.helpFunc - } - if c.HasParent() { - return c.parent.checkHelpFunc() - } - return nil -} - // Help puts out the help for the command. // Used when a user calls help [command]. // Can be defined by user by overriding HelpFunc. @@ -341,8 +331,7 @@ func (c *Command) UsageTemplate() string { {{ .CommandPath}} [command]{{end}}{{if gt .Aliases 0}} Aliases: - {{.NameAndAliases}} -{{end}}{{if .HasExample}} + {{.NameAndAliases}}{{end}}{{if .HasExample}} Examples: {{ .Example }}{{end}}{{if .HasAvailableSubCommands}} @@ -377,64 +366,62 @@ func (c *Command) HelpTemplate() string { {{end}}{{if or .Runnable .HasSubCommands}}{{.UsageString}}{{end}}` } -// Really only used when casting a command to a commander. -func (c *Command) resetChildrensParents() { - for _, x := range c.commands { - x.parent = c - } -} - func hasNoOptDefVal(name string, f *flag.FlagSet) bool { flag := f.Lookup(name) if flag == nil { return false } - return len(flag.NoOptDefVal) > 0 + return flag.NoOptDefVal != "" } func shortHasNoOptDefVal(name string, fs *flag.FlagSet) bool { result := false fs.VisitAll(func(flag *flag.Flag) { - if flag.Shorthand == name && len(flag.NoOptDefVal) > 0 { + if flag.Shorthand == name && flag.NoOptDefVal != "" { result = true + return } }) return result } func stripFlags(args []string, c *Command) []string { - if len(args) < 1 { + if len(args) == 0 { return args } c.mergePersistentFlags() commands := []string{} - inQuote := false - inFlag := false - for _, y := range args { + flags := c.Flags() + +Loop: + for len(args) > 0 { + s := args[0] + args = args[1:] if !inQuote { switch { - case strings.HasPrefix(y, "\""): - inQuote = true - case strings.Contains(y, "=\""): + case strings.HasPrefix(s, "\"") || strings.Contains(s, "=\""): 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 = !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 - case y == "": - // strip empty commands, as the go tests expect this to be ok.... - case !strings.HasPrefix(y, "-"): - commands = append(commands, y) - inFlag = false + case strings.HasPrefix(s, "--") && !strings.Contains(s, "=") && !hasNoOptDefVal(s[2:], flags): + // If '--flag arg' then + // delete arg from args. + fallthrough // (do the same as below) + case strings.HasPrefix(s, "-") && !strings.Contains(s, "=") && len(s) == 2 && !shortHasNoOptDefVal(s[1:], flags): + // If '-f arg' then + // delete 'arg' from args or break the loop if len(args) <= 1. + if len(args) <= 1 { + break Loop + } else { + args = args[1:] + continue + } + case s != "" && !strings.HasPrefix(s, "-"): + commands = append(commands, s) } } - if strings.HasSuffix(y, "\"") && !strings.HasSuffix(y, "\\\"") { + if strings.HasSuffix(s, "\"") && !strings.HasSuffix(s, "\\\"") { inQuote = false } } @@ -547,32 +534,18 @@ func (c *Command) SuggestionsFor(typedName string) []string { // VisitParents visits all parents of the command and invokes fn on each parent. func (c *Command) VisitParents(fn func(*Command)) { - var traverse func(*Command) *Command - - traverse = func(x *Command) *Command { - if x != c { - fn(x) - } - if x.HasParent() { - return traverse(x.parent) - } - return x + if c.HasParent() { + fn(c.Parent()) + c.Parent().VisitParents(fn) } - traverse(c) } // Root finds root command. func (c *Command) Root() *Command { - var findRoot func(*Command) *Command - - findRoot = func(x *Command) *Command { - if x.HasParent() { - return findRoot(x.parent) - } - return x + if c.HasParent() { + return c.Parent().Root() } - - return findRoot(c) + return c } // ArgsLenAtDash will return the length of f.Args at the moment when a -- was @@ -675,17 +648,6 @@ func (c *Command) preRun() { } } -func (c *Command) errorMsgFromParse() string { - s := c.flagErrorBuf.String() - - x := strings.Split(s, "\n") - - if len(x) > 0 { - return x[0] - } - return "" -} - // Execute Call execute to use the args (os.Args[1:] by default) // and run through the command tree finding appropriate matches // for commands and then corresponding flags. @@ -796,6 +758,7 @@ func (c *Command) initHelpCmd() { func (c *Command) ResetCommands() { c.commands = nil c.helpCommand = nil + c.parentsPflags = nil } // Sorts commands by their names. @@ -927,12 +890,8 @@ func (c *Command) DebugFlags() { } if x.HasFlags() { x.flags.VisitAll(func(f *flag.Flag) { - if x.HasPersistentFlags() { - if x.persistentFlag(f.Name) == nil { - c.Println(" -"+f.Shorthand+",", "--"+f.Name, "["+f.DefValue+"]", "", f.Value, " [L]") - } else { - c.Println(" -"+f.Shorthand+",", "--"+f.Name, "["+f.DefValue+"]", "", f.Value, " [LP]") - } + if x.HasPersistentFlags() && x.persistentFlag(f.Name) != nil { + c.Println(" -"+f.Shorthand+",", "--"+f.Name, "["+f.DefValue+"]", "", f.Value, " [LP]") } else { c.Println(" -"+f.Shorthand+",", "--"+f.Name, "["+f.DefValue+"]", "", f.Value, " [L]") } @@ -949,7 +908,6 @@ func (c *Command) DebugFlags() { } }) } - c.Println(x.flagErrorBuf) if x.HasSubCommands() { for _, y := range x.commands { debugflags(y) @@ -1090,11 +1048,9 @@ func (c *Command) GlobalNormalizationFunc() func(f *flag.FlagSet, name string) f func (c *Command) Flags() *flag.FlagSet { if c.flags == nil { c.flags = flag.NewFlagSet(c.Name(), flag.ContinueOnError) - if c.flagErrorBuf == nil { - c.flagErrorBuf = new(bytes.Buffer) - } - c.flags.SetOutput(c.flagErrorBuf) + c.flags.SetOutput(c.OutOrStderr()) } + return c.flags } @@ -1115,47 +1071,37 @@ func (c *Command) LocalNonPersistentFlags() *flag.FlagSet { func (c *Command) LocalFlags() *flag.FlagSet { c.mergePersistentFlags() - local := flag.NewFlagSet(c.Name(), flag.ContinueOnError) - c.lflags.VisitAll(func(f *flag.Flag) { - local.AddFlag(f) - }) - if !c.HasParent() { - flag.CommandLine.VisitAll(func(f *flag.Flag) { - if local.Lookup(f.Name) == nil { - local.AddFlag(f) - } - }) + if c.lflags == nil { + c.lflags = flag.NewFlagSet(c.Name(), flag.ContinueOnError) + c.lflags.SetOutput(c.OutOrStderr()) } - return local + c.lflags.SortFlags = c.Flags().SortFlags + + addToLocal := func(f *flag.Flag) { + if c.lflags.Lookup(f.Name) == nil && c.parentsPflags.Lookup(f.Name) == nil { + c.lflags.AddFlag(f) + } + } + c.Flags().VisitAll(addToLocal) + c.PersistentFlags().VisitAll(addToLocal) + return c.lflags } // InheritedFlags returns all flags which were inherited from parents commands. func (c *Command) InheritedFlags() *flag.FlagSet { c.mergePersistentFlags() - inherited := flag.NewFlagSet(c.Name(), flag.ContinueOnError) - local := c.LocalFlags() - - var rmerge func(x *Command) - - rmerge = func(x *Command) { - if x.HasPersistentFlags() { - x.PersistentFlags().VisitAll(func(f *flag.Flag) { - if inherited.Lookup(f.Name) == nil && local.Lookup(f.Name) == nil { - inherited.AddFlag(f) - } - }) - } - if x.HasParent() { - rmerge(x.parent) - } + if c.iflags == nil { + c.iflags = flag.NewFlagSet(c.Name(), flag.ContinueOnError) } - if c.HasParent() { - rmerge(c.parent) - } - - return inherited + local := c.LocalFlags() + c.parentsPflags.VisitAll(func(f *flag.Flag) { + if c.iflags.Lookup(f.Name) == nil && local.Lookup(f.Name) == nil { + c.iflags.AddFlag(f) + } + }) + return c.iflags } // NonInheritedFlags returns all flags which were not inherited from parent commands. @@ -1167,22 +1113,17 @@ func (c *Command) NonInheritedFlags() *flag.FlagSet { func (c *Command) PersistentFlags() *flag.FlagSet { if c.pflags == nil { c.pflags = flag.NewFlagSet(c.Name(), flag.ContinueOnError) - if c.flagErrorBuf == nil { - c.flagErrorBuf = new(bytes.Buffer) - } - c.pflags.SetOutput(c.flagErrorBuf) + c.pflags.SetOutput(c.OutOrStderr()) } return c.pflags } // ResetFlags is used in testing. func (c *Command) ResetFlags() { - c.flagErrorBuf = new(bytes.Buffer) - c.flagErrorBuf.Reset() c.flags = flag.NewFlagSet(c.Name(), flag.ContinueOnError) - c.flags.SetOutput(c.flagErrorBuf) + c.flags.SetOutput(c.OutOrStderr()) c.pflags = flag.NewFlagSet(c.Name(), flag.ContinueOnError) - c.pflags.SetOutput(c.flagErrorBuf) + c.pflags.SetOutput(c.OutOrStderr()) } // HasFlags checks if the command contains any flags (local plus persistent from the entire structure). @@ -1245,8 +1186,9 @@ func (c *Command) persistentFlag(name string) (flag *flag.Flag) { flag = c.PersistentFlags().Lookup(name) } - if flag == nil && c.HasParent() { - flag = c.parent.persistentFlag(name) + if flag == nil { + c.updateParentsPflags() + flag = c.parentsPflags.Lookup(name) } return } @@ -1266,41 +1208,27 @@ func (c *Command) Parent() *Command { return c.parent } +// mergePersistentFlags merges c.PersistentFlags() to c.Flags() +// and adds missing persistent flags of all parents. func (c *Command) mergePersistentFlags() { - var rmerge func(x *Command) + c.Flags().AddFlagSet(c.PersistentFlags()) + c.updateParentsPflags() + c.Flags().AddFlagSet(c.parentsPflags) +} - // Save the set of local flags - if c.lflags == nil { - c.lflags = flag.NewFlagSet(c.Name(), flag.ContinueOnError) - if c.flagErrorBuf == nil { - c.flagErrorBuf = new(bytes.Buffer) - } - c.lflags.SetOutput(c.flagErrorBuf) - addtolocal := func(f *flag.Flag) { - c.lflags.AddFlag(f) - } - c.Flags().VisitAll(addtolocal) - c.PersistentFlags().VisitAll(addtolocal) - } - rmerge = func(x *Command) { - if !x.HasParent() { - flag.CommandLine.VisitAll(func(f *flag.Flag) { - if x.PersistentFlags().Lookup(f.Name) == nil { - x.PersistentFlags().AddFlag(f) - } - }) - } - if x.HasPersistentFlags() { - x.PersistentFlags().VisitAll(func(f *flag.Flag) { - if c.Flags().Lookup(f.Name) == nil { - c.Flags().AddFlag(f) - } - }) - } - if x.HasParent() { - rmerge(x.parent) - } +// updateParentsPflags updates c.parentsPflags by adding +// new persistent flags of all parents. +// If c.parentsPflags == nil, it makes new. +func (c *Command) updateParentsPflags() { + if c.parentsPflags == nil { + c.parentsPflags = flag.NewFlagSet(c.Name(), flag.ContinueOnError) + c.parentsPflags.SetOutput(c.OutOrStderr()) + c.parentsPflags.SortFlags = false } - rmerge(c) + c.Root().PersistentFlags().AddFlagSet(flag.CommandLine) + + c.VisitParents(func(parent *Command) { + c.parentsPflags.AddFlagSet(parent.PersistentFlags()) + }) } |