Borrowing from this SO example using the built-in flag library, it's possible to do something like this:
package main
import "flag"
type arrayFlags []string
func (i *arrayFlags) String() string {
return "my string representation"
}
func (i *arrayFlags) Set(value string) error {
*i = append(*i, value)
return nil
}
var myFlags arrayFlags
func main() {
flag.Var(&myFlags, "list1", "Some description for this param.")
flag.Parse()
}
Such that it is possible to do this:
go run your_file.go --list1 value1 --list1 value2
And get an slice of strings in the list1 flag. I've checked issues and documentation and it seems that this is not possible via cobra. Feel free to correct me if I'm wrong. If not, I'd like propose that this feature be considered.
Ps: I've tried repeated flags and the value of the last flag is picked up. Previous ones are somewhat discarded.
Ps 2: Obviously, you can use a comma-delimited list and split on the comma. Just figured I'd throw the idea out there. This is not a blocker, so don't feel obliged in any way.
you can use pflag.StringSlice* or pflag.StringArray* functions to get what you show above "out of the box". StringSlice accepts a list of CSVs. StringArray accepts 1 value per invocation. aka StringArray looks similar to your example. You will find other *Slice flags provided by pflag.
@eparis Thanks for pointing me in the right direction. I'd been working with IntVar* and StringVar* for so long (as that's what's in the README documentation) that it wasn't immediately obvious that there are more types!
Took me a while to figure our what you were talking about 馃槄 but eventually got to the pflag godoc reference and then it all made sense! 馃帀
For anyone who finds themselves here, wondering what the difference is ... using --ss="one" --ss="two,three" as an example:
StringSlice* - will result in []string{"one", "two", "three"}StringArray* - will result in []string{"one", "two,three"}Learn more at:
Hi,
can somebody provide some full example (in this case with StringSliceor StringArray) how to use cobra and pflag together?
BR,
Victor
func NewCommand() *cobra.Command {
var slice []string
var arr []string
c := &cobra.Command{
Use: "cmd",
Run: func(cmd *cobra.Command, args []string) {
for _, v := range slice {
fmt.Println(v)
}
for _, v := range arr {
fmt.Println(v)
}
},
}
c.Flags().StringSliceVarP(&slice, "slice", "s", []string{}, "")
c.Flags().StringArrayVarP(&arr, "arr", "a", []string{}, "")
return c
}
func main() {
NewCommand().Execute()
}
$ cmd --slice a --slice b --slice c,d,e
a
b
c
d
e
$ cmd --arr a --arr b --arr c,d,e
a
b
c,d,e
@tylrd, thank you very much!
There are use cases where you would want to repeat a flag to make a cleaner interface. For example, I'm building out a CLI that searches a REST API and will do some filtering. I want to be able to specify filters as individual flags.
my-cmd search --filter 'someType == value' --filter 'someValue != value'
You could still do these as a slice but that's almost certainly going to be harder to read/write from a user's perspective versus individual flags.
@durandj, did you see @tylrd's comment above?
Most helpful comment
For anyone who finds themselves here, wondering what the difference is ... using
--ss="one" --ss="two,three"as an example:StringSlice*- will result in[]string{"one", "two", "three"}StringArray*- will result in[]string{"one", "two,three"}Learn more at: