diff --git a/cobra.go b/cobra.go index e0b0947..67c5799 100644 --- a/cobra.go +++ b/cobra.go @@ -47,6 +47,7 @@ const ( defaultCommandSorting = true defaultCaseInsensitive = false defaultTraverseRunHooks = false + defaultErrorOnUnknownSubcommand = false ) // EnablePrefixMatching allows setting automatic prefix matching. Automatic prefix matching can be a dangerous thing @@ -65,6 +66,17 @@ var EnableCaseInsensitive = defaultCaseInsensitive // By default this is disabled, which means only the first run hook to be found is executed. var EnableTraverseRunHooks = defaultTraverseRunHooks +// EnableErrorOnUnknownSubcommand controls the behavior of subcommand handling. +// When the flag is set true the behavior of Command.Execute() will change: +// If a sub-subcommand is not found ErrUnknownSubcommand will be returned on calling +// Command.Exec() instead of the old behavior where a nil error was sent. +// If the flag is false (default) the old behavior is performed. +// For this behavior the child subcommand must be nil. +// Example: in root/service/run - there would be an existing subcommand `run` +// in root/service/unknown - there would be an unknown subcommand `unknown` therefore returning an error +// `service` must have a nil Command.Run() function for this. +var EnableErrorOnUnknownSubcommand = defaultErrorOnUnknownSubcommand + // MousetrapHelpText enables an information splash screen on Windows // if the CLI is started from explorer.exe. // To disable the mousetrap, just set this variable to blank string (""). diff --git a/command.go b/command.go index f583275..af61b49 100644 --- a/command.go +++ b/command.go @@ -258,17 +258,6 @@ type Command struct { // SuggestionsMinimumDistance defines minimum levenshtein distance to display suggestions. // Must be > 0. SuggestionsMinimumDistance int - - // ErrorOnUnknownSubcommand controls the behavior of subcommand handling. - // When the flag is set true the behavior of Command.Execute() will change: - // If a sub-subcommand is not found ErrUnknownSubcommand will be returned on calling - // Command.Exec() instead of the old behavior where a nil error was sent. - // If the flag is false (default) the old behavior is performed. - // For this behavior the child subcommand must be nil. - // Example: in root/service/run - there would be an existing subcommand `run` - // in root/service/unknown - there would be an unknown subcommand `unknown` therefore returning an error - // `service` must have a nil Command.Run() function for this. - ErrorOnUnknownSubcommand bool } // Context returns underlying command context. If command was executed @@ -939,7 +928,7 @@ func (c *Command) execute(a []string) (err error) { } if !c.Runnable() { - if c.ErrorOnUnknownSubcommand { + if EnableErrorOnUnknownSubcommand { return ErrUnknownSubcommand } else { return flag.ErrHelp diff --git a/command_test.go b/command_test.go index 78f86ed..b901b56 100644 --- a/command_test.go +++ b/command_test.go @@ -179,7 +179,9 @@ func TestSubcommandExecuteMissingSubcommand(t *testing.T) { rootCmd := &Command{Use: "root", Run: emptyRun} const childName = "child" const grandchildName = "grandchild" - childCmd := &Command{Use: childName, Run: nil, ErrorOnUnknownSubcommand: false} + EnableErrorOnUnknownSubcommand = false + defer func() { EnableErrorOnUnknownSubcommand = defaultErrorOnUnknownSubcommand }() + childCmd := &Command{Use: childName, Run: nil} child2Cmd := &Command{Use: grandchildName, Run: emptyRun} rootCmd.AddCommand(childCmd) childCmd.AddCommand(child2Cmd) @@ -225,7 +227,9 @@ func TestSubcommandExecuteMissingSubcommandWithErrorOnUnknownSubcommand(t *testi rootCmd := &Command{Use: "root", Run: emptyRun} const childName = "child" const grandchildName = "grandchild" - childCmd := &Command{Use: childName, Run: nil, ErrorOnUnknownSubcommand: true} + EnableErrorOnUnknownSubcommand = true + defer func() { EnableErrorOnUnknownSubcommand = defaultErrorOnUnknownSubcommand }() + childCmd := &Command{Use: childName, Run: nil} child2Cmd := &Command{Use: grandchildName, Run: emptyRun} rootCmd.AddCommand(childCmd) childCmd.AddCommand(child2Cmd)