subcommand.go raw

   1  package arg
   2  
   3  import "fmt"
   4  
   5  // Subcommand returns the user struct for the subcommand selected by
   6  // the command line arguments most recently processed by the parser.
   7  // The return value is always a pointer to a struct. If no subcommand
   8  // was specified then it returns the top-level arguments struct. If
   9  // no command line arguments have been processed by this parser then it
  10  // returns nil.
  11  func (p *Parser) Subcommand() interface{} {
  12  	if len(p.subcommand) == 0 {
  13  		return nil
  14  	}
  15  	cmd, err := p.lookupCommand(p.subcommand...)
  16  	if err != nil {
  17  		return nil
  18  	}
  19  	return p.val(cmd.dest).Interface()
  20  }
  21  
  22  // SubcommandNames returns the sequence of subcommands specified by the
  23  // user. If no subcommands were given then it returns an empty slice.
  24  func (p *Parser) SubcommandNames() []string {
  25  	return p.subcommand
  26  }
  27  
  28  // lookupCommand finds a subcommand based on a sequence of subcommand names. The
  29  // first string should be a top-level subcommand, the next should be a child
  30  // subcommand of that subcommand, and so on. If no strings are given then the
  31  // root command is returned. If no such subcommand exists then an error is
  32  // returned.
  33  func (p *Parser) lookupCommand(path ...string) (*command, error) {
  34  	cmd := p.cmd
  35  	for _, name := range path {
  36  		found := findSubcommand(cmd.subcommands, name)
  37  		if found == nil {
  38  			return nil, fmt.Errorf("%q is not a subcommand of %s", name, cmd.name)
  39  		}
  40  		cmd = found
  41  	}
  42  	return cmd, nil
  43  }
  44