forked from mirror/cobra
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.
This commit is contained in:
parent
66816bcd03
commit
d0bb3e33e6
58
command.go
58
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")
|
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)
|
var innerfind func(*Command, []string) (*Command, []string)
|
||||||
|
|
||||||
innerfind = func(c *Command, innerArgs []string) (*Command, []string) {
|
innerfind = func(c *Command, innerArgs []string) (*Command, []string) {
|
||||||
if len(innerArgs) > 0 && c.HasSubCommands() {
|
argsWOflags := stripFlags(innerArgs, c)
|
||||||
argsWOflags := stripFlags(innerArgs, c)
|
if len(argsWOflags) == 0 {
|
||||||
if len(argsWOflags) > 0 {
|
return c, innerArgs
|
||||||
matches := make([]*Command, 0)
|
}
|
||||||
for _, cmd := range c.commands {
|
nextSubCmd := argsWOflags[0]
|
||||||
if cmd.Name() == argsWOflags[0] || cmd.HasAlias(argsWOflags[0]) { // exact name or alias match
|
matches := make([]*Command, 0)
|
||||||
return innerfind(cmd, argsMinusFirstX(innerArgs, argsWOflags[0]))
|
for _, cmd := range c.commands {
|
||||||
} else if EnablePrefixMatching {
|
if cmd.Name() == nextSubCmd || cmd.HasAlias(nextSubCmd) { // exact name or alias match
|
||||||
if strings.HasPrefix(cmd.Name(), argsWOflags[0]) { // prefix match
|
return innerfind(cmd, argsMinusFirstX(innerArgs, nextSubCmd))
|
||||||
matches = append(matches, cmd)
|
}
|
||||||
}
|
if EnablePrefixMatching {
|
||||||
for _, x := range cmd.Aliases {
|
if strings.HasPrefix(cmd.Name(), nextSubCmd) { // prefix match
|
||||||
if strings.HasPrefix(x, argsWOflags[0]) {
|
matches = append(matches, cmd)
|
||||||
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
|
return c, innerArgs
|
||||||
}
|
}
|
||||||
|
|
||||||
commandFound, a := innerfind(c, args)
|
commandFound, a := innerfind(c, args)
|
||||||
|
|
||||||
// If we matched on the root, but we asked for a subcommand, return an error
|
|
||||||
argsWOflags := stripFlags(a, commandFound)
|
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 {
|
if commandFound == c && len(argsWOflags) > 0 {
|
||||||
return nil, a, fmt.Errorf("unknown command %q", argsWOflags[0])
|
return nil, a, fmt.Errorf("unknown command %q", argsWOflags[0])
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue