commands: Removed Command#Register and exported Subcommands so subcommands can be defined statically
Matt Bell committed
Oct 21, 2014 at 18:05 UTC
ca44d0da2c4602a804f7ca67fa7a4e8e71edab5e
1 file changed
+6
-69
commands/command.go
+6
-69
@@ -15,37 +15,17 @@ var log = u.Logger("command")
15
type Function func(Request, Response)
16
17
// Command is a runnable command, with input arguments and options (flags).
18
-// It can also have subcommands, to group units of work into sets.
18
+// It can also have Subcommands, to group units of work into sets.
19
type Command struct {
20
- Help string
21
- Options []Option
22
- Run Function
23
-
24
- subcommands map[string]*Command
20
+ Help string
21
+ Options []Option
22
+ Run Function
23
+ Subcommands map[string]*Command
24
}
25
26
// ErrNotCallable signals a command that cannot be called.
27
var ErrNotCallable = errors.New("This command can't be called directly. Try one of its subcommands.")
28
30
-// Register adds a subcommand
31
-func (c *Command) Register(id string, sub *Command) error {
32
- if c.subcommands == nil {
33
- c.subcommands = make(map[string]*Command)
34
- }
35
-
36
- // check for duplicate option names (only checks downwards)
37
- if err := checkOptionClashes(globalCommand, c, sub); err != nil {
38
- return err
39
- }
40
-
41
- if _, found := c.subcommands[id]; found {
42
- return fmt.Errorf("There is already a subcommand registered with id '%s'", id)
43
- }
44
-
45
- c.subcommands[id] = sub
46
- return nil
47
-}
48
-
29
// Call invokes the command for the given Request
30
func (c *Command) Call(req Request) Response {
31
res := NewResponse(req)
@@ -138,48 +118,5 @@ func (c *Command) GetOptions(path []string) (map[string]Option, error) {
118
119
// Subcommand returns the subcommand with the given id
120
func (c *Command) Subcommand(id string) *Command {
141
- return c.subcommands[id]
142
-}
143
-
144
-// AddOptionNames returns a map of all command options names, and the command
145
-// they belong to. Will error if names clash in the command hierarchy.
146
-func AddOptionNames(c *Command, names map[string]*Command) error {
147
-
148
- for _, opt := range c.Options {
149
- for _, name := range opt.Names {
150
- if c2, found := names[name]; found {
151
-
152
- // option can be reused in same command, but more often than not
153
- // the clash will be across commands so error out with that, as
154
- // commands tell us where the problem is
155
- errstr := "Option name ('%s') used multiple times (%v, %v)"
156
- return fmt.Errorf(errstr, c2, c)
157
- }
158
-
159
- // mark the name as in use
160
- names[name] = c
161
- }
162
- }
163
-
164
- // for every subcommand, recurse
165
- for _, c2 := range c.subcommands {
166
- if err := AddOptionNames(c2, names); err != nil {
167
- return err
168
- }
169
- }
170
-
171
- return nil
172
-}
173
-
174
-// checkOptionClashes checks all command option names for clashes
175
-func checkOptionClashes(cmds ...*Command) error {
176
- names := map[string]*Command{}
177
-
178
- for _, c := range cmds {
179
- if err := AddOptionNames(c, names); err != nil {
180
- return err
181
- }
182
- }
183
-
184
- return nil
121
+ return c.Subcommands[id]
122
}