From bd0f8a846e1229add83e293f6f93b70f885c8a35 Mon Sep 17 00:00:00 2001 From: Eric Paris Date: Sat, 28 Mar 2015 23:56:22 -0400 Subject: [PATCH] Stop special casing runnable root commands The special case code to handle a runnable root command had some problems. It was noticed that if you created a runnable root and a subcommand. And the subcommand was then executed with both a valid and invalid flag, the error message was about the valid flag being invalid. For example ./command subcommand --goodflag=10 --badflag=10 Would fail and tell you that --goodflag was an invalid flag. Instead if we just do away with the special Command.execute() for the root command the parser for subcommand is what prints the error and it gets it right... --- command.go | 55 ++++++------------------------------------------------ 1 file changed, 6 insertions(+), 49 deletions(-) diff --git a/command.go b/command.go index 5e882d03..7e52d34f 100644 --- a/command.go +++ b/command.go @@ -305,6 +305,8 @@ func stripFlags(args []string, c *Command) []string { 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 @@ -375,9 +377,8 @@ func (c *Command) Find(arrs []string) (*Command, []string, error) { commandFound, a := innerfind(c, arrs) - // if commander returned and the first argument (if it exists) doesn't - // match the command name, return nil & error - if commandFound.Name() == c.Name() && len(arrs[0]) > 0 && commandFound.Name() != arrs[0] { + // If we matched on the root, but we asked for a subcommand, return an error + if commandFound.Name() == c.Name() && len(stripFlags(arrs, c)) > 0 && commandFound.Name() != arrs[0] { return nil, a, fmt.Errorf("unknown command %q", a[0]) } @@ -398,16 +399,6 @@ func (c *Command) Root() *Command { return findRoot(c) } -// execute the command determined by args and the command tree -func (c *Command) findAndExecute(args []string) (err error) { - - cmd, a, e := c.Find(args) - if e != nil { - return e - } - return cmd.execute(a) -} - func (c *Command) execute(a []string) (err error) { if c == nil { return fmt.Errorf("Called Execute() on a nil Command") @@ -494,45 +485,11 @@ func (c *Command) Execute() (err error) { c.Help() } } else { - err = c.findAndExecute(args) - } - - // Now handle the case where the root is runnable and only flags are provided - if err != 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) + cmd, flags, e := c.Find(args) if e != nil { - // Flags parsing had an error. - // If an error happens here, we have to report it to the user - c.Println(e.Error()) - // If an error happens search also for subcommand info about that - if c.cmdErrorBuf != nil && c.cmdErrorBuf.Len() > 0 { - c.Println(c.cmdErrorBuf.String()) - } else { - c.Usage() - } err = e - return } else { - // If help is called, regardless of other flags, we print that - if c.helpFlagVal { - c.Help() - return nil - } - - argWoFlags := c.Flags().Args() - if len(argWoFlags) > 0 { - // If there are arguments (not flags) one of the earlier - // cases should have caught it.. It means invalid usage - // print the usage - c.Usage() - } else { - // Only flags left... Call root.Run - c.preRun() - c.Run(c, argWoFlags) - err = nil - } + err = cmd.execute(flags) } }