1package flags
2
3// Command represents an application command. Commands can be added to the
4// parser (which itself is a command) and are selected/executed when its name
5// is specified on the command line. The Command type embeds a Group and
6// therefore also carries a set of command specific options.
7type Command struct {
8	// Embedded, see Group for more information
9	*Group
10
11	// The name by which the command can be invoked
12	Name string
13
14	// The active sub command (set by parsing) or nil
15	Active *Command
16
17	// Whether subcommands are optional
18	SubcommandsOptional bool
19
20	// Aliases for the command
21	Aliases []string
22
23	// Whether positional arguments are required
24	ArgsRequired bool
25
26	commands            []*Command
27	hasBuiltinHelpGroup bool
28	args                []*Arg
29}
30
31// Commander is an interface which can be implemented by any command added in
32// the options. When implemented, the Execute method will be called for the last
33// specified (sub)command providing the remaining command line arguments.
34type Commander interface {
35	// Execute will be called for the last active (sub)command. The
36	// args argument contains the remaining command line arguments. The
37	// error that Execute returns will be eventually passed out of the
38	// Parse method of the Parser.
39	Execute(args []string) error
40}
41
42// Usage is an interface which can be implemented to show a custom usage string
43// in the help message shown for a command.
44type Usage interface {
45	// Usage is called for commands to allow customized printing of command
46	// usage in the generated help message.
47	Usage() string
48}
49
50// AddCommand adds a new command to the parser with the given name and data. The
51// data needs to be a pointer to a struct from which the fields indicate which
52// options are in the command. The provided data can implement the Command and
53// Usage interfaces.
54func (c *Command) AddCommand(command string, shortDescription string, longDescription string, data interface{}) (*Command, error) {
55	cmd := newCommand(command, shortDescription, longDescription, data)
56
57	cmd.parent = c
58
59	if err := cmd.scan(); err != nil {
60		return nil, err
61	}
62
63	c.commands = append(c.commands, cmd)
64	return cmd, nil
65}
66
67// AddGroup adds a new group to the command with the given name and data. The
68// data needs to be a pointer to a struct from which the fields indicate which
69// options are in the group.
70func (c *Command) AddGroup(shortDescription string, longDescription string, data interface{}) (*Group, error) {
71	group := newGroup(shortDescription, longDescription, data)
72
73	group.parent = c
74
75	if err := group.scanType(c.scanSubcommandHandler(group)); err != nil {
76		return nil, err
77	}
78
79	c.groups = append(c.groups, group)
80	return group, nil
81}
82
83// Commands returns a list of subcommands of this command.
84func (c *Command) Commands() []*Command {
85	return c.commands
86}
87
88// Find locates the subcommand with the given name and returns it. If no such
89// command can be found Find will return nil.
90func (c *Command) Find(name string) *Command {
91	for _, cc := range c.commands {
92		if cc.match(name) {
93			return cc
94		}
95	}
96
97	return nil
98}
99
100// Args returns a list of positional arguments associated with this command.
101func (c *Command) Args() []*Arg {
102	ret := make([]*Arg, len(c.args))
103	copy(ret, c.args)
104
105	return ret
106}
107