commands: Changed Option to an interface
Matt Bell committed
Nov 19, 2014 at 00:24 UTC
bbf3a1f4d4d7813c2baa336aa22227f322a01623
4 files changed
+37
-30
commands/cli/helptext.go
+2
-2
@@ -239,7 +239,7 @@ func optionText(cmd ...*cmds.Command) []string {
239
lines = append(lines, "")
240
}
241
242
- names := sortByLength(opt.Names)
242
+ names := sortByLength(opt.Names())
243
if len(names) >= j+1 {
244
lines[i] += fmt.Sprintf(optionFlag, names[j])
245
}
@@ -268,7 +268,7 @@ func optionText(cmd ...*cmds.Command) []string {
268
269
// add option descriptions to output
270
for i, opt := range options {
271
- lines[i] += " - " + opt.Description
271
+ lines[i] += " - " + opt.Description()
272
}
273
274
return lines
commands/command.go
+2
-2
@@ -167,7 +167,7 @@ func (c *Command) Get(path []string) (*Command, error) {
167
168
// GetOptions gets the options in the given path of commands
169
func (c *Command) GetOptions(path []string) (map[string]Option, error) {
170
- options := make([]Option, len(c.Options))
170
+ options := make([]Option, 0, len(c.Options))
171
172
cmds, err := c.Resolve(path)
173
if err != nil {
@@ -181,7 +181,7 @@ func (c *Command) GetOptions(path []string) (map[string]Option, error) {
181
182
optionsMap := make(map[string]Option)
183
for _, opt := range options {
184
- for _, name := range opt.Names {
184
+ for _, name := range opt.Names() {
185
if _, found := optionsMap[name]; found {
186
return nil, fmt.Errorf("Option name '%s' used multiple times", name)
187
}
commands/option.go
+25
-11
@@ -17,14 +17,28 @@ const (
17
)
18
19
// Option is used to specify a field that will be provided by a consumer
20
-type Option struct {
21
- Names []string // a list of unique names to
22
- Type reflect.Kind // value must be this type
23
- Description string // a short string to describe this option
20
+type Option interface {
21
+ Names() []string // a list of unique names matched with user-provided flags
22
+ Type() reflect.Kind // value must be this type
23
+ Description() string // a short string that describes this option
24
+}
25
+
26
+type option struct {
27
+ names []string
28
+ kind reflect.Kind
29
+ description string
30
+}
31
+
32
+func (o *option) Names() []string {
33
+ return o.names
34
+}
35
+
36
+func (o *option) Type() reflect.Kind {
37
+ return o.kind
38
+}
39
25
- // MAYBE_TODO: add more features(?):
26
- //Default interface{} // the default value (ignored if `Required` is true)
27
- //Required bool // whether or not the option must be provided
40
+func (o *option) Description() string {
41
+ return o.description
42
}
43
44
// constructor helper functions
@@ -37,10 +51,10 @@ func NewOption(kind reflect.Kind, names ...string) Option {
51
desc := names[len(names)-1]
52
names = names[:len(names)-1]
53
40
- return Option{
41
- Names: names,
42
- Type: kind,
43
- Description: desc,
54
+ return &option{
55
+ names: names,
56
+ kind: kind,
57
+ description: desc,
58
}
59
}
60
commands/request.go
+8
-15
@@ -92,13 +92,6 @@ func (r *request) Path() []string {
92
93
// Option returns the value of the option for given name.
94
func (r *request) Option(name string) *OptionValue {
95
- val, found := r.options[name]
96
- if found {
97
- return &OptionValue{val, found}
98
- }
99
-
100
- // if a value isn't defined for that name, we will try to look it up by its aliases
101
-
95
// find the option with the specified name
96
option, found := r.optionDefs[name]
97
if !found {
@@ -106,8 +99,8 @@ func (r *request) Option(name string) *OptionValue {
99
}
100
101
// try all the possible names, break if we find a value
109
- for _, n := range option.Names {
110
- val, found = r.options[n]
102
+ for _, n := range option.Names() {
103
+ val, found := r.options[n]
104
if found {
105
return &OptionValue{val, found}
106
}
@@ -135,7 +128,7 @@ func (r *request) SetOption(name string, val interface{}) {
128
}
129
130
// try all the possible names, if we already have a value then set over it
138
- for _, n := range option.Names {
131
+ for _, n := range option.Names() {
132
_, found := r.options[n]
133
if found {
134
r.options[n] = val
@@ -222,9 +215,9 @@ func (r *request) ConvertOptions() error {
215
}
216
217
kind := reflect.TypeOf(v).Kind()
225
- if kind != opt.Type {
218
+ if kind != opt.Type() {
219
if kind == String {
227
- convert := converters[opt.Type]
220
+ convert := converters[opt.Type()]
221
str, ok := v.(string)
222
if !ok {
223
return u.ErrCast()
@@ -236,19 +229,19 @@ func (r *request) ConvertOptions() error {
229
value = "empty value"
230
}
231
return fmt.Errorf("Could not convert %s to type '%s' (for option '-%s')",
239
- value, opt.Type.String(), k)
232
+ value, opt.Type().String(), k)
233
}
234
r.options[k] = val
235
236
} else {
237
return fmt.Errorf("Option '%s' should be type '%s', but got type '%s'",
245
- k, opt.Type.String(), kind.String())
238
+ k, opt.Type().String(), kind.String())
239
}
240
} else {
241
r.options[k] = v
242
}
243
251
- for _, name := range opt.Names {
244
+ for _, name := range opt.Names() {
245
if _, ok := r.options[name]; name != k && ok {
246
return fmt.Errorf("Duplicate command options were provided ('%s' and '%s')",
247
k, name)