diff --git a/cli/parse.go b/cli/parse.go index ae74d98741b495e1019f79ca4a669c342ba6439a..eebd6b43af7e3609e0c78f57d85b1037cb05bbf5 100644 --- a/cli/parse.go +++ b/cli/parse.go @@ -100,7 +100,7 @@ func setOpts(kv kv, kvType reflect.Kind, opts cmds.OptMap) error { if kvType == cmds.Strings { res, _ := opts[kv.Key].([]string) - opts[kv.Key] = append(res, kv.Value.(string)) + opts[kv.Key] = append(res, kv.Value.([]string)...) } else if _, exists := opts[kv.Key]; !exists { opts[kv.Key] = kv.Value } else { diff --git a/option.go b/option.go index 68962bc40b20326872b061ef9c958f7da5fa359c..21b59b75ccf350d919b6b26144f6ac5325aa8a7b 100644 --- a/option.go +++ b/option.go @@ -184,6 +184,44 @@ func FloatOption(names ...string) Option { func StringOption(names ...string) Option { return NewOption(String, names...) } + +// StringsOption is a command option that can handle a slice of strings func StringsOption(names ...string) Option { - return NewOption(Strings, names...) + return DelimitedStringsOption("", names...) +} + +// DelimitedStringsOption like StringsOption is a command option that can handle a slice of strings. +// However, DelimitedStringsOption will automatically break up the associated CLI inputs based on the delimiter. +// For example, instead of passing `command --option=val1 --option=val2` you can pass `command --option=val1,val2` or +// even `command --option=val1,val2 --option=val3,val4`. +// +// A delimiter of "" means that no delimiter is used +func DelimitedStringsOption(delimiter string, names ...string) Option { + return &stringsOption{ + Option: NewOption(Strings, names...), + delimiter: delimiter, + } +} + +type stringsOption struct { + Option + delimiter string +} + +func (s *stringsOption) WithDefault(v interface{}) Option { + if v == nil { + return s.Option.WithDefault(v) + } + + defVal := v.([]string) + s.Option = s.Option.WithDefault(defVal) + return s +} + +func (s *stringsOption) Parse(v string) (interface{}, error) { + if s.delimiter == "" { + return []string{v}, nil + } + + return strings.Split(v, s.delimiter), nil }