From d0bb3e33e6a2daf86a1c7809e6558656052555af Mon Sep 17 00:00:00 2001 From: Eric Paris Date: Tue, 9 Jun 2015 13:52:43 -0400 Subject: [PATCH] rework Find() to make it more obvious what is happening We had lots of quirky if statements like `commandFound.Name() == c.Name() && len(stripFlags(args, c)) > 0 && commandFound.Name() != args[0]` which embeed all sorts of artifacts which are hard to parse. So in general, just try to simplify and make stuff readable. --- command.go | 58 ++++++++++++++++++++++++++---------------------------- 1 file changed, 28 insertions(+), 30 deletions(-) diff --git a/command.go b/command.go index 141cfab1..4209c8d8 100644 --- a/command.go +++ b/command.go @@ -381,49 +381,47 @@ func (c *Command) Find(args []string) (*Command, []string, error) { return nil, nil, fmt.Errorf("Called find() on a nil Command") } - // If there are no arguments, return the root command. If the root has no - // subcommands, args reflects arguments that should actually be passed to - // the root command, so also return the root command. - if len(args) == 0 || !c.Root().HasSubCommands() { - return c.Root(), args, nil - } - var innerfind func(*Command, []string) (*Command, []string) innerfind = func(c *Command, innerArgs []string) (*Command, []string) { - if len(innerArgs) > 0 && c.HasSubCommands() { - argsWOflags := stripFlags(innerArgs, c) - if len(argsWOflags) > 0 { - matches := make([]*Command, 0) - for _, cmd := range c.commands { - if cmd.Name() == argsWOflags[0] || cmd.HasAlias(argsWOflags[0]) { // exact name or alias match - return innerfind(cmd, argsMinusFirstX(innerArgs, argsWOflags[0])) - } else if EnablePrefixMatching { - if strings.HasPrefix(cmd.Name(), argsWOflags[0]) { // prefix match - matches = append(matches, cmd) - } - for _, x := range cmd.Aliases { - if strings.HasPrefix(x, argsWOflags[0]) { - matches = append(matches, cmd) - } - } + argsWOflags := stripFlags(innerArgs, c) + if len(argsWOflags) == 0 { + return c, innerArgs + } + nextSubCmd := argsWOflags[0] + matches := make([]*Command, 0) + for _, cmd := range c.commands { + if cmd.Name() == nextSubCmd || cmd.HasAlias(nextSubCmd) { // exact name or alias match + return innerfind(cmd, argsMinusFirstX(innerArgs, nextSubCmd)) + } + if EnablePrefixMatching { + if strings.HasPrefix(cmd.Name(), nextSubCmd) { // prefix match + matches = append(matches, cmd) + } + for _, x := range cmd.Aliases { + if strings.HasPrefix(x, nextSubCmd) { + matches = append(matches, cmd) } } - - // only accept a single prefix match - multiple matches would be ambiguous - if len(matches) == 1 { - return innerfind(matches[0], argsMinusFirstX(innerArgs, argsWOflags[0])) - } } } + // only accept a single prefix match - multiple matches would be ambiguous + if len(matches) == 1 { + return innerfind(matches[0], argsMinusFirstX(innerArgs, argsWOflags[0])) + } + return c, innerArgs } commandFound, a := innerfind(c, args) - - // If we matched on the root, but we asked for a subcommand, return an error argsWOflags := stripFlags(a, commandFound) + + // no subcommand, always take args + if !commandFound.HasSubCommands() { + return commandFound, a, nil + } + // root command with subcommands, do subcommand checking if commandFound == c && len(argsWOflags) > 0 { return nil, a, fmt.Errorf("unknown command %q", argsWOflags[0]) }