From 382fd11f8d0aa47ade40d5a9d4c89e5c1fcce06f Mon Sep 17 00:00:00 2001 From: Adin Schmahmann Date: Thu, 14 Jan 2021 17:01:11 -0500 Subject: [PATCH] feat: StringsOption.Parse(string) now returns a slice containing the original string. Added DelimitedStringsOption which allows passing delimited options on the CLI, such as --option=opt1,opt2 when the delimiter is a comma, instead of requiring the longer form --option=op1 --option=opt2 --- cli/parse.go | 2 +- option.go | 40 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/cli/parse.go b/cli/parse.go index ae74d98..eebd6b4 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 68962bc..21b59b7 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 } -- GitLab