commands: Check for option name collisions
Matt Bell committed
Oct 9, 2014 at 13:39 UTC
5b18844c063b9dc344046a98f30e5f70d05aee0c
1 file changed
+27
-1
commands/command.go
+27
-1
@@ -19,7 +19,13 @@ func (c *Command) Register(id string, sub *Command) error {
19
c.subcommands = make(map[string]*Command)
20
}
21
22
- // TODO: check for duplicate option names
22
+ // check for duplicate option names (only checks downwards)
23
+ names := make(map[string]bool)
24
+ c.checkOptions(names)
25
+ err := sub.checkOptions(names)
26
+ if err != nil {
27
+ return err
28
+ }
29
30
if _, ok := c.subcommands[id]; ok {
31
return fmt.Errorf("There is already a subcommand registered with id '%s'", id)
@@ -83,3 +89,23 @@ func (c *Command) Call(path []string, req *Request) (interface{}, error) {
89
func (c *Command) Sub(id string) *Command {
90
return c.subcommands[id]
91
}
92
+
93
+func (c *Command) checkOptions(names map[string]bool) error {
94
+ for _, opt := range c.Options {
95
+ for _, name := range opt.Names {
96
+ if _, ok := names[name]; ok {
97
+ return fmt.Errorf("Multiple options are using the same name ('%s')", name)
98
+ }
99
+ names[name] = true
100
+ }
101
+ }
102
+
103
+ for _, cmd := range c.subcommands {
104
+ err := cmd.checkOptions(names)
105
+ if err != nil {
106
+ return err
107
+ }
108
+ }
109
+
110
+ return nil
111
+}