command-line-api icon indicating copy to clipboard operation
command-line-api copied to clipboard

Mutually exclusive options

Open sandcastle opened this issue 6 years ago • 15 comments

It would be great to be able to handle mutually exclusive options.

Example

For example, if I had a command that either took an --all option or a --tenant <tenant-id> option, but never both.

public static Command Rebuild(IContainer container)
{
    var rebuild = new Command("rebuild", "Rebuilds a search index for one (--tenant <tenant-id>) or all (--all) tenants.")
    {
        Handler = CommandHandler.Create<bool, Guid>((all, tenant) =>
            container.Resolve<SearchRebuildTask>().ExecuteAsync(all, tenant))
    };

    rebuild.AddOption(new Option(new[] {"--all", "-a"},
        "Indicates if all tenants should be rebuilt.",
        new Argument<bool>(false) {Arity = ArgumentArity.ZeroOrOne}));

    rebuild.AddOption(new Option(new[] {"--tenant", "-t"},
        "Specifies the specific tenant that should be rebuilt.",
        new Argument<Guid> {Arity = ArgumentArity.ZeroOrOne}));

    return rebuild;
}

sandcastle avatar Jan 20 '19 23:01 sandcastle

This can currently be done using a custom validator, although it's a bit awkward.

https://github.com/dotnet/command-line-api/blob/master/src/System.CommandLine.Tests/ParsingValidationTests.cs#L104

Suggestions on a nicer API for this feature?

jonsequitur avatar Jan 22 '19 23:01 jonsequitur

@jonsequitur As per our discussion earlier. It would also be great to have these changes cascade to dotnet-suggest. i.e The auto completion should not suggest the mutually excusive options when one of them is set.

Should we track this in separate issue or should we include it in this issue itself?

srsaggam avatar Feb 20 '19 21:02 srsaggam

I think it's fine to track it here.

jonsequitur avatar Feb 20 '19 21:02 jonsequitur

cc : @CESARDELATORRE @vinodshanbhag @rjoshi

srsaggam avatar Feb 20 '19 22:02 srsaggam

@jonsequitur Jon, what's the priority for this feature? It'd be very good for the ML.NET CLI due to parameters like the following which are exclusive:

--label-column-name | --label-column-index

CESARDELATORRE avatar Feb 21 '19 20:02 CESARDELATORRE

@CESARDELATORRE, this capability is supported right now but the API is awkward. Improving the API will likely be done along with improvements to enable #310, and it's fairly high priority but I don't have a timeline for it. I don't believe this should block you.

@srsaggam, my understanding is that you have the validation working but tab suggestions don't reflect the exclusivity. Is that correct?

jonsequitur avatar Feb 21 '19 22:02 jonsequitur

@jonsequitur That is correct. My comment is regarding tab suggestions. I think @CESARDELATORRE is referring to the same. We are not blocked by the functionality but we were thinking the intelligent suggestions for this case will be a good feature to demo and will help our users to not make mistakes.

srsaggam avatar Feb 21 '19 22:02 srsaggam

Sorry, I was not clear with my comment. It is regarding tab suggestions. For example, if I use the arg --label-column-name then since --label-column-index is mutually exclusive, the tab suggestion shouldn't show --label-column-index but the next argument.

I think we're good if that feature related to tab suggestions is moving forward. You are right that this is not a blocking issue but improving the user's experience. 👍

CESARDELATORRE avatar Feb 21 '19 22:02 CESARDELATORRE

Also for this. Lets say we have options like : --abc --abze --dab --dbc

when we type --ab[->TAB] the suggestions should be abc on first tab and abze on the second tab and this should repeat it shouldn't suggest anything else. kind of prefix tree based suggestions then sorting ascending order

but looks like the current dotnet suggest doesn't do this kind of behavior it doesn't seem to respect the prefix that is already typed. it just suggests in the alphabetical order on whole set rather than filtered prefix.

@jonsequitur @CESARDELATORRE

srsaggam avatar Feb 27 '19 00:02 srsaggam

@srsaggam This deserves a separate issue. If you type ab and hit tab do you see the expected behavior?

jonsequitur avatar Feb 27 '19 03:02 jonsequitur

The link to a custom validator above is no longer valid. Here is a valid one

AndrewSav avatar Aug 07 '20 04:08 AndrewSav

Just to circle back on this; Is the current way to do this only via custom validation? is there a different API planned or..?

ransagy avatar Aug 10 '22 14:08 ransagy

Currently, a custom parse delegate is the recommended approach, although we'll likely add first-class API for this in the future.

jonsequitur avatar Aug 10 '22 14:08 jonsequitur

In case anyone is interested; this is how I do it:

Generic validator: https://github.com/dorssel/usbipd-win/blob/2f7cbb732889ed00617e85f2f0b22239e8533960/Usbipd/Program.cs#L86-L94

Used as: https://github.com/dorssel/usbipd-win/blob/2f7cbb732889ed00617e85f2f0b22239e8533960/Usbipd/Program.cs#L188-L191

This can be used for any number of n mutually exclusive options, with the correct error message if none or too many are given. Of course, this can easily be tweaked to allow zero options as well.

dorssel avatar Sep 12 '22 19:09 dorssel