Cobra https://github.com/spf13/cobra uses https://github.com/spf13/pflag, which supports GNU style flags. Cobra has been developed for many years now and has a ton of additional features, like automatically generating the autocompletions and has tons of unit tests.
I'd just use cobra.
I've become a fan of https://github.com/jessevdk/go-flags (also enjoyed structopt which is similar for Rust). I much prefer defining the flags statically on a type which stores them after rather than building it all up programmatically.
Otherwise, I'm not really sure what this offers that alternatives don't, apart from the -a 1 2 3 -> [1,2,3] business which seems highly confusing and undesirable to me so I'd think of it as more of an anti-feature.
I use Kong https://github.com/alecthomas/kong
I does everything, including too complicated options.
The standard flag package in Go also supports GNU style flags.
Interesting. I used
in the past and was pretty happy with it. However sometimes it's good to try something New :-)
I'm glad that this package exists.
I know of UNIX parameters, with a single hyphen & a single letter, and GNU parameters, with a double parameter and a word. But a single hyphen and then a word: *mind broken*.
When I first saw that on Terraform, I was upset & conflicted.
OK, I know that Java also has mental parameter options like that ('-version', note the *single* hyphen followed by, gasp, a word!), but I just dismissed it as weird enterprise-ism.
Then I saw that this 'single hyphen + word' was an accepted convention for parameters, in the Go world & I was disappointed.
Glad that this package is fighting the good fight.
Aside from the other comments, an ick I have is that struct tags are being abused here. Instead of providing a grouping like json, yaml, mapstructure, gorm, etc - it just goes willy nilly with struct tags like it owns the whole space. I’d like to see it grouped like…
type Conf struct {
Thing string `argp:”name:thing;short:t;desc:A thing you can do”`
}
This would follow go struct tag standards.Maybe the README should mention whether reflection (the part that would disable dead-code elimnation) is used? That was a pain point for me when I had to investigate a binary bloat issue due to reflect.
I might be the only person in this camp, but I find the "standard" command line arguments style absolutely repulsive. I write tons of CL code, and I always use easy key=value notation (sometimes it's flag=true, which I consider to be a minor sacrifice of conciseness in favor of consistency and readability).
There's already go implementation for docopt[0]
[0]: https://docopt.org/
Does it throw an exception when it fails to parse?
Assigning values like -v as an int and allowing -vvvv to be easily parsed is a great compatibility feature for existing utils.
I really favor posix style, which is why I use pflags package for my cli Tools.
I have yet to find a cli args solution I enjoy using more than docopt.org
i hope the below is agreed on, mycmd -h, and mycmd --help, are the same, - for single letter,-- for longer format
same to mycmd -v, mycmd --version
Sanity!
If you need long options because you are running out of letters, time for a rewrite :)
> * multiple options can be combined: -abc is the same as -a -b -c
> * option values can be separated by a space, equal sign, or nothing: -a1 -a=1 -a 1 are all equal
> * options can have multiple values: -a 1 2 3 means that a is an array/slice/struct of three numbers of value [1,2,3]
while convenient, one of the reasons I dislike gnu style flags is just how inconsistent they can be and annoyingly hard to parse by humans
In general, command-line argument parsers should just follow the GNU style. No more, no less. Deviations confuse users as it is not immediately obvious to them what rules a parser is imposing.
> options can have multiple values: -a 1 2 3 means that a is an array/slice/struct of three numbers of value [1,2,3]
Allowing multiple values is inconsistent because you can't tell in "./cmd -a 1 2 3" whether 2 and 3 are positional arguments or arguments for -a. This is not a GNU style. The GNU way is "./cmd -a 1 -a 2 -a 3" (or "./cmd -a 1,2,3"). This package supports that, which is good.
> option values can be separated by a space, equal sign, or nothing: -a1 -a=1 -a 1 are all equal
"--a=1" is a GNU style but "-a=1" is not. This is a minor issue, though.
Also, does this package support "--"? Everything following "--" should be treated as positional arguments.