1 // Copyright © 2013 Steve Francia <spf@spf13.com>.
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 // http://www.apache.org/licenses/LICENSE-2.0
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
14 // Package cobra is a commander providing a simple interface to create powerful modern CLI interfaces.
15 // In addition to providing an interface, Cobra simultaneously provides a controller to organize your application code.
27 flag "github.com/spf13/pflag"
30 // Command is just that, a command for your application.
31 // E.g. 'go run ...' - 'run' is the command. Cobra requires
32 // you to define the usage and description as part of your command
33 // definition to ensure usability.
35 // Use is the one-line usage message.
38 // Aliases is an array of aliases that can be used instead of the first word in Use.
41 // SuggestFor is an array of command names for which this command will be suggested -
42 // similar to aliases but only suggests.
45 // Short is the short description shown in the 'help' output.
48 // Long is the long message shown in the 'help <this-command>' output.
51 // Example is examples of how to use the command.
54 // ValidArgs is list of all valid non-flag arguments that are accepted in bash completions
60 // ArgAliases is List of aliases for ValidArgs.
61 // These are not suggested to the user in the bash completion,
62 // but accepted if entered manually.
65 // BashCompletionFunction is custom functions used by the bash autocompletion generator.
66 BashCompletionFunction string
68 // Deprecated defines, if this command is deprecated and should print this string when used.
71 // Hidden defines, if this command is hidden and should NOT show up in the list of available commands.
74 // Annotations are key/value pairs that can be used by applications to identify or
76 Annotations map[string]string
78 // The *Run functions are executed in the following order:
79 // * PersistentPreRun()
83 // * PersistentPostRun()
84 // All functions get the same args, the arguments after the command name.
86 // PersistentPreRun: children of this command will inherit and execute.
87 PersistentPreRun func(cmd *Command, args []string)
88 // PersistentPreRunE: PersistentPreRun but returns an error.
89 PersistentPreRunE func(cmd *Command, args []string) error
90 // PreRun: children of this command will not inherit.
91 PreRun func(cmd *Command, args []string)
92 // PreRunE: PreRun but returns an error.
93 PreRunE func(cmd *Command, args []string) error
94 // Run: Typically the actual work function. Most commands will only implement this.
95 Run func(cmd *Command, args []string)
96 // RunE: Run but returns an error.
97 RunE func(cmd *Command, args []string) error
98 // PostRun: run after the Run command.
99 PostRun func(cmd *Command, args []string)
100 // PostRunE: PostRun but returns an error.
101 PostRunE func(cmd *Command, args []string) error
102 // PersistentPostRun: children of this command will inherit and execute after PostRun.
103 PersistentPostRun func(cmd *Command, args []string)
104 // PersistentPostRunE: PersistentPostRun but returns an error.
105 PersistentPostRunE func(cmd *Command, args []string) error
107 // SilenceErrors is an option to quiet errors down stream.
110 // SilenceUsage is an option to silence usage when an error occurs.
113 // DisableFlagParsing disables the flag parsing.
114 // If this is true all flags will be passed to the command as arguments.
115 DisableFlagParsing bool
117 // DisableAutoGenTag defines, if gen tag ("Auto generated by spf13/cobra...")
118 // will be printed by generating docs for this command.
119 DisableAutoGenTag bool
121 // DisableSuggestions disables the suggestions based on Levenshtein distance
122 // that go along with 'unknown command' messages.
123 DisableSuggestions bool
124 // SuggestionsMinimumDistance defines minimum levenshtein distance to display suggestions.
126 SuggestionsMinimumDistance int
128 // TraverseChildren parses flags on all parents before executing child command.
129 TraverseChildren bool
131 // commands is the list of commands supported by this program.
133 // parent is a parent command for this command.
135 // Max lengths of commands' string lengths for use in padding.
136 commandsMaxUseLen int
137 commandsMaxCommandPathLen int
138 commandsMaxNameLen int
139 // commandsAreSorted defines, if command slice are sorted or not.
140 commandsAreSorted bool
142 // args is actual args parsed from flags.
144 // flagErrorBuf contains all error messages from pflag.
145 flagErrorBuf *bytes.Buffer
146 // flags is full set of flags.
148 // pflags contains persistent flags.
150 // lflags contains local flags.
152 // iflags contains inherited flags.
154 // parentsPflags is all persistent flags of cmd's parents.
155 parentsPflags *flag.FlagSet
156 // globNormFunc is the global normalization function
157 // that we can use on every pflag set and children commands
158 globNormFunc func(f *flag.FlagSet, name string) flag.NormalizedName
160 // output is an output writer defined by user.
162 // usageFunc is usage func defined by user.
163 usageFunc func(*Command) error
164 // usageTemplate is usage template defined by user.
166 // flagErrorFunc is func defined by user and it's called when the parsing of
167 // flags returns an error.
168 flagErrorFunc func(*Command, error) error
169 // helpTemplate is help template defined by user.
171 // helpFunc is help func defined by user.
172 helpFunc func(*Command, []string)
173 // helpCommand is command with usage 'help'. If it's not defined by user,
174 // cobra uses default help command.
178 // SetArgs sets arguments for the command. It is set to os.Args[1:] by default, if desired, can be overridden
179 // particularly useful when testing.
180 func (c *Command) SetArgs(a []string) {
184 // SetOutput sets the destination for usage and error messages.
185 // If output is nil, os.Stderr is used.
186 func (c *Command) SetOutput(output io.Writer) {
190 // SetUsageFunc sets usage function. Usage can be defined by application.
191 func (c *Command) SetUsageFunc(f func(*Command) error) {
195 // SetUsageTemplate sets usage template. Can be defined by Application.
196 func (c *Command) SetUsageTemplate(s string) {
200 // SetFlagErrorFunc sets a function to generate an error when flag parsing
202 func (c *Command) SetFlagErrorFunc(f func(*Command, error) error) {
206 // SetHelpFunc sets help function. Can be defined by Application.
207 func (c *Command) SetHelpFunc(f func(*Command, []string)) {
211 // SetHelpCommand sets help command.
212 func (c *Command) SetHelpCommand(cmd *Command) {
216 // SetHelpTemplate sets help template to be used. Application can use it to set custom template.
217 func (c *Command) SetHelpTemplate(s string) {
221 // SetGlobalNormalizationFunc sets a normalization function to all flag sets and also to child commands.
222 // The user should not have a cyclic dependency on commands.
223 func (c *Command) SetGlobalNormalizationFunc(n func(f *flag.FlagSet, name string) flag.NormalizedName) {
224 c.Flags().SetNormalizeFunc(n)
225 c.PersistentFlags().SetNormalizeFunc(n)
228 for _, command := range c.commands {
229 command.SetGlobalNormalizationFunc(n)
233 // OutOrStdout returns output to stdout.
234 func (c *Command) OutOrStdout() io.Writer {
235 return c.getOut(os.Stdout)
238 // OutOrStderr returns output to stderr
239 func (c *Command) OutOrStderr() io.Writer {
240 return c.getOut(os.Stderr)
243 func (c *Command) getOut(def io.Writer) io.Writer {
248 return c.parent.getOut(def)
253 // UsageFunc returns either the function set by SetUsageFunc for this command
254 // or a parent, or it returns a default usage function.
255 func (c *Command) UsageFunc() (f func(*Command) error) {
256 if c.usageFunc != nil {
260 return c.Parent().UsageFunc()
262 return func(c *Command) error {
263 c.mergePersistentFlags()
264 err := tmpl(c.OutOrStderr(), c.UsageTemplate(), c)
272 // Usage puts out the usage for the command.
273 // Used when a user provides invalid input.
274 // Can be defined by user by overriding UsageFunc.
275 func (c *Command) Usage() error {
276 return c.UsageFunc()(c)
279 // HelpFunc returns either the function set by SetHelpFunc for this command
280 // or a parent, or it returns a function with default help behavior.
281 func (c *Command) HelpFunc() func(*Command, []string) {
282 if c.helpFunc != nil {
286 return c.Parent().HelpFunc()
288 return func(c *Command, a []string) {
289 c.mergePersistentFlags()
290 err := tmpl(c.OutOrStdout(), c.HelpTemplate(), c)
297 // Help puts out the help for the command.
298 // Used when a user calls help [command].
299 // Can be defined by user by overriding HelpFunc.
300 func (c *Command) Help() error {
301 c.HelpFunc()(c, []string{})
305 // UsageString return usage string.
306 func (c *Command) UsageString() string {
307 tmpOutput := c.output
308 bb := new(bytes.Buffer)
315 // FlagErrorFunc returns either the function set by SetFlagErrorFunc for this
316 // command or a parent, or it returns a function which returns the original
318 func (c *Command) FlagErrorFunc() (f func(*Command, error) error) {
319 if c.flagErrorFunc != nil {
320 return c.flagErrorFunc
324 return c.parent.FlagErrorFunc()
326 return func(c *Command, err error) error {
331 var minUsagePadding = 25
333 // UsagePadding return padding for the usage.
334 func (c *Command) UsagePadding() int {
335 if c.parent == nil || minUsagePadding > c.parent.commandsMaxUseLen {
336 return minUsagePadding
338 return c.parent.commandsMaxUseLen
341 var minCommandPathPadding = 11
343 // CommandPathPadding return padding for the command path.
344 func (c *Command) CommandPathPadding() int {
345 if c.parent == nil || minCommandPathPadding > c.parent.commandsMaxCommandPathLen {
346 return minCommandPathPadding
348 return c.parent.commandsMaxCommandPathLen
351 var minNamePadding = 11
353 // NamePadding returns padding for the name.
354 func (c *Command) NamePadding() int {
355 if c.parent == nil || minNamePadding > c.parent.commandsMaxNameLen {
356 return minNamePadding
358 return c.parent.commandsMaxNameLen
361 // UsageTemplate returns usage template for the command.
362 func (c *Command) UsageTemplate() string {
363 if c.usageTemplate != "" {
364 return c.usageTemplate
368 return c.parent.UsageTemplate()
370 return `Usage:{{if .Runnable}}
371 {{.UseLine}}{{end}}{{if .HasAvailableSubCommands}}
372 {{.CommandPath}} [command]{{end}}{{if gt (len .Aliases) 0}}
375 {{.NameAndAliases}}{{end}}{{if .HasExample}}
378 {{.Example}}{{end}}{{if .HasAvailableSubCommands}}
380 Available Commands:{{range .Commands}}{{if (or .IsAvailableCommand (eq .Name "help"))}}
381 {{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}{{end}}{{if .HasAvailableLocalFlags}}
384 {{.LocalFlags.FlagUsages | trimTrailingWhitespaces}}{{end}}{{if .HasAvailableInheritedFlags}}
387 {{.InheritedFlags.FlagUsages | trimTrailingWhitespaces}}{{end}}{{if .HasHelpSubCommands}}
389 Additional help topics:{{range .Commands}}{{if .IsAdditionalHelpTopicCommand}}
390 {{rpad .CommandPath .CommandPathPadding}} {{.Short}}{{end}}{{end}}{{end}}{{if .HasAvailableSubCommands}}
392 Use "{{.CommandPath}} [command] --help" for more information about a command.{{end}}
396 // HelpTemplate return help template for the command.
397 func (c *Command) HelpTemplate() string {
398 if c.helpTemplate != "" {
399 return c.helpTemplate
403 return c.parent.HelpTemplate()
405 return `{{with (or .Long .Short)}}{{. | trimTrailingWhitespaces}}
407 {{end}}{{if or .Runnable .HasSubCommands}}{{.UsageString}}{{end}}`
410 func hasNoOptDefVal(name string, fs *flag.FlagSet) bool {
411 flag := fs.Lookup(name)
415 return flag.NoOptDefVal != ""
418 func shortHasNoOptDefVal(name string, fs *flag.FlagSet) bool {
423 flag := fs.ShorthandLookup(name[:1])
427 return flag.NoOptDefVal != ""
430 func stripFlags(args []string, c *Command) []string {
434 c.mergePersistentFlags()
436 commands := []string{}
444 case strings.HasPrefix(s, "--") && !strings.Contains(s, "=") && !hasNoOptDefVal(s[2:], flags):
445 // If '--flag arg' then
446 // delete arg from args.
447 fallthrough // (do the same as below)
448 case strings.HasPrefix(s, "-") && !strings.Contains(s, "=") && len(s) == 2 && !shortHasNoOptDefVal(s[1:], flags):
450 // delete 'arg' from args or break the loop if len(args) <= 1.
457 case s != "" && !strings.HasPrefix(s, "-"):
458 commands = append(commands, s)
465 // argsMinusFirstX removes only the first x from args. Otherwise, commands that look like
466 // openshift admin policy add-role-to-user admin my-user, lose the admin argument (arg[4]).
467 func argsMinusFirstX(args []string, x string) []string {
468 for i, y := range args {
471 ret = append(ret, args[:i]...)
472 ret = append(ret, args[i+1:]...)
479 func isFlagArg(arg string) bool {
480 return ((len(arg) >= 3 && arg[1] == '-') ||
481 (len(arg) >= 2 && arg[0] == '-' && arg[1] != '-'))
484 // Find the target command given the args and command tree
485 // Meant to be run on the highest node. Only searches down.
486 func (c *Command) Find(args []string) (*Command, []string, error) {
487 var innerfind func(*Command, []string) (*Command, []string)
489 innerfind = func(c *Command, innerArgs []string) (*Command, []string) {
490 argsWOflags := stripFlags(innerArgs, c)
491 if len(argsWOflags) == 0 {
494 nextSubCmd := argsWOflags[0]
496 cmd := c.findNext(nextSubCmd)
498 return innerfind(cmd, argsMinusFirstX(innerArgs, nextSubCmd))
503 commandFound, a := innerfind(c, args)
504 if commandFound.Args == nil {
505 return commandFound, a, legacyArgs(commandFound, stripFlags(a, commandFound))
507 return commandFound, a, nil
510 func (c *Command) findSuggestions(arg string) string {
511 if c.DisableSuggestions {
514 if c.SuggestionsMinimumDistance <= 0 {
515 c.SuggestionsMinimumDistance = 2
517 suggestionsString := ""
518 if suggestions := c.SuggestionsFor(arg); len(suggestions) > 0 {
519 suggestionsString += "\n\nDid you mean this?\n"
520 for _, s := range suggestions {
521 suggestionsString += fmt.Sprintf("\t%v\n", s)
524 return suggestionsString
527 func (c *Command) findNext(next string) *Command {
528 matches := make([]*Command, 0)
529 for _, cmd := range c.commands {
530 if cmd.Name() == next || cmd.HasAlias(next) {
533 if EnablePrefixMatching && cmd.hasNameOrAliasPrefix(next) {
534 matches = append(matches, cmd)
538 if len(matches) == 1 {
544 // Traverse the command tree to find the command, and parse args for
546 func (c *Command) Traverse(args []string) (*Command, []string, error) {
550 for i, arg := range args {
552 // A long flag with a space separated value
553 case strings.HasPrefix(arg, "--") && !strings.Contains(arg, "="):
554 // TODO: this isn't quite right, we should really check ahead for 'true' or 'false'
555 inFlag = !hasNoOptDefVal(arg[2:], c.Flags())
556 flags = append(flags, arg)
558 // A short flag with a space separated value
559 case strings.HasPrefix(arg, "-") && !strings.Contains(arg, "=") && len(arg) == 2 && !shortHasNoOptDefVal(arg[1:], c.Flags()):
561 flags = append(flags, arg)
563 // The value for a flag
566 flags = append(flags, arg)
568 // A flag without a value, or with an `=` separated value
570 flags = append(flags, arg)
574 cmd := c.findNext(arg)
579 if err := c.ParseFlags(flags); err != nil {
580 return nil, args, err
582 return cmd.Traverse(args[i+1:])
587 // SuggestionsFor provides suggestions for the typedName.
588 func (c *Command) SuggestionsFor(typedName string) []string {
589 suggestions := []string{}
590 for _, cmd := range c.commands {
591 if cmd.IsAvailableCommand() {
592 levenshteinDistance := ld(typedName, cmd.Name(), true)
593 suggestByLevenshtein := levenshteinDistance <= c.SuggestionsMinimumDistance
594 suggestByPrefix := strings.HasPrefix(strings.ToLower(cmd.Name()), strings.ToLower(typedName))
595 if suggestByLevenshtein || suggestByPrefix {
596 suggestions = append(suggestions, cmd.Name())
598 for _, explicitSuggestion := range cmd.SuggestFor {
599 if strings.EqualFold(typedName, explicitSuggestion) {
600 suggestions = append(suggestions, cmd.Name())
608 // VisitParents visits all parents of the command and invokes fn on each parent.
609 func (c *Command) VisitParents(fn func(*Command)) {
612 c.Parent().VisitParents(fn)
616 // Root finds root command.
617 func (c *Command) Root() *Command {
619 return c.Parent().Root()
624 // ArgsLenAtDash will return the length of f.Args at the moment when a -- was
625 // found during arg parsing. This allows your program to know which args were
626 // before the -- and which came after. (Description from
627 // https://godoc.org/github.com/spf13/pflag#FlagSet.ArgsLenAtDash).
628 func (c *Command) ArgsLenAtDash() int {
629 return c.Flags().ArgsLenAtDash()
632 func (c *Command) execute(a []string) (err error) {
634 return fmt.Errorf("Called Execute() on a nil Command")
637 if len(c.Deprecated) > 0 {
638 c.Printf("Command %q is deprecated, %s\n", c.Name(), c.Deprecated)
641 // initialize help flag as the last point possible to allow for user
643 c.InitDefaultHelpFlag()
645 err = c.ParseFlags(a)
647 return c.FlagErrorFunc()(c, err)
650 // If help is called, regardless of other flags, return we want help.
651 // Also say we need help if the command isn't runnable.
652 helpVal, err := c.Flags().GetBool("help")
654 // should be impossible to get here as we always declare a help
655 // flag in InitDefaultHelpFlag()
656 c.Println("\"help\" flag declared as non-bool. Please correct your code")
660 if helpVal || !c.Runnable() {
666 argWoFlags := c.Flags().Args()
667 if c.DisableFlagParsing {
671 if err := c.ValidateArgs(argWoFlags); err != nil {
675 for p := c; p != nil; p = p.Parent() {
676 if p.PersistentPreRunE != nil {
677 if err := p.PersistentPreRunE(c, argWoFlags); err != nil {
681 } else if p.PersistentPreRun != nil {
682 p.PersistentPreRun(c, argWoFlags)
686 if c.PreRunE != nil {
687 if err := c.PreRunE(c, argWoFlags); err != nil {
690 } else if c.PreRun != nil {
691 c.PreRun(c, argWoFlags)
694 if err := c.validateRequiredFlags(); err != nil {
698 if err := c.RunE(c, argWoFlags); err != nil {
704 if c.PostRunE != nil {
705 if err := c.PostRunE(c, argWoFlags); err != nil {
708 } else if c.PostRun != nil {
709 c.PostRun(c, argWoFlags)
711 for p := c; p != nil; p = p.Parent() {
712 if p.PersistentPostRunE != nil {
713 if err := p.PersistentPostRunE(c, argWoFlags); err != nil {
717 } else if p.PersistentPostRun != nil {
718 p.PersistentPostRun(c, argWoFlags)
726 func (c *Command) preRun() {
727 for _, x := range initializers {
732 // Execute uses the args (os.Args[1:] by default)
733 // and run through the command tree finding appropriate matches
734 // for commands and then corresponding flags.
735 func (c *Command) Execute() error {
736 _, err := c.ExecuteC()
740 // ExecuteC executes the command.
741 func (c *Command) ExecuteC() (cmd *Command, err error) {
742 // Regardless of what command execute is called on, run on Root only
744 return c.Root().ExecuteC()
748 if preExecHookFn != nil {
752 // initialize help as the last point possible to allow for user
754 c.InitDefaultHelpCmd()
758 // Workaround FAIL with "go test -v" or "cobra.test -test.v", see #155
759 if c.args == nil && filepath.Base(os.Args[0]) != "cobra.test" {
766 if c.TraverseChildren {
767 cmd, flags, err = c.Traverse(args)
769 cmd, flags, err = c.Find(args)
772 // If found parse to a subcommand and then failed, talk about the subcommand
776 if !c.SilenceErrors {
777 c.Println("Error:", err.Error())
778 c.Printf("Run '%v --help' for usage.\n", c.CommandPath())
783 err = cmd.execute(flags)
785 // Always show help if requested, even if SilenceErrors is in
787 if err == flag.ErrHelp {
788 cmd.HelpFunc()(cmd, args)
792 // If root command has SilentErrors flagged,
793 // all subcommands should respect it
794 if !cmd.SilenceErrors && !c.SilenceErrors {
795 c.Println("Error:", err.Error())
798 // If root command has SilentUsage flagged,
799 // all subcommands should respect it
800 if !cmd.SilenceUsage && !c.SilenceUsage {
801 c.Println(cmd.UsageString())
807 func (c *Command) ValidateArgs(args []string) error {
811 return c.Args(c, args)
814 func (c *Command) validateRequiredFlags() error {
816 missingFlagNames := []string{}
817 flags.VisitAll(func(pflag *flag.Flag) {
818 requiredAnnotation, found := pflag.Annotations[BashCompOneRequiredFlag]
822 if (requiredAnnotation[0] == "true") && !pflag.Changed {
823 missingFlagNames = append(missingFlagNames, pflag.Name)
827 if len(missingFlagNames) > 0 {
828 return fmt.Errorf(`Required flag(s) "%s" have/has not been set`, strings.Join(missingFlagNames, `", "`))
833 // InitDefaultHelpFlag adds default help flag to c.
834 // It is called automatically by executing the c or by calling help and usage.
835 // If c already has help flag, it will do nothing.
836 func (c *Command) InitDefaultHelpFlag() {
837 c.mergePersistentFlags()
838 if c.Flags().Lookup("help") == nil {
841 usage += "this command"
845 c.Flags().BoolP("help", "h", false, usage)
849 // InitDefaultHelpCmd adds default help command to c.
850 // It is called automatically by executing the c or by calling help and usage.
851 // If c already has help command or c has no subcommands, it will do nothing.
852 func (c *Command) InitDefaultHelpCmd() {
853 if !c.HasSubCommands() {
857 if c.helpCommand == nil {
858 c.helpCommand = &Command{
859 Use: "help [command]",
860 Short: "Help about any command",
861 Long: `Help provides help for any command in the application.
862 Simply type ` + c.Name() + ` help [path to command] for full details.`,
864 Run: func(c *Command, args []string) {
865 cmd, _, e := c.Root().Find(args)
866 if cmd == nil || e != nil {
867 c.Printf("Unknown help topic %#q\n", args)
870 cmd.InitDefaultHelpFlag() // make possible 'help' flag to be shown
876 c.RemoveCommand(c.helpCommand)
877 c.AddCommand(c.helpCommand)
880 // ResetCommands used for testing.
881 func (c *Command) ResetCommands() {
885 c.parentsPflags = nil
888 // Sorts commands by their names.
889 type commandSorterByName []*Command
891 func (c commandSorterByName) Len() int { return len(c) }
892 func (c commandSorterByName) Swap(i, j int) { c[i], c[j] = c[j], c[i] }
893 func (c commandSorterByName) Less(i, j int) bool { return c[i].Name() < c[j].Name() }
895 // Commands returns a sorted slice of child commands.
896 func (c *Command) Commands() []*Command {
897 // do not sort commands if it already sorted or sorting was disabled
898 if EnableCommandSorting && !c.commandsAreSorted {
899 sort.Sort(commandSorterByName(c.commands))
900 c.commandsAreSorted = true
905 // AddCommand adds one or more commands to this parent command.
906 func (c *Command) AddCommand(cmds ...*Command) {
907 for i, x := range cmds {
909 panic("Command can't be a child of itself")
912 // update max lengths
913 usageLen := len(x.Use)
914 if usageLen > c.commandsMaxUseLen {
915 c.commandsMaxUseLen = usageLen
917 commandPathLen := len(x.CommandPath())
918 if commandPathLen > c.commandsMaxCommandPathLen {
919 c.commandsMaxCommandPathLen = commandPathLen
921 nameLen := len(x.Name())
922 if nameLen > c.commandsMaxNameLen {
923 c.commandsMaxNameLen = nameLen
925 // If global normalization function exists, update all children
926 if c.globNormFunc != nil {
927 x.SetGlobalNormalizationFunc(c.globNormFunc)
929 c.commands = append(c.commands, x)
930 c.commandsAreSorted = false
934 // RemoveCommand removes one or more commands from a parent command.
935 func (c *Command) RemoveCommand(cmds ...*Command) {
936 commands := []*Command{}
938 for _, command := range c.commands {
939 for _, cmd := range cmds {
945 commands = append(commands, command)
947 c.commands = commands
948 // recompute all lengths
949 c.commandsMaxUseLen = 0
950 c.commandsMaxCommandPathLen = 0
951 c.commandsMaxNameLen = 0
952 for _, command := range c.commands {
953 usageLen := len(command.Use)
954 if usageLen > c.commandsMaxUseLen {
955 c.commandsMaxUseLen = usageLen
957 commandPathLen := len(command.CommandPath())
958 if commandPathLen > c.commandsMaxCommandPathLen {
959 c.commandsMaxCommandPathLen = commandPathLen
961 nameLen := len(command.Name())
962 if nameLen > c.commandsMaxNameLen {
963 c.commandsMaxNameLen = nameLen
968 // Print is a convenience method to Print to the defined output, fallback to Stderr if not set.
969 func (c *Command) Print(i ...interface{}) {
970 fmt.Fprint(c.OutOrStderr(), i...)
973 // Println is a convenience method to Println to the defined output, fallback to Stderr if not set.
974 func (c *Command) Println(i ...interface{}) {
975 c.Print(fmt.Sprintln(i...))
978 // Printf is a convenience method to Printf to the defined output, fallback to Stderr if not set.
979 func (c *Command) Printf(format string, i ...interface{}) {
980 c.Print(fmt.Sprintf(format, i...))
983 // CommandPath returns the full path to this command.
984 func (c *Command) CommandPath() string {
986 return c.Parent().CommandPath() + " " + c.Name()
991 // UseLine puts out the full usage for a given command (including parents).
992 func (c *Command) UseLine() string {
995 useline = c.parent.CommandPath() + " " + c.Use
999 if c.HasAvailableFlags() && !strings.Contains(useline, "[flags]") {
1000 useline += " [flags]"
1005 // DebugFlags used to determine which flags have been assigned to which commands
1006 // and which persist.
1007 func (c *Command) DebugFlags() {
1008 c.Println("DebugFlags called on", c.Name())
1009 var debugflags func(*Command)
1011 debugflags = func(x *Command) {
1012 if x.HasFlags() || x.HasPersistentFlags() {
1016 x.flags.VisitAll(func(f *flag.Flag) {
1017 if x.HasPersistentFlags() && x.persistentFlag(f.Name) != nil {
1018 c.Println(" -"+f.Shorthand+",", "--"+f.Name, "["+f.DefValue+"]", "", f.Value, " [LP]")
1020 c.Println(" -"+f.Shorthand+",", "--"+f.Name, "["+f.DefValue+"]", "", f.Value, " [L]")
1024 if x.HasPersistentFlags() {
1025 x.pflags.VisitAll(func(f *flag.Flag) {
1027 if x.flags.Lookup(f.Name) == nil {
1028 c.Println(" -"+f.Shorthand+",", "--"+f.Name, "["+f.DefValue+"]", "", f.Value, " [P]")
1031 c.Println(" -"+f.Shorthand+",", "--"+f.Name, "["+f.DefValue+"]", "", f.Value, " [P]")
1035 c.Println(x.flagErrorBuf)
1036 if x.HasSubCommands() {
1037 for _, y := range x.commands {
1046 // Name returns the command's name: the first word in the use line.
1047 func (c *Command) Name() string {
1049 i := strings.Index(name, " ")
1056 // HasAlias determines if a given string is an alias of the command.
1057 func (c *Command) HasAlias(s string) bool {
1058 for _, a := range c.Aliases {
1066 // hasNameOrAliasPrefix returns true if the Name or any of aliases start
1068 func (c *Command) hasNameOrAliasPrefix(prefix string) bool {
1069 if strings.HasPrefix(c.Name(), prefix) {
1072 for _, alias := range c.Aliases {
1073 if strings.HasPrefix(alias, prefix) {
1080 // NameAndAliases returns a list of the command name and all aliases
1081 func (c *Command) NameAndAliases() string {
1082 return strings.Join(append([]string{c.Name()}, c.Aliases...), ", ")
1085 // HasExample determines if the command has example.
1086 func (c *Command) HasExample() bool {
1087 return len(c.Example) > 0
1090 // Runnable determines if the command is itself runnable.
1091 func (c *Command) Runnable() bool {
1092 return c.Run != nil || c.RunE != nil
1095 // HasSubCommands determines if the command has children commands.
1096 func (c *Command) HasSubCommands() bool {
1097 return len(c.commands) > 0
1100 // IsAvailableCommand determines if a command is available as a non-help command
1101 // (this includes all non deprecated/hidden commands).
1102 func (c *Command) IsAvailableCommand() bool {
1103 if len(c.Deprecated) != 0 || c.Hidden {
1107 if c.HasParent() && c.Parent().helpCommand == c {
1111 if c.Runnable() || c.HasAvailableSubCommands() {
1118 // IsAdditionalHelpTopicCommand determines if a command is an additional
1119 // help topic command; additional help topic command is determined by the
1120 // fact that it is NOT runnable/hidden/deprecated, and has no sub commands that
1121 // are runnable/hidden/deprecated.
1122 // Concrete example: https://github.com/spf13/cobra/issues/393#issuecomment-282741924.
1123 func (c *Command) IsAdditionalHelpTopicCommand() bool {
1124 // if a command is runnable, deprecated, or hidden it is not a 'help' command
1125 if c.Runnable() || len(c.Deprecated) != 0 || c.Hidden {
1129 // if any non-help sub commands are found, the command is not a 'help' command
1130 for _, sub := range c.commands {
1131 if !sub.IsAdditionalHelpTopicCommand() {
1136 // the command either has no sub commands, or no non-help sub commands
1140 // HasHelpSubCommands determines if a command has any available 'help' sub commands
1141 // that need to be shown in the usage/help default template under 'additional help
1143 func (c *Command) HasHelpSubCommands() bool {
1144 // return true on the first found available 'help' sub command
1145 for _, sub := range c.commands {
1146 if sub.IsAdditionalHelpTopicCommand() {
1151 // the command either has no sub commands, or no available 'help' sub commands
1155 // HasAvailableSubCommands determines if a command has available sub commands that
1156 // need to be shown in the usage/help default template under 'available commands'.
1157 func (c *Command) HasAvailableSubCommands() bool {
1158 // return true on the first found available (non deprecated/help/hidden)
1160 for _, sub := range c.commands {
1161 if sub.IsAvailableCommand() {
1166 // the command either has no sub comamnds, or no available (non deprecated/help/hidden)
1171 // HasParent determines if the command is a child command.
1172 func (c *Command) HasParent() bool {
1173 return c.parent != nil
1176 // GlobalNormalizationFunc returns the global normalization function or nil if doesn't exists.
1177 func (c *Command) GlobalNormalizationFunc() func(f *flag.FlagSet, name string) flag.NormalizedName {
1178 return c.globNormFunc
1181 // Flags returns the complete FlagSet that applies
1182 // to this command (local and persistent declared here and by all parents).
1183 func (c *Command) Flags() *flag.FlagSet {
1185 c.flags = flag.NewFlagSet(c.Name(), flag.ContinueOnError)
1186 if c.flagErrorBuf == nil {
1187 c.flagErrorBuf = new(bytes.Buffer)
1189 c.flags.SetOutput(c.flagErrorBuf)
1195 // LocalNonPersistentFlags are flags specific to this command which will NOT persist to subcommands.
1196 func (c *Command) LocalNonPersistentFlags() *flag.FlagSet {
1197 persistentFlags := c.PersistentFlags()
1199 out := flag.NewFlagSet(c.Name(), flag.ContinueOnError)
1200 c.LocalFlags().VisitAll(func(f *flag.Flag) {
1201 if persistentFlags.Lookup(f.Name) == nil {
1208 // LocalFlags returns the local FlagSet specifically set in the current command.
1209 func (c *Command) LocalFlags() *flag.FlagSet {
1210 c.mergePersistentFlags()
1212 if c.lflags == nil {
1213 c.lflags = flag.NewFlagSet(c.Name(), flag.ContinueOnError)
1214 if c.flagErrorBuf == nil {
1215 c.flagErrorBuf = new(bytes.Buffer)
1217 c.lflags.SetOutput(c.flagErrorBuf)
1219 c.lflags.SortFlags = c.Flags().SortFlags
1220 if c.globNormFunc != nil {
1221 c.lflags.SetNormalizeFunc(c.globNormFunc)
1224 addToLocal := func(f *flag.Flag) {
1225 if c.lflags.Lookup(f.Name) == nil && c.parentsPflags.Lookup(f.Name) == nil {
1229 c.Flags().VisitAll(addToLocal)
1230 c.PersistentFlags().VisitAll(addToLocal)
1234 // InheritedFlags returns all flags which were inherited from parents commands.
1235 func (c *Command) InheritedFlags() *flag.FlagSet {
1236 c.mergePersistentFlags()
1238 if c.iflags == nil {
1239 c.iflags = flag.NewFlagSet(c.Name(), flag.ContinueOnError)
1240 if c.flagErrorBuf == nil {
1241 c.flagErrorBuf = new(bytes.Buffer)
1243 c.iflags.SetOutput(c.flagErrorBuf)
1246 local := c.LocalFlags()
1247 if c.globNormFunc != nil {
1248 c.iflags.SetNormalizeFunc(c.globNormFunc)
1251 c.parentsPflags.VisitAll(func(f *flag.Flag) {
1252 if c.iflags.Lookup(f.Name) == nil && local.Lookup(f.Name) == nil {
1259 // NonInheritedFlags returns all flags which were not inherited from parent commands.
1260 func (c *Command) NonInheritedFlags() *flag.FlagSet {
1261 return c.LocalFlags()
1264 // PersistentFlags returns the persistent FlagSet specifically set in the current command.
1265 func (c *Command) PersistentFlags() *flag.FlagSet {
1266 if c.pflags == nil {
1267 c.pflags = flag.NewFlagSet(c.Name(), flag.ContinueOnError)
1268 if c.flagErrorBuf == nil {
1269 c.flagErrorBuf = new(bytes.Buffer)
1271 c.pflags.SetOutput(c.flagErrorBuf)
1276 // ResetFlags is used in testing.
1277 func (c *Command) ResetFlags() {
1278 c.flagErrorBuf = new(bytes.Buffer)
1279 c.flagErrorBuf.Reset()
1280 c.flags = flag.NewFlagSet(c.Name(), flag.ContinueOnError)
1281 c.flags.SetOutput(c.flagErrorBuf)
1282 c.pflags = flag.NewFlagSet(c.Name(), flag.ContinueOnError)
1283 c.pflags.SetOutput(c.flagErrorBuf)
1287 c.parentsPflags = nil
1290 // HasFlags checks if the command contains any flags (local plus persistent from the entire structure).
1291 func (c *Command) HasFlags() bool {
1292 return c.Flags().HasFlags()
1295 // HasPersistentFlags checks if the command contains persistent flags.
1296 func (c *Command) HasPersistentFlags() bool {
1297 return c.PersistentFlags().HasFlags()
1300 // HasLocalFlags checks if the command has flags specifically declared locally.
1301 func (c *Command) HasLocalFlags() bool {
1302 return c.LocalFlags().HasFlags()
1305 // HasInheritedFlags checks if the command has flags inherited from its parent command.
1306 func (c *Command) HasInheritedFlags() bool {
1307 return c.InheritedFlags().HasFlags()
1310 // HasAvailableFlags checks if the command contains any flags (local plus persistent from the entire
1311 // structure) which are not hidden or deprecated.
1312 func (c *Command) HasAvailableFlags() bool {
1313 return c.Flags().HasAvailableFlags()
1316 // HasAvailablePersistentFlags checks if the command contains persistent flags which are not hidden or deprecated.
1317 func (c *Command) HasAvailablePersistentFlags() bool {
1318 return c.PersistentFlags().HasAvailableFlags()
1321 // HasAvailableLocalFlags checks if the command has flags specifically declared locally which are not hidden
1323 func (c *Command) HasAvailableLocalFlags() bool {
1324 return c.LocalFlags().HasAvailableFlags()
1327 // HasAvailableInheritedFlags checks if the command has flags inherited from its parent command which are
1328 // not hidden or deprecated.
1329 func (c *Command) HasAvailableInheritedFlags() bool {
1330 return c.InheritedFlags().HasAvailableFlags()
1333 // Flag climbs up the command tree looking for matching flag.
1334 func (c *Command) Flag(name string) (flag *flag.Flag) {
1335 flag = c.Flags().Lookup(name)
1338 flag = c.persistentFlag(name)
1344 // Recursively find matching persistent flag.
1345 func (c *Command) persistentFlag(name string) (flag *flag.Flag) {
1346 if c.HasPersistentFlags() {
1347 flag = c.PersistentFlags().Lookup(name)
1351 c.updateParentsPflags()
1352 flag = c.parentsPflags.Lookup(name)
1357 // ParseFlags parses persistent flag tree and local flags.
1358 func (c *Command) ParseFlags(args []string) error {
1359 if c.DisableFlagParsing {
1363 if c.flagErrorBuf == nil {
1364 c.flagErrorBuf = new(bytes.Buffer)
1366 beforeErrorBufLen := c.flagErrorBuf.Len()
1367 c.mergePersistentFlags()
1368 err := c.Flags().Parse(args)
1369 // Print warnings if they occurred (e.g. deprecated flag messages).
1370 if c.flagErrorBuf.Len()-beforeErrorBufLen > 0 && err == nil {
1371 c.Print(c.flagErrorBuf.String())
1377 // Parent returns a commands parent command.
1378 func (c *Command) Parent() *Command {
1382 // mergePersistentFlags merges c.PersistentFlags() to c.Flags()
1383 // and adds missing persistent flags of all parents.
1384 func (c *Command) mergePersistentFlags() {
1385 c.updateParentsPflags()
1386 c.Flags().AddFlagSet(c.PersistentFlags())
1387 c.Flags().AddFlagSet(c.parentsPflags)
1390 // updateParentsPflags updates c.parentsPflags by adding
1391 // new persistent flags of all parents.
1392 // If c.parentsPflags == nil, it makes new.
1393 func (c *Command) updateParentsPflags() {
1394 if c.parentsPflags == nil {
1395 c.parentsPflags = flag.NewFlagSet(c.Name(), flag.ContinueOnError)
1396 c.parentsPflags.SetOutput(c.flagErrorBuf)
1397 c.parentsPflags.SortFlags = false
1400 if c.globNormFunc != nil {
1401 c.parentsPflags.SetNormalizeFunc(c.globNormFunc)
1404 c.Root().PersistentFlags().AddFlagSet(flag.CommandLine)
1406 c.VisitParents(func(parent *Command) {
1407 c.parentsPflags.AddFlagSet(parent.PersistentFlags())