From fddac5a640c26d9dd1b61dbd440854cdc05e6af7 Mon Sep 17 00:00:00 2001 From: deads2k Date: Thu, 26 Mar 2015 08:54:00 -0400 Subject: [PATCH] prevent incorrect flag message on bad subcommand parse --- cobra_test.go | 27 +++++++++++++++++++++++++++ command.go | 20 +++++++++++++------- 2 files changed, 40 insertions(+), 7 deletions(-) diff --git a/cobra_test.go b/cobra_test.go index 120bc5c7..30236bc3 100644 --- a/cobra_test.go +++ b/cobra_test.go @@ -417,6 +417,33 @@ func TestTrailingCommandFlags(t *testing.T) { } } +func TestInvalidSubCommandFlags(t *testing.T) { + sub := &Command{ + Use: "sub", + Short: "Invalid sub command test sub", + Run: func(cmd *Command, args []string) { + }, + } + sub.Flags().String("images", "", "images flag") + + root := &Command{ + Use: "root", + Short: "Invalid sub command test root", + Run: func(cmd *Command, args []string) { + }, + } + root.AddCommand(sub) + + result := simpleTester(root, "sub --images=foo --master=bar") + + checkResultContains(t, result, "unknown flag: --master") + + if strings.Contains(result.Output, "unknown flag: --images") { + t.Errorf("invalid --master flag shouldn't fail on images, Got: \n %s", result.Output) + } + +} + func TestPersistentFlags(t *testing.T) { fullSetupTest("echo -s something -p more here") diff --git a/command.go b/command.go index a7d90886..2539ffbb 100644 --- a/command.go +++ b/command.go @@ -399,13 +399,13 @@ func (c *Command) Root() *Command { } // execute the command determined by args and the command tree -func (c *Command) findAndExecute(args []string) (err error) { +func (c *Command) findAndExecute(args []string) (findErr error, err error) { cmd, a, e := c.Find(args) if e != nil { - return e + return e, nil } - return cmd.execute(a) + return nil, cmd.execute(a) } func (c *Command) execute(a []string) (err error) { @@ -486,19 +486,25 @@ func (c *Command) Execute() (err error) { args = c.args } + var findErr error + var rootCommandError error + if len(args) == 0 { // Only the executable is called and the root is runnable, run it if c.Runnable() { - err = c.execute([]string(nil)) + rootCommandError = c.execute([]string(nil)) + err = rootCommandError + } else { c.Help() } } else { - err = c.findAndExecute(args) + findErr, err = c.findAndExecute(args) } - // Now handle the case where the root is runnable and only flags are provided - if err != nil && c.Runnable() { + // if there was an error caused by running the root command or an inability to locate the requested command + // try to reparse the flags and run using the root command. + if (findErr != nil || rootCommandError != nil) && c.Runnable() { // This is pretty much a custom version of the *Command.execute method // with a few differences because it's the final command (no fall back) e := c.ParseFlags(args)