CommandLineUtils: VersionOption doesn't ever use the short getter

Steps to Reproduce

  1. Clone this repo (at commit 92481fac0cf8ccc8345af7f785a4a50d29675534 at time of reporting)
  2. Build the solution using build.cmd
  3. Run C# Interactive (csi.exe)
  4. Add reference to McMaster.Extensions.CommandLineUtils.dll via #r
  5. Execute the following:
    using McMaster.Extensions.CommandLineUtils;
    var app = new CommandLineApplication(throwOnUnexpectedArg: false);
    app.VersionOption("-v|--version", () => "version (short)", () => "version (long)");
    app.Execute(new[] { "-v" });
    app.Execute(new[] { "--version" });
    

Expected Output

Expected the line app.Execute(new[] { "-v" }); to print version (short) and the line app.Execute(new[] { "--version" }); to print version (long).

Actual Output

Microsoft (R) Visual C# Interactive Compiler version 2.7.0.62715
Copyright (C) Microsoft Corporation. All rights reserved.

Type "#help" for more information.
> #r "A:\CommandLineUtils\.build\bin\McMaster.Extensions.CommandLineUtils\Debug\net45\McMaster.Extensions.CommandLineUtils.dll"
> using McMaster.Extensions.CommandLineUtils;
> var app = new CommandLineApplication(throwOnUnexpectedArg: false);
> app.VersionOption("-v|--version", () => "version (short)", () => "version (long)");
> app.Execute(new[] { "-v" });
version (long)
> app.Execute(new[] { "--version" });
version (long)

Both of the following lines:

app.Execute(new[] { "-v" });
app.Execute(new[] { "--version" });

print version (long), which is incorrect. There seems to be no way to distinguish between the two when VersionOption specifically allows one to have a short and a long getter.

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Comments: 15 (11 by maintainers)

Most upvoted comments

@atruskie Thanks for the very detailed and awesome response.

Earlier the example of git log -h vs git log --help was cited as a seemingly incongruent example; they, in fact, aren’t and follow the behaviour of my second example. Internally git rewrites the --help flag to invoke git help (see git help docs). The --help option is a separate option from the -h option.

I’m well aware of this but you have to admit, irrespective of what it does under the hood (for the curious few who bother to read the help on help and pop and look under the hood) is irrelevant because the end effect is that to the uninformed user, -h appears like an alias for --help. Now we can argue whether that’s intended or it’s really two separation options (which I think what it is):

-h        Show a summary of usage and common options
--help    Show detailed help documentation

I’m strongly opposed to the idea that the same option should have different behaviours based on whether the short or long version is used. The essential notion of short forms is that they are synonyms of the long forms

I’m not arguing for long and short forms should do different things. As far as version display goes, there are different ways to go about it like you suggested. I’d even say the following is confusing:

-v                             Show short version information
--version                      Show long version information

What I’d rather see is combining options. Suppose:

-v|verbose                     Show verbose output
--version                      Show version information

So if you use --version, you get the short version display. If you specify --version with -v or --verbose then you get a more detailed display. You can also go the other way if you have a -q or --quiet option, where --version will give you the longer display by default but combined with -q or --quiet will give the short machine-readable format. I can even imagine --version --machine.

Anyway, I think we’ve gone a bit off track here. The issue title reads, “VersionOption doesn’t ever use the short getter” and that’s all I meant to highlight as a bug. I didn’t want to argue here the merits or perils of using the long and short form of an option to change the display of what is logically the same information. Even if I was to argue that, it would be confined to version and version display only. I would never suggest that an application should use long and short forms as a general approach to switch between machine-readable and human-readable output. It’s much better to have an explicit option to flag that and version display doesn’t have to be an exception to that rule. I guess VersionOption mislead me there given its signature and I can admit that I was being mischievous 😇 and taking advantage of (what appeared to be) its support for long and short version display.

Ok, how about this as a hotfix to unblock you @atifaziz? --> #96

@atruskie you’re comments connect well with some refactoring I’ve been considering. I don’t like that --version and --help are special-cased in the parser. As we’ve discovered, it makes it hard to extend and customize their behavior, or to add your own version/help options. Users end up putting code at the top of the OnExecute block to check for “special” options. Maybe that’s okay, but I was thinking of generalizing this behavior; I just haven’t landed on an implementation I like yet.