commandlineparser / commandlineparser/commandline

Design discussion: how to handle --help option

Abierto
#600 5 comentarios 3 reacciones 0 asignados Ver en GitHub
Lenguaje dominante
C#
Estrellas
4.8k
Forks
478
Métricas de merge de PR
Sin PR fusionados en 30 d

Descripción

The design principle behind CommandLineParser is to [mimic the behavior of the standard GNU `getopt` library](https://github.com/commandlineparser/commandline/issues/498#issuecomment-521757260), but the handling of the standard `--help` option is failing to mimic `getopt` correctly.

## How it currently works

Currently, the `--help` option is really only recognized if it's the *first* option passed, e.g.:

* `progname --help` causes the parser to return a HelpRequestedError, which if AutoHelp=true (the default) will print the help text.
* `progname help` causes the parser to return a HelpVerbRequestedError, which if AutoHelp=true will print the help text.
* `progname foo --help` is handled differently depending on whether `foo` is a verb:
* If `foo` is a verb, then the help for that verb is constructed and returned.
* If `foo` is NOT a verb, then `progname foo --help` causes the parser to return an UnknownOptionError("help"), which if AutoHelp=true will print the help text, and NOT print "ERROR(S): Option 'help' is unknown." This is because [UnknownOptionError("help") is explicitly filtered out](https://github.com/commandlineparser/commandline/blob/182e72fa363485f10b2cdbf22b8c1ca23d03eae5/src/CommandLine/ErrorExtensions.cs#L19) of the "meaningful errors" list, and only "meaningful errors" are displayed to the user.
* `progname foo bar --help`, when `foo` is a verb, actually does the same as `progname foo --help` when `foo` is not a verb: it returns an UnknownOptionError("help") which is then filtered out of the output.

## How it should work

The [GNU Coding Standards docs on how to handle `--help`](https://www.gnu.org/prep/standards/standards.html#g_t_002d_002dhelp) are short:

> The standard `--help` option should output brief documentation for how to invoke the program, on standard output, then exit successfully. Other options and arguments should be ignored once this is seen, and the program should not perform its normal function.

This doesn't resolve some of the ambiguous situations. But by experimenting with standard GNU utilities and how they handle the `--help` option, some clear patterns emerge:

* `progname --help` should print help output
* `progname --help foo` should ignore the argument "foo" and print help output.
* `progname arg1 arg2 --help` should ignore `arg1` and `arg2` and print help output. Whether `arg1` and `arg2` were valid options or not should be completely ignored, and the help output should not contain any errors even if `arg1` and `arg2` were invalid.
* `progname --input-file --help`, where `--input-file` is an option that expects a string parameter, is a bit of a gotcha. This should **NOT** print help output; rather, `--input-file` should receive the string `--help` as its parameter. (You can confirm this by running multiple GNU commands on Linux, such as `ls --help` vs `ls --quoting-style --help`, and so on). More about this later.
* `progname verb --help` should display the help text for the specific verb in question *if* verbs are being used, otherwise `verb` should be ignored.
* `progname verb arg1 arg2 --help` should also display the help text for the specific verb in question, and not return any errors about arg1 and arg2.

The GNU standards do not specify whether `-h` should be taken as a short form for the long `--help` option. Here the behavior differs between Linux programs: *some* programs allow `-h` as a short form for `--help`, while others use `-h` as a short form for a different command (e.g., `ls -h` is short for `ls --human-readable`). The way CommandLineParser should handle this is to have a AutoHelpShortName flag (a bool), defaulting to **false*. If it is true, then the `-h` option will be taken as a shortname for `--help`. AutoHelpShortName should *not* be a string or a char; it is *not* recommended to change the shortname of the auto-help parameter from `-h` to something else, so if you want to do that you'll need to set AutoHelp=false and implement your own help option.

### About that `--input-file --help` scenario

The naïve approach, of scanning the incoming arguments to look for a `--help` option, will fail in this scenario. What needs to happen instead is that *all* arguments need to be parsed, and *then* all options (but NOT values) need to be scanned for the `--help` option, and/or the `-h` option if AutoHelpShortName is true. If the `--help` option is found, then all other errors are *ignored* (as per [the GNU docs](https://www.gnu.org/prep/standards/standards.html#g_t_002d_002dhelp)) and the help text is printed out. (The only time errors should be printed out is if `--help` is not present).

## What about `--version`?

The [GNU docs for `--version`](https://www.gnu.org/prep/standards/standards.html#g_t_002d_002dversion) are similar to `--help`:

> The standard `--version` option should direct the program to print information about its name, version, origin and legal status, all on standard output, and then exit successfully. Other options and arguments should be ignored once this is seen, and the program should not perform its normal function.

They go on to explain in more detail how to format the version information, but that's not really relevant for this issue. What's important here is that `--version` should be treated just like `--help`: it should handle `--version` appearing in *any* position in the options (except as a value to some other option), and should not return any other errors if `--version` is found. Also, there should be flag named AutoVersionShortName, defaulting to false, which will use the shortname `-V` (capital V) if it is true. (Lowercase `-v` is usually reserved for `--verbose`; the de facto standard in Linux utilities is that if `--version` has a shortname, it's capital `-V`).

## PR forthcoming

I plan to write a PR to handle `--help` and `--version` correctly, as opposed to the slightly-wrong way that CommandLineParser currently handles it. Expect that PR in the next few weeks.

Guía de contribución

No hay ninguna guía de contribución indexada para este repositorio

Evaluación

Este issue todavía no se ha evaluado.

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.