jawher / mow.cli

A versatile library for building CLI applications in Go
MIT License
871 stars 55 forks source link

All flags look like booleans in -h output #82

Open masiulaniec opened 5 years ago

masiulaniec commented 5 years ago
$ ./foocli -h

Usage: foocli [-n] [-f config_file]

Options:
  -n                  No-op mode.
  -f                  Path to the config file.
$

In this example, -n is a boolean but -f is not (it takes a string). It would be clearer if -f was rendered as -f string. One could also borrow the back quote idea from the flag package, see https://godoc.org/flag#PrintDefaults.

wkhere commented 4 years ago

Alternative to back quotes would be also to add Metavar to the *Opt structs, acting similar as in Python's argparse.

Yet another alternative would be reusing names from Spec in this -h output.

That would be actually super helpful, as mow.cli is already more advanced than most of cli parsers, this one area seems to ask for improvement.

jawher commented 4 years ago

@wkhere Thank you for your suggestions !

Could you clarify a bit the following points ?

wkhere commented 4 years ago

@jawher thank you for a swift reply!

Metavar

Metavar is a concrete name representing flag value (or arg value). In pythonic argparse it is displayed in usage headline (well, we seem to have Spec for that) and in usage lines describing each option. Following an example from the original doc:

>>> parser.add_argument('--foo', metavar='YYY')
>>> parser.add_argument('bar', metavar='XXX')
>>> parser.parse_args('X --foo Y'.split())
Namespace(bar='X', foo='Y')
>>> parser.print_help()
usage:  [-h] [--foo YYY] XXX

positional arguments:
 XXX

optional arguments:
 -h, --help  show this help message and exit
 --foo YYY

Hope this example explains. PS. I specifically referred to Python's argparse a it became de facto standard in Python world, included in Py3 and backported to Py2, and lot of people coming from that background know it.

Here, I think, we could define Metavar in Opt struct, defaulting to Opt type (so it would give bool in your example), and print it in usage text.

In Go world this has been a bit different, flag has the mechanism that if you use back quotes in option's description then it is also used like metavar above - see the doc. Several other projects incl. pflag/cobra copied that behaviour.

Spec

By reusing names from Spec I meant, if an option requires value and we're writing the Spec, then we must refer this value somehow, ie. -x=<foo>. Then we could print this also in options details instead of just -x + description.

I am sorry for somewhat chaotic style of writing, in a hurry a bit, hope this is little clearer.

[EDIT: changed formatting a bit]