// Copyright 2013-2023 The Cobra Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Package cobra is a commander providing a simple interface to create powerful modern CLI interfaces. // In addition to providing an interface, Cobra simultaneously provides a controller to organize your application code.
package cobra import ( flag ) const ( FlagSetByCobraAnnotation = "cobra_annotation_flag_set_by_cobra" CommandDisplayNameAnnotation = "cobra_annotation_command_display_name" ) // FParseErrWhitelist configures Flag parse errors to be ignored type FParseErrWhitelist flag.ParseErrorsWhitelist // Group Structure to manage groups for commands type Group struct { ID string Title string } // Command is just that, a command for your application. // E.g. 'go run ...' - 'run' is the command. Cobra requires // you to define the usage and description as part of your command // definition to ensure usability. type Command struct { // Use is the one-line usage message. // Recommended syntax is as follows: // [ ] identifies an optional argument. Arguments that are not enclosed in brackets are required. // ... indicates that you can specify multiple values for the previous argument. // | indicates mutually exclusive information. You can use the argument to the left of the separator or the // argument to the right of the separator. You cannot use both arguments in a single use of the command. // { } delimits a set of mutually exclusive arguments when one of the arguments is required. If the arguments are // optional, they are enclosed in brackets ([ ]). // Example: add [-F file | -D dir]... [-f format] profile Use string // Aliases is an array of aliases that can be used instead of the first word in Use. Aliases []string // SuggestFor is an array of command names for which this command will be suggested - // similar to aliases but only suggests. SuggestFor []string // Short is the short description shown in the 'help' output. Short string // The group id under which this subcommand is grouped in the 'help' output of its parent. GroupID string // Long is the long message shown in the 'help <this-command>' output. Long string // Example is examples of how to use the command. Example string // ValidArgs is list of all valid non-flag arguments that are accepted in shell completions ValidArgs []string // ValidArgsFunction is an optional function that provides valid non-flag arguments for shell completion. // It is a dynamic version of using ValidArgs. // Only one of ValidArgs and ValidArgsFunction can be used for a command. ValidArgsFunction func(cmd *Command, args []string, toComplete string) ([]string, ShellCompDirective) // Expected arguments Args PositionalArgs // ArgAliases is List of aliases for ValidArgs. // These are not suggested to the user in the shell completion, // but accepted if entered manually. ArgAliases []string // BashCompletionFunction is custom bash functions used by the legacy bash autocompletion generator. // For portability with other shells, it is recommended to instead use ValidArgsFunction BashCompletionFunction string // Deprecated defines, if this command is deprecated and should print this string when used. Deprecated string // Annotations are key/value pairs that can be used by applications to identify or // group commands or set special options. Annotations map[string]string // Version defines the version for this command. If this value is non-empty and the command does not // define a "version" flag, a "version" boolean flag will be added to the command and, if specified, // will print content of the "Version" variable. A shorthand "v" flag will also be added if the // command does not define one. Version string // The *Run functions are executed in the following order: // * PersistentPreRun() // * PreRun() // * Run() // * PostRun() // * PersistentPostRun() // All functions get the same args, the arguments after the command name. // The *PreRun and *PostRun functions will only be executed if the Run function of the current // command has been declared. // // PersistentPreRun: children of this command will inherit and execute. PersistentPreRun func(cmd *Command, args []string) // PersistentPreRunE: PersistentPreRun but returns an error. PersistentPreRunE func(cmd *Command, args []string) error // PreRun: children of this command will not inherit. PreRun func(cmd *Command, args []string) // PreRunE: PreRun but returns an error. PreRunE func(cmd *Command, args []string) error // Run: Typically the actual work function. Most commands will only implement this. Run func(cmd *Command, args []string) // RunE: Run but returns an error. RunE func(cmd *Command, args []string) error // PostRun: run after the Run command. PostRun func(cmd *Command, args []string) // PostRunE: PostRun but returns an error. PostRunE func(cmd *Command, args []string) error // PersistentPostRun: children of this command will inherit and execute after PostRun. PersistentPostRun func(cmd *Command, args []string) // PersistentPostRunE: PersistentPostRun but returns an error. PersistentPostRunE func(cmd *Command, args []string) error // groups for subcommands commandgroups []*Group // args is actual args parsed from flags. args []string // flagErrorBuf contains all error messages from pflag. flagErrorBuf *bytes.Buffer // flags is full set of flags. flags *flag.FlagSet // pflags contains persistent flags. pflags *flag.FlagSet // lflags contains local flags. // This field does not represent internal state, it's used as a cache to optimise LocalFlags function call lflags *flag.FlagSet // iflags contains inherited flags. // This field does not represent internal state, it's used as a cache to optimise InheritedFlags function call iflags *flag.FlagSet // parentsPflags is all persistent flags of cmd's parents. parentsPflags *flag.FlagSet // globNormFunc is the global normalization function // that we can use on every pflag set and children commands globNormFunc func(f *flag.FlagSet, name string) flag.NormalizedName // usageFunc is usage func defined by user. usageFunc func(*Command) error // usageTemplate is usage template defined by user. usageTemplate string // flagErrorFunc is func defined by user and it's called when the parsing of // flags returns an error. flagErrorFunc func(*Command, error) error // helpTemplate is help template defined by user. helpTemplate string // helpFunc is help func defined by user. helpFunc func(*Command, []string) // helpCommand is command with usage 'help'. If it's not defined by user, // cobra uses default help command. helpCommand *Command // helpCommandGroupID is the group id for the helpCommand helpCommandGroupID string // completionCommandGroupID is the group id for the completion command completionCommandGroupID string // versionTemplate is the version template defined by user. versionTemplate string // errPrefix is the error message prefix defined by user. errPrefix string // inReader is a reader defined by the user that replaces stdin inReader io.Reader // outWriter is a writer defined by the user that replaces stdout outWriter io.Writer // errWriter is a writer defined by the user that replaces stderr errWriter io.Writer // FParseErrWhitelist flag parse errors to be ignored FParseErrWhitelist FParseErrWhitelist // CompletionOptions is a set of options to control the handling of shell completion CompletionOptions CompletionOptions // commandsAreSorted defines, if command slice are sorted or not. commandsAreSorted bool // commandCalledAs is the name or alias value used to call this command. commandCalledAs struct { name string called bool } ctx context.Context // commands is the list of commands supported by this program. commands []*Command // parent is a parent command for this command. parent *Command // Max lengths of commands' string lengths for use in padding. commandsMaxUseLen int commandsMaxCommandPathLen int commandsMaxNameLen int // TraverseChildren parses flags on all parents before executing child command. TraverseChildren bool // Hidden defines, if this command is hidden and should NOT show up in the list of available commands. Hidden bool // SilenceErrors is an option to quiet errors down stream. SilenceErrors bool // SilenceUsage is an option to silence usage when an error occurs. SilenceUsage bool // DisableFlagParsing disables the flag parsing. // If this is true all flags will be passed to the command as arguments. DisableFlagParsing bool // DisableAutoGenTag defines, if gen tag ("Auto generated by spf13/cobra...") // will be printed by generating docs for this command. DisableAutoGenTag bool // DisableFlagsInUseLine will disable the addition of [flags] to the usage // line of a command when printing help or generating docs DisableFlagsInUseLine bool // DisableSuggestions disables the suggestions based on Levenshtein distance // that go along with 'unknown command' messages. DisableSuggestions bool // SuggestionsMinimumDistance defines minimum levenshtein distance to display suggestions. // Must be > 0. SuggestionsMinimumDistance int } // Context returns underlying command context. If command was executed // with ExecuteContext or the context was set with SetContext, the // previously set context will be returned. Otherwise, nil is returned. // // Notice that a call to Execute and ExecuteC will replace a nil context of // a command with a context.Background, so a background context will be // returned by Context after one of these functions has been called. func ( *Command) () context.Context { return .ctx } // SetContext sets context for the command. This context will be overwritten by // Command.ExecuteContext or Command.ExecuteContextC. func ( *Command) ( context.Context) { .ctx = } // SetArgs sets arguments for the command. It is set to os.Args[1:] by default, if desired, can be overridden // particularly useful when testing. func ( *Command) ( []string) { .args = } // SetOutput sets the destination for usage and error messages. // If output is nil, os.Stderr is used. // Deprecated: Use SetOut and/or SetErr instead func ( *Command) ( io.Writer) { .outWriter = .errWriter = } // SetOut sets the destination for usage messages. // If newOut is nil, os.Stdout is used. func ( *Command) ( io.Writer) { .outWriter = } // SetErr sets the destination for error messages. // If newErr is nil, os.Stderr is used. func ( *Command) ( io.Writer) { .errWriter = } // SetIn sets the source for input data // If newIn is nil, os.Stdin is used. func ( *Command) ( io.Reader) { .inReader = } // SetUsageFunc sets usage function. Usage can be defined by application. func ( *Command) ( func(*Command) error) { .usageFunc = } // SetUsageTemplate sets usage template. Can be defined by Application. func ( *Command) ( string) { .usageTemplate = } // SetFlagErrorFunc sets a function to generate an error when flag parsing // fails. func ( *Command) ( func(*Command, error) error) { .flagErrorFunc = } // SetHelpFunc sets help function. Can be defined by Application. func ( *Command) ( func(*Command, []string)) { .helpFunc = } // SetHelpCommand sets help command. func ( *Command) ( *Command) { .helpCommand = } // SetHelpCommandGroupID sets the group id of the help command. func ( *Command) ( string) { if .helpCommand != nil { .helpCommand.GroupID = } // helpCommandGroupID is used if no helpCommand is defined by the user .helpCommandGroupID = } // SetCompletionCommandGroupID sets the group id of the completion command. func ( *Command) ( string) { // completionCommandGroupID is used if no completion command is defined by the user .Root().completionCommandGroupID = } // SetHelpTemplate sets help template to be used. Application can use it to set custom template. func ( *Command) ( string) { .helpTemplate = } // SetVersionTemplate sets version template to be used. Application can use it to set custom template. func ( *Command) ( string) { .versionTemplate = } // SetErrPrefix sets error message prefix to be used. Application can use it to set custom prefix. func ( *Command) ( string) { .errPrefix = } // SetGlobalNormalizationFunc sets a normalization function to all flag sets and also to child commands. // The user should not have a cyclic dependency on commands. func ( *Command) ( func( *flag.FlagSet, string) flag.NormalizedName) { .Flags().SetNormalizeFunc() .PersistentFlags().SetNormalizeFunc() .globNormFunc = for , := range .commands { .() } } // OutOrStdout returns output to stdout. func ( *Command) () io.Writer { return .getOut(os.Stdout) } // OutOrStderr returns output to stderr func ( *Command) () io.Writer { return .getOut(os.Stderr) } // ErrOrStderr returns output to stderr func ( *Command) () io.Writer { return .getErr(os.Stderr) } // InOrStdin returns input to stdin func ( *Command) () io.Reader { return .getIn(os.Stdin) } func ( *Command) ( io.Writer) io.Writer { if .outWriter != nil { return .outWriter } if .HasParent() { return .parent.() } return } func ( *Command) ( io.Writer) io.Writer { if .errWriter != nil { return .errWriter } if .HasParent() { return .parent.() } return } func ( *Command) ( io.Reader) io.Reader { if .inReader != nil { return .inReader } if .HasParent() { return .parent.() } return } // UsageFunc returns either the function set by SetUsageFunc for this command // or a parent, or it returns a default usage function. func ( *Command) () ( func(*Command) error) { if .usageFunc != nil { return .usageFunc } if .HasParent() { return .Parent().() } return func( *Command) error { .mergePersistentFlags() := tmpl(.OutOrStderr(), .UsageTemplate(), ) if != nil { .PrintErrln() } return } } // Usage puts out the usage for the command. // Used when a user provides invalid input. // Can be defined by user by overriding UsageFunc. func ( *Command) () error { return .UsageFunc()() } // HelpFunc returns either the function set by SetHelpFunc for this command // or a parent, or it returns a function with default help behavior. func ( *Command) () func(*Command, []string) { if .helpFunc != nil { return .helpFunc } if .HasParent() { return .Parent().() } return func( *Command, []string) { .mergePersistentFlags() // The help should be sent to stdout // See https://github.com/spf13/cobra/issues/1002 := tmpl(.OutOrStdout(), .HelpTemplate(), ) if != nil { .PrintErrln() } } } // Help puts out the help for the command. // Used when a user calls help [command]. // Can be defined by user by overriding HelpFunc. func ( *Command) () error { .HelpFunc()(, []string{}) return nil } // UsageString returns usage string. func ( *Command) () string { // Storing normal writers := .outWriter := .errWriter := new(bytes.Buffer) .outWriter = .errWriter = CheckErr(.Usage()) // Setting things back to normal .outWriter = .errWriter = return .String() } // FlagErrorFunc returns either the function set by SetFlagErrorFunc for this // command or a parent, or it returns a function which returns the original // error. func ( *Command) () ( func(*Command, error) error) { if .flagErrorFunc != nil { return .flagErrorFunc } if .HasParent() { return .parent.() } return func( *Command, error) error { return } } var minUsagePadding = 25 // UsagePadding return padding for the usage. func ( *Command) () int { if .parent == nil || minUsagePadding > .parent.commandsMaxUseLen { return minUsagePadding } return .parent.commandsMaxUseLen } var minCommandPathPadding = 11 // CommandPathPadding return padding for the command path. func ( *Command) () int { if .parent == nil || minCommandPathPadding > .parent.commandsMaxCommandPathLen { return minCommandPathPadding } return .parent.commandsMaxCommandPathLen } var minNamePadding = 11 // NamePadding returns padding for the name. func ( *Command) () int { if .parent == nil || minNamePadding > .parent.commandsMaxNameLen { return minNamePadding } return .parent.commandsMaxNameLen } // UsageTemplate returns usage template for the command. func ( *Command) () string { if .usageTemplate != "" { return .usageTemplate } if .HasParent() { return .parent.() } return `Usage:{{if .Runnable}} {{.UseLine}}{{end}}{{if .HasAvailableSubCommands}} {{.CommandPath}} [command]{{end}}{{if gt (len .Aliases) 0}} Aliases: {{.NameAndAliases}}{{end}}{{if .HasExample}} Examples: {{.Example}}{{end}}{{if .HasAvailableSubCommands}}{{$cmds := .Commands}}{{if eq (len .Groups) 0}} Available Commands:{{range $cmds}}{{if (or .IsAvailableCommand (eq .Name "help"))}} {{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}{{else}}{{range $group := .Groups}} {{.Title}}{{range $cmds}}{{if (and (eq .GroupID $group.ID) (or .IsAvailableCommand (eq .Name "help")))}} {{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}{{end}}{{if not .AllChildCommandsHaveGroup}} Additional Commands:{{range $cmds}}{{if (and (eq .GroupID "") (or .IsAvailableCommand (eq .Name "help")))}} {{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}{{end}}{{end}}{{end}}{{if .HasAvailableLocalFlags}} Flags: {{.LocalFlags.FlagUsages | trimTrailingWhitespaces}}{{end}}{{if .HasAvailableInheritedFlags}} Global Flags: {{.InheritedFlags.FlagUsages | trimTrailingWhitespaces}}{{end}}{{if .HasHelpSubCommands}} Additional help topics:{{range .Commands}}{{if .IsAdditionalHelpTopicCommand}} {{rpad .CommandPath .CommandPathPadding}} {{.Short}}{{end}}{{end}}{{end}}{{if .HasAvailableSubCommands}} Use "{{.CommandPath}} [command] --help" for more information about a command.{{end}} ` } // HelpTemplate return help template for the command. func ( *Command) () string { if .helpTemplate != "" { return .helpTemplate } if .HasParent() { return .parent.() } return `{{with (or .Long .Short)}}{{. | trimTrailingWhitespaces}} {{end}}{{if or .Runnable .HasSubCommands}}{{.UsageString}}{{end}}` } // VersionTemplate return version template for the command. func ( *Command) () string { if .versionTemplate != "" { return .versionTemplate } if .HasParent() { return .parent.() } return `{{with .Name}}{{printf "%s " .}}{{end}}{{printf "version %s" .Version}} ` } // ErrPrefix return error message prefix for the command func ( *Command) () string { if .errPrefix != "" { return .errPrefix } if .HasParent() { return .parent.() } return "Error:" } func hasNoOptDefVal( string, *flag.FlagSet) bool { := .Lookup() if == nil { return false } return .NoOptDefVal != "" } func shortHasNoOptDefVal( string, *flag.FlagSet) bool { if len() == 0 { return false } := .ShorthandLookup([:1]) if == nil { return false } return .NoOptDefVal != "" } func stripFlags( []string, *Command) []string { if len() == 0 { return } .mergePersistentFlags() := []string{} := .Flags() : for len() > 0 { := [0] = [1:] switch { case == "--": // "--" terminates the flags break case strings.HasPrefix(, "--") && !strings.Contains(, "=") && !hasNoOptDefVal([2:], ): // If '--flag arg' then // delete arg from args. fallthrough // (do the same as below) case strings.HasPrefix(, "-") && !strings.Contains(, "=") && len() == 2 && !shortHasNoOptDefVal([1:], ): // If '-f arg' then // delete 'arg' from args or break the loop if len(args) <= 1. if len() <= 1 { break } else { = [1:] continue } case != "" && !strings.HasPrefix(, "-"): = append(, ) } } return } // argsMinusFirstX removes only the first x from args. Otherwise, commands that look like // openshift admin policy add-role-to-user admin my-user, lose the admin argument (arg[4]). // Special care needs to be taken not to remove a flag value. func ( *Command) ( []string, string) []string { if len() == 0 { return } .mergePersistentFlags() := .Flags() : for := 0; < len(); ++ { := [] switch { case == "--": // -- means we have reached the end of the parseable args. Break out of the loop now. break case strings.HasPrefix(, "--") && !strings.Contains(, "=") && !hasNoOptDefVal([2:], ): fallthrough case strings.HasPrefix(, "-") && !strings.Contains(, "=") && len() == 2 && !shortHasNoOptDefVal([1:], ): // This is a flag without a default value, and an equal sign is not used. Increment pos in order to skip // over the next arg, because that is the value of this flag. ++ continue case !strings.HasPrefix(, "-"): // This is not a flag or a flag value. Check to see if it matches what we're looking for, and if so, // return the args, excluding the one at this position. if == { := make([]string, 0, len()-1) = append(, [:]...) = append(, [+1:]...) return } } } return } func isFlagArg( string) bool { return ((len() >= 3 && [0:2] == "--") || (len() >= 2 && [0] == '-' && [1] != '-')) } // Find the target command given the args and command tree // Meant to be run on the highest node. Only searches down. func ( *Command) ( []string) (*Command, []string, error) { var func(*Command, []string) (*Command, []string) = func( *Command, []string) (*Command, []string) { := stripFlags(, ) if len() == 0 { return , } := [0] := .findNext() if != nil { return (, .argsMinusFirstX(, )) } return , } , := (, ) if .Args == nil { return , , legacyArgs(, stripFlags(, )) } return , , nil } func ( *Command) ( string) string { if .DisableSuggestions { return "" } if .SuggestionsMinimumDistance <= 0 { .SuggestionsMinimumDistance = 2 } var strings.Builder if := .SuggestionsFor(); len() > 0 { .WriteString("\n\nDid you mean this?\n") for , := range { _, _ = fmt.Fprintf(&, "\t%v\n", ) } } return .String() } func ( *Command) ( string) *Command { := make([]*Command, 0) for , := range .commands { if commandNameMatches(.Name(), ) || .HasAlias() { .commandCalledAs.name = return } if EnablePrefixMatching && .hasNameOrAliasPrefix() { = append(, ) } } if len() == 1 { // Temporarily disable gosec G602, which produces a false positive. // See https://github.com/securego/gosec/issues/1005. return [0] // #nosec G602 } return nil } // Traverse the command tree to find the command, and parse args for // each parent. func ( *Command) ( []string) (*Command, []string, error) { := []string{} := false for , := range { switch { // A long flag with a space separated value case strings.HasPrefix(, "--") && !strings.Contains(, "="): // TODO: this isn't quite right, we should really check ahead for 'true' or 'false' = !hasNoOptDefVal([2:], .Flags()) = append(, ) continue // A short flag with a space separated value case strings.HasPrefix(, "-") && !strings.Contains(, "=") && len() == 2 && !shortHasNoOptDefVal([1:], .Flags()): = true = append(, ) continue // The value for a flag case : = false = append(, ) continue // A flag without a value, or with an `=` separated value case isFlagArg(): = append(, ) continue } := .findNext() if == nil { return , , nil } if := .ParseFlags(); != nil { return nil, , } return .([+1:]) } return , , nil } // SuggestionsFor provides suggestions for the typedName. func ( *Command) ( string) []string { := []string{} for , := range .commands { if .IsAvailableCommand() { := ld(, .Name(), true) := <= .SuggestionsMinimumDistance := strings.HasPrefix(strings.ToLower(.Name()), strings.ToLower()) if || { = append(, .Name()) } for , := range .SuggestFor { if strings.EqualFold(, ) { = append(, .Name()) } } } } return } // VisitParents visits all parents of the command and invokes fn on each parent. func ( *Command) ( func(*Command)) { if .HasParent() { (.Parent()) .Parent().() } } // Root finds root command. func ( *Command) () *Command { if .HasParent() { return .Parent().() } return } // ArgsLenAtDash will return the length of c.Flags().Args at the moment // when a -- was found during args parsing. func ( *Command) () int { return .Flags().ArgsLenAtDash() } func ( *Command) ( []string) ( error) { if == nil { return fmt.Errorf("called Execute() on a nil Command") } if len(.Deprecated) > 0 { .Printf("Command %q is deprecated, %s\n", .Name(), .Deprecated) } // initialize help and version flag at the last point possible to allow for user // overriding .InitDefaultHelpFlag() .InitDefaultVersionFlag() = .ParseFlags() if != nil { return .FlagErrorFunc()(, ) } // If help is called, regardless of other flags, return we want help. // Also say we need help if the command isn't runnable. , := .Flags().GetBool("help") if != nil { // should be impossible to get here as we always declare a help // flag in InitDefaultHelpFlag() .Println("\"help\" flag declared as non-bool. Please correct your code") return } if { return flag.ErrHelp } // for back-compat, only add version flag behavior if version is defined if .Version != "" { , := .Flags().GetBool("version") if != nil { .Println("\"version\" flag declared as non-bool. Please correct your code") return } if { := tmpl(.OutOrStdout(), .VersionTemplate(), ) if != nil { .Println() } return } } if !.Runnable() { return flag.ErrHelp } .preRun() defer .postRun() := .Flags().Args() if .DisableFlagParsing { = } if := .ValidateArgs(); != nil { return } := make([]*Command, 0, 5) for := ; != nil; = .Parent() { if EnableTraverseRunHooks { // When EnableTraverseRunHooks is set: // - Execute all persistent pre-runs from the root parent till this command. // - Execute all persistent post-runs from this command till the root parent. = append([]*Command{}, ...) } else { // Otherwise, execute only the first found persistent hook. = append(, ) } } for , := range { if .PersistentPreRunE != nil { if := .PersistentPreRunE(, ); != nil { return } if !EnableTraverseRunHooks { break } } else if .PersistentPreRun != nil { .PersistentPreRun(, ) if !EnableTraverseRunHooks { break } } } if .PreRunE != nil { if := .PreRunE(, ); != nil { return } } else if .PreRun != nil { .PreRun(, ) } if := .ValidateRequiredFlags(); != nil { return } if := .ValidateFlagGroups(); != nil { return } if .RunE != nil { if := .RunE(, ); != nil { return } } else { .Run(, ) } if .PostRunE != nil { if := .PostRunE(, ); != nil { return } } else if .PostRun != nil { .PostRun(, ) } for := ; != nil; = .Parent() { if .PersistentPostRunE != nil { if := .PersistentPostRunE(, ); != nil { return } if !EnableTraverseRunHooks { break } } else if .PersistentPostRun != nil { .PersistentPostRun(, ) if !EnableTraverseRunHooks { break } } } return nil } func ( *Command) () { for , := range initializers { () } } func ( *Command) () { for , := range finalizers { () } } // ExecuteContext is the same as Execute(), but sets the ctx on the command. // Retrieve ctx by calling cmd.Context() inside your *Run lifecycle or ValidArgs // functions. func ( *Command) ( context.Context) error { .ctx = return .Execute() } // Execute uses the args (os.Args[1:] by default) // and run through the command tree finding appropriate matches // for commands and then corresponding flags. func ( *Command) () error { , := .ExecuteC() return } // ExecuteContextC is the same as ExecuteC(), but sets the ctx on the command. // Retrieve ctx by calling cmd.Context() inside your *Run lifecycle or ValidArgs // functions. func ( *Command) ( context.Context) (*Command, error) { .ctx = return .ExecuteC() } // ExecuteC executes the command. func ( *Command) () ( *Command, error) { if .ctx == nil { .ctx = context.Background() } // Regardless of what command execute is called on, run on Root only if .HasParent() { return .Root().() } // windows hook if preExecHookFn != nil { preExecHookFn() } // initialize help at the last point to allow for user overriding .InitDefaultHelpCmd() // initialize completion at the last point to allow for user overriding .InitDefaultCompletionCmd() // Now that all commands have been created, let's make sure all groups // are properly created also .checkCommandGroups() := .args // Workaround FAIL with "go test -v" or "cobra.test -test.v", see #155 if .args == nil && filepath.Base(os.Args[0]) != "cobra.test" { = os.Args[1:] } // initialize the hidden command to be used for shell completion .initCompleteCmd() var []string if .TraverseChildren { , , = .Traverse() } else { , , = .Find() } if != nil { // If found parse to a subcommand and then failed, talk about the subcommand if != nil { = } if !.SilenceErrors { .PrintErrln(.ErrPrefix(), .Error()) .PrintErrf("Run '%v --help' for usage.\n", .CommandPath()) } return , } .commandCalledAs.called = true if .commandCalledAs.name == "" { .commandCalledAs.name = .Name() } // We have to pass global context to children command // if context is present on the parent command. if .ctx == nil { .ctx = .ctx } = .execute() if != nil { // Always show help if requested, even if SilenceErrors is in // effect if errors.Is(, flag.ErrHelp) { .HelpFunc()(, ) return , nil } // If root command has SilenceErrors flagged, // all subcommands should respect it if !.SilenceErrors && !.SilenceErrors { .PrintErrln(.ErrPrefix(), .Error()) } // If root command has SilenceUsage flagged, // all subcommands should respect it if !.SilenceUsage && !.SilenceUsage { .Println(.UsageString()) } } return , } func ( *Command) ( []string) error { if .Args == nil { return ArbitraryArgs(, ) } return .Args(, ) } // ValidateRequiredFlags validates all required flags are present and returns an error otherwise func ( *Command) () error { if .DisableFlagParsing { return nil } := .Flags() := []string{} .VisitAll(func( *flag.Flag) { , := .Annotations[BashCompOneRequiredFlag] if ! { return } if ([0] == "true") && !.Changed { = append(, .Name) } }) if len() > 0 { return fmt.Errorf(`required flag(s) "%s" not set`, strings.Join(, `", "`)) } return nil } // checkCommandGroups checks if a command has been added to a group that does not exists. // If so, we panic because it indicates a coding error that should be corrected. func ( *Command) () { for , := range .commands { // if Group is not defined let the developer know right away if .GroupID != "" && !.ContainsGroup(.GroupID) { panic(fmt.Sprintf("group id '%s' is not defined for subcommand '%s'", .GroupID, .CommandPath())) } .() } } // InitDefaultHelpFlag adds default help flag to c. // It is called automatically by executing the c or by calling help and usage. // If c already has help flag, it will do nothing. func ( *Command) () { .mergePersistentFlags() if .Flags().Lookup("help") == nil { := "help for " := .displayName() if == "" { += "this command" } else { += } .Flags().BoolP("help", "h", false, ) _ = .Flags().SetAnnotation("help", FlagSetByCobraAnnotation, []string{"true"}) } } // InitDefaultVersionFlag adds default version flag to c. // It is called automatically by executing the c. // If c already has a version flag, it will do nothing. // If c.Version is empty, it will do nothing. func ( *Command) () { if .Version == "" { return } .mergePersistentFlags() if .Flags().Lookup("version") == nil { := "version for " if .Name() == "" { += "this command" } else { += .Name() } if .Flags().ShorthandLookup("v") == nil { .Flags().BoolP("version", "v", false, ) } else { .Flags().Bool("version", false, ) } _ = .Flags().SetAnnotation("version", FlagSetByCobraAnnotation, []string{"true"}) } } // InitDefaultHelpCmd adds default help command to c. // It is called automatically by executing the c or by calling help and usage. // If c already has help command or c has no subcommands, it will do nothing. func ( *Command) () { if !.HasSubCommands() { return } if .helpCommand == nil { .helpCommand = &Command{ Use: "help [command]", Short: "Help about any command", Long: `Help provides help for any command in the application. Simply type ` + .displayName() + ` help [path to command] for full details.`, ValidArgsFunction: func( *Command, []string, string) ([]string, ShellCompDirective) { var []string , , := .Root().Find() if != nil { return nil, ShellCompDirectiveNoFileComp } if == nil { // Root help command. = .Root() } for , := range .Commands() { if .IsAvailableCommand() || == .helpCommand { if strings.HasPrefix(.Name(), ) { = append(, fmt.Sprintf("%s\t%s", .Name(), .Short)) } } } return , ShellCompDirectiveNoFileComp }, Run: func( *Command, []string) { , , := .Root().Find() if == nil || != nil { .Printf("Unknown help topic %#q\n", ) CheckErr(.Root().Usage()) } else { .InitDefaultHelpFlag() // make possible 'help' flag to be shown .InitDefaultVersionFlag() // make possible 'version' flag to be shown CheckErr(.Help()) } }, GroupID: .helpCommandGroupID, } } .RemoveCommand(.helpCommand) .AddCommand(.helpCommand) } // ResetCommands delete parent, subcommand and help command from c. func ( *Command) () { .parent = nil .commands = nil .helpCommand = nil .parentsPflags = nil } // Sorts commands by their names. type commandSorterByName []*Command func ( commandSorterByName) () int { return len() } func ( commandSorterByName) (, int) { [], [] = [], [] } func ( commandSorterByName) (, int) bool { return [].Name() < [].Name() } // Commands returns a sorted slice of child commands. func ( *Command) () []*Command { // do not sort commands if it already sorted or sorting was disabled if EnableCommandSorting && !.commandsAreSorted { sort.Sort(commandSorterByName(.commands)) .commandsAreSorted = true } return .commands } // AddCommand adds one or more commands to this parent command. func ( *Command) ( ...*Command) { for , := range { if [] == { panic("Command can't be a child of itself") } [].parent = // update max lengths := len(.Use) if > .commandsMaxUseLen { .commandsMaxUseLen = } := len(.CommandPath()) if > .commandsMaxCommandPathLen { .commandsMaxCommandPathLen = } := len(.Name()) if > .commandsMaxNameLen { .commandsMaxNameLen = } // If global normalization function exists, update all children if .globNormFunc != nil { .SetGlobalNormalizationFunc(.globNormFunc) } .commands = append(.commands, ) .commandsAreSorted = false } } // Groups returns a slice of child command groups. func ( *Command) () []*Group { return .commandgroups } // AllChildCommandsHaveGroup returns if all subcommands are assigned to a group func ( *Command) () bool { for , := range .commands { if (.IsAvailableCommand() || == .helpCommand) && .GroupID == "" { return false } } return true } // ContainsGroup return if groupID exists in the list of command groups. func ( *Command) ( string) bool { for , := range .commandgroups { if .ID == { return true } } return false } // AddGroup adds one or more command groups to this parent command. func ( *Command) ( ...*Group) { .commandgroups = append(.commandgroups, ...) } // RemoveCommand removes one or more commands from a parent command. func ( *Command) ( ...*Command) { := []*Command{} : for , := range .commands { for , := range { if == { .parent = nil continue } } = append(, ) } .commands = // recompute all lengths .commandsMaxUseLen = 0 .commandsMaxCommandPathLen = 0 .commandsMaxNameLen = 0 for , := range .commands { := len(.Use) if > .commandsMaxUseLen { .commandsMaxUseLen = } := len(.CommandPath()) if > .commandsMaxCommandPathLen { .commandsMaxCommandPathLen = } := len(.Name()) if > .commandsMaxNameLen { .commandsMaxNameLen = } } } // Print is a convenience method to Print to the defined output, fallback to Stderr if not set. func ( *Command) ( ...interface{}) { fmt.Fprint(.OutOrStderr(), ...) } // Println is a convenience method to Println to the defined output, fallback to Stderr if not set. func ( *Command) ( ...interface{}) { .Print(fmt.Sprintln(...)) } // Printf is a convenience method to Printf to the defined output, fallback to Stderr if not set. func ( *Command) ( string, ...interface{}) { .Print(fmt.Sprintf(, ...)) } // PrintErr is a convenience method to Print to the defined Err output, fallback to Stderr if not set. func ( *Command) ( ...interface{}) { fmt.Fprint(.ErrOrStderr(), ...) } // PrintErrln is a convenience method to Println to the defined Err output, fallback to Stderr if not set. func ( *Command) ( ...interface{}) { .PrintErr(fmt.Sprintln(...)) } // PrintErrf is a convenience method to Printf to the defined Err output, fallback to Stderr if not set. func ( *Command) ( string, ...interface{}) { .PrintErr(fmt.Sprintf(, ...)) } // CommandPath returns the full path to this command. func ( *Command) () string { if .HasParent() { return .Parent().() + " " + .Name() } return .displayName() } func ( *Command) () string { if , := .Annotations[CommandDisplayNameAnnotation]; { return } return .Name() } // UseLine puts out the full usage for a given command (including parents). func ( *Command) () string { var string := strings.Replace(.Use, .Name(), .displayName(), 1) if .HasParent() { = .parent.CommandPath() + " " + } else { = } if .DisableFlagsInUseLine { return } if .HasAvailableFlags() && !strings.Contains(, "[flags]") { += " [flags]" } return } // DebugFlags used to determine which flags have been assigned to which commands // and which persist. func ( *Command) () { .Println("DebugFlags called on", .Name()) var func(*Command) = func( *Command) { if .HasFlags() || .HasPersistentFlags() { .Println(.Name()) } if .HasFlags() { .flags.VisitAll(func( *flag.Flag) { if .HasPersistentFlags() && .persistentFlag(.Name) != nil { .Println(" -"+.Shorthand+",", "--"+.Name, "["+.DefValue+"]", "", .Value, " [LP]") } else { .Println(" -"+.Shorthand+",", "--"+.Name, "["+.DefValue+"]", "", .Value, " [L]") } }) } if .HasPersistentFlags() { .pflags.VisitAll(func( *flag.Flag) { if .HasFlags() { if .flags.Lookup(.Name) == nil { .Println(" -"+.Shorthand+",", "--"+.Name, "["+.DefValue+"]", "", .Value, " [P]") } } else { .Println(" -"+.Shorthand+",", "--"+.Name, "["+.DefValue+"]", "", .Value, " [P]") } }) } .Println(.flagErrorBuf) if .HasSubCommands() { for , := range .commands { () } } } () } // Name returns the command's name: the first word in the use line. func ( *Command) () string { := .Use := strings.Index(, " ") if >= 0 { = [:] } return } // HasAlias determines if a given string is an alias of the command. func ( *Command) ( string) bool { for , := range .Aliases { if commandNameMatches(, ) { return true } } return false } // CalledAs returns the command name or alias that was used to invoke // this command or an empty string if the command has not been called. func ( *Command) () string { if .commandCalledAs.called { return .commandCalledAs.name } return "" } // hasNameOrAliasPrefix returns true if the Name or any of aliases start // with prefix func ( *Command) ( string) bool { if strings.HasPrefix(.Name(), ) { .commandCalledAs.name = .Name() return true } for , := range .Aliases { if strings.HasPrefix(, ) { .commandCalledAs.name = return true } } return false } // NameAndAliases returns a list of the command name and all aliases func ( *Command) () string { return strings.Join(append([]string{.Name()}, .Aliases...), ", ") } // HasExample determines if the command has example. func ( *Command) () bool { return len(.Example) > 0 } // Runnable determines if the command is itself runnable. func ( *Command) () bool { return .Run != nil || .RunE != nil } // HasSubCommands determines if the command has children commands. func ( *Command) () bool { return len(.commands) > 0 } // IsAvailableCommand determines if a command is available as a non-help command // (this includes all non deprecated/hidden commands). func ( *Command) () bool { if len(.Deprecated) != 0 || .Hidden { return false } if .HasParent() && .Parent().helpCommand == { return false } if .Runnable() || .HasAvailableSubCommands() { return true } return false } // IsAdditionalHelpTopicCommand determines if a command is an additional // help topic command; additional help topic command is determined by the // fact that it is NOT runnable/hidden/deprecated, and has no sub commands that // are runnable/hidden/deprecated. // Concrete example: https://github.com/spf13/cobra/issues/393#issuecomment-282741924. func ( *Command) () bool { // if a command is runnable, deprecated, or hidden it is not a 'help' command if .Runnable() || len(.Deprecated) != 0 || .Hidden { return false } // if any non-help sub commands are found, the command is not a 'help' command for , := range .commands { if !.() { return false } } // the command either has no sub commands, or no non-help sub commands return true } // HasHelpSubCommands determines if a command has any available 'help' sub commands // that need to be shown in the usage/help default template under 'additional help // topics'. func ( *Command) () bool { // return true on the first found available 'help' sub command for , := range .commands { if .IsAdditionalHelpTopicCommand() { return true } } // the command either has no sub commands, or no available 'help' sub commands return false } // HasAvailableSubCommands determines if a command has available sub commands that // need to be shown in the usage/help default template under 'available commands'. func ( *Command) () bool { // return true on the first found available (non deprecated/help/hidden) // sub command for , := range .commands { if .IsAvailableCommand() { return true } } // the command either has no sub commands, or no available (non deprecated/help/hidden) // sub commands return false } // HasParent determines if the command is a child command. func ( *Command) () bool { return .parent != nil } // GlobalNormalizationFunc returns the global normalization function or nil if it doesn't exist. func ( *Command) () func( *flag.FlagSet, string) flag.NormalizedName { return .globNormFunc } // Flags returns the complete FlagSet that applies // to this command (local and persistent declared here and by all parents). func ( *Command) () *flag.FlagSet { if .flags == nil { .flags = flag.NewFlagSet(.displayName(), flag.ContinueOnError) if .flagErrorBuf == nil { .flagErrorBuf = new(bytes.Buffer) } .flags.SetOutput(.flagErrorBuf) } return .flags } // LocalNonPersistentFlags are flags specific to this command which will NOT persist to subcommands. // This function does not modify the flags of the current command, it's purpose is to return the current state. func ( *Command) () *flag.FlagSet { := .PersistentFlags() := flag.NewFlagSet(.displayName(), flag.ContinueOnError) .LocalFlags().VisitAll(func( *flag.Flag) { if .Lookup(.Name) == nil { .AddFlag() } }) return } // LocalFlags returns the local FlagSet specifically set in the current command. // This function does not modify the flags of the current command, it's purpose is to return the current state. func ( *Command) () *flag.FlagSet { .mergePersistentFlags() if .lflags == nil { .lflags = flag.NewFlagSet(.displayName(), flag.ContinueOnError) if .flagErrorBuf == nil { .flagErrorBuf = new(bytes.Buffer) } .lflags.SetOutput(.flagErrorBuf) } .lflags.SortFlags = .Flags().SortFlags if .globNormFunc != nil { .lflags.SetNormalizeFunc(.globNormFunc) } := func( *flag.Flag) { // Add the flag if it is not a parent PFlag, or it shadows a parent PFlag if .lflags.Lookup(.Name) == nil && != .parentsPflags.Lookup(.Name) { .lflags.AddFlag() } } .Flags().VisitAll() .PersistentFlags().VisitAll() return .lflags } // InheritedFlags returns all flags which were inherited from parent commands. // This function does not modify the flags of the current command, it's purpose is to return the current state. func ( *Command) () *flag.FlagSet { .mergePersistentFlags() if .iflags == nil { .iflags = flag.NewFlagSet(.displayName(), flag.ContinueOnError) if .flagErrorBuf == nil { .flagErrorBuf = new(bytes.Buffer) } .iflags.SetOutput(.flagErrorBuf) } := .LocalFlags() if .globNormFunc != nil { .iflags.SetNormalizeFunc(.globNormFunc) } .parentsPflags.VisitAll(func( *flag.Flag) { if .iflags.Lookup(.Name) == nil && .Lookup(.Name) == nil { .iflags.AddFlag() } }) return .iflags } // NonInheritedFlags returns all flags which were not inherited from parent commands. // This function does not modify the flags of the current command, it's purpose is to return the current state. func ( *Command) () *flag.FlagSet { return .LocalFlags() } // PersistentFlags returns the persistent FlagSet specifically set in the current command. func ( *Command) () *flag.FlagSet { if .pflags == nil { .pflags = flag.NewFlagSet(.displayName(), flag.ContinueOnError) if .flagErrorBuf == nil { .flagErrorBuf = new(bytes.Buffer) } .pflags.SetOutput(.flagErrorBuf) } return .pflags } // ResetFlags deletes all flags from command. func ( *Command) () { .flagErrorBuf = new(bytes.Buffer) .flagErrorBuf.Reset() .flags = flag.NewFlagSet(.displayName(), flag.ContinueOnError) .flags.SetOutput(.flagErrorBuf) .pflags = flag.NewFlagSet(.displayName(), flag.ContinueOnError) .pflags.SetOutput(.flagErrorBuf) .lflags = nil .iflags = nil .parentsPflags = nil } // HasFlags checks if the command contains any flags (local plus persistent from the entire structure). func ( *Command) () bool { return .Flags().HasFlags() } // HasPersistentFlags checks if the command contains persistent flags. func ( *Command) () bool { return .PersistentFlags().HasFlags() } // HasLocalFlags checks if the command has flags specifically declared locally. func ( *Command) () bool { return .LocalFlags().HasFlags() } // HasInheritedFlags checks if the command has flags inherited from its parent command. func ( *Command) () bool { return .InheritedFlags().HasFlags() } // HasAvailableFlags checks if the command contains any flags (local plus persistent from the entire // structure) which are not hidden or deprecated. func ( *Command) () bool { return .Flags().HasAvailableFlags() } // HasAvailablePersistentFlags checks if the command contains persistent flags which are not hidden or deprecated. func ( *Command) () bool { return .PersistentFlags().HasAvailableFlags() } // HasAvailableLocalFlags checks if the command has flags specifically declared locally which are not hidden // or deprecated. func ( *Command) () bool { return .LocalFlags().HasAvailableFlags() } // HasAvailableInheritedFlags checks if the command has flags inherited from its parent command which are // not hidden or deprecated. func ( *Command) () bool { return .InheritedFlags().HasAvailableFlags() } // Flag climbs up the command tree looking for matching flag. func ( *Command) ( string) ( *flag.Flag) { = .Flags().Lookup() if == nil { = .persistentFlag() } return } // Recursively find matching persistent flag. func ( *Command) ( string) ( *flag.Flag) { if .HasPersistentFlags() { = .PersistentFlags().Lookup() } if == nil { .updateParentsPflags() = .parentsPflags.Lookup() } return } // ParseFlags parses persistent flag tree and local flags. func ( *Command) ( []string) error { if .DisableFlagParsing { return nil } if .flagErrorBuf == nil { .flagErrorBuf = new(bytes.Buffer) } := .flagErrorBuf.Len() .mergePersistentFlags() // do it here after merging all flags and just before parse .Flags().ParseErrorsWhitelist = flag.ParseErrorsWhitelist(.FParseErrWhitelist) := .Flags().Parse() // Print warnings if they occurred (e.g. deprecated flag messages). if .flagErrorBuf.Len()- > 0 && == nil { .Print(.flagErrorBuf.String()) } return } // Parent returns a commands parent command. func ( *Command) () *Command { return .parent } // mergePersistentFlags merges c.PersistentFlags() to c.Flags() // and adds missing persistent flags of all parents. func ( *Command) () { .updateParentsPflags() .Flags().AddFlagSet(.PersistentFlags()) .Flags().AddFlagSet(.parentsPflags) } // updateParentsPflags updates c.parentsPflags by adding // new persistent flags of all parents. // If c.parentsPflags == nil, it makes new. func ( *Command) () { if .parentsPflags == nil { .parentsPflags = flag.NewFlagSet(.displayName(), flag.ContinueOnError) .parentsPflags.SetOutput(.flagErrorBuf) .parentsPflags.SortFlags = false } if .globNormFunc != nil { .parentsPflags.SetNormalizeFunc(.globNormFunc) } .Root().PersistentFlags().AddFlagSet(flag.CommandLine) .VisitParents(func( *Command) { .parentsPflags.AddFlagSet(.PersistentFlags()) }) } // commandNameMatches checks if two command names are equal // taking into account case sensitivity according to // EnableCaseInsensitive global configuration. func commandNameMatches( string, string) bool { if EnableCaseInsensitive { return strings.EqualFold(, ) } return == }