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:
		
							
								
								
									
										34
									
								
								command.go
									
									
									
									
									
								
							
							
						
						
									
										34
									
								
								command.go
									
									
									
									
									
								
							@ -381,29 +381,25 @@ 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
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							nextSubCmd := argsWOflags[0]
 | 
				
			||||||
		matches := make([]*Command, 0)
 | 
							matches := make([]*Command, 0)
 | 
				
			||||||
		for _, cmd := range c.commands {
 | 
							for _, cmd := range c.commands {
 | 
				
			||||||
					if cmd.Name() == argsWOflags[0] || cmd.HasAlias(argsWOflags[0]) { // exact name or alias match
 | 
								if cmd.Name() == nextSubCmd || cmd.HasAlias(nextSubCmd) { // exact name or alias match
 | 
				
			||||||
						return innerfind(cmd, argsMinusFirstX(innerArgs, argsWOflags[0]))
 | 
									return innerfind(cmd, argsMinusFirstX(innerArgs, nextSubCmd))
 | 
				
			||||||
					} else if EnablePrefixMatching {
 | 
								}
 | 
				
			||||||
						if strings.HasPrefix(cmd.Name(), argsWOflags[0]) { // prefix match
 | 
								if EnablePrefixMatching {
 | 
				
			||||||
 | 
									if strings.HasPrefix(cmd.Name(), nextSubCmd) { // prefix match
 | 
				
			||||||
					matches = append(matches, cmd)
 | 
										matches = append(matches, cmd)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				for _, x := range cmd.Aliases {
 | 
									for _, x := range cmd.Aliases {
 | 
				
			||||||
							if strings.HasPrefix(x, argsWOflags[0]) {
 | 
										if strings.HasPrefix(x, nextSubCmd) {
 | 
				
			||||||
						matches = append(matches, cmd)
 | 
											matches = append(matches, cmd)
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
@ -414,16 +410,18 @@ func (c *Command) Find(args []string) (*Command, []string, error) {
 | 
				
			|||||||
		if len(matches) == 1 {
 | 
							if len(matches) == 1 {
 | 
				
			||||||
			return innerfind(matches[0], argsMinusFirstX(innerArgs, argsWOflags[0]))
 | 
								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])
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user