Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Required Arguments (ExactlyOne arity) aren't being validated if not supplied #484

Open
watermelonpizza opened this Issue Apr 6, 2019 · 9 comments

Comments

Projects
None yet
3 participants
@watermelonpizza
Copy link

commented Apr 6, 2019

If you create a command with an option and its arity is ExactlyOne it will not be validated if the option isn't supplied in the arguments.

For example:

var command = new Command("team")
{
    new Option("--sport", argument: new Argument<string> { Arity = ArgumentArity.ExactlyOne })
};

command.Handler = CommandHandler.Create(async (string sport) => 
{
   // sport is null
   ...
}

If you call the application with myapp team there is no validation performed against --sport so it can slip through as null in the handler.

If supplied i.e. myapp team --sport then you get validation:

Required argument missing for option: --sport
@jonsequitur

This comment has been minimized.

Copy link
Collaborator

commented Apr 7, 2019

Thanks, @watermelonpizza. This is the intended design, although it's a bit confusing. What the ExactlyOne arity means in your example (which by the way is the default for Argument<T> in all cases where T is neither bool nor IEnumerable) is that if --sport is specified, it must be provided exactly one argument. It does not mean that the --sport is required when invoking the team command. So:

> team                    #valid
> team --sport futbol     #valid
> team --sport            #invalid

I added arity examples to the wiki to help explain. Please let me know if this is helpful and whether there's a clearer way we can communicate the intention.

@watermelonpizza

This comment has been minimized.

Copy link
Author

commented Apr 7, 2019

Ah ok thanks @jonsequitur .
If possible maybe also add some clarification of the automatic assumptions on Arity based on the argument type under perhaps here https://github.com/dotnet/command-line-api/wiki/How-To#argument-validation-and-binding (unless I missed it somewhere else) like what a standard value type like string sets as arity vs. a IEnumerable vs. bool etc.

Also, is there any way to specify an argument as required then? Sometimes like in my case it would be nice to force users to specify an argument for some command/option.

Thanks! :)

@jonsequitur

This comment has been minimized.

Copy link
Collaborator

commented Apr 9, 2019

An argument with an arity of ExactlyOne is required when its parent command or option is specified.

If you're wondering if there's a way to require that an option be specified (e.g. make --sport required), there's currently a way to do this but it's awkward. We're planning to create a simpler API here, but this will work:

var command = new RootCommand { new Option("-x") };

command.Argument.AddValidator(symbolResult =>
{
    if (symbolResult.Children["-x"] is null)
    {
        return "Option -x is required";
    }
    else
    {
        return null;
    }
});

var result = command.Parse("");

result.Errors.Should().Contain(e => e.Message == "Option -x is required");
@watermelonpizza

This comment has been minimized.

Copy link
Author

commented Apr 9, 2019

Oh, awesome!
Thanks mate. I'll use that in my app. :)

Should I close this issue then?

@tmds

This comment has been minimized.

Copy link
Member

commented Apr 11, 2019

@jonsequitur It may be meaningful that System.CommandLine understands what Options are required, so no custom validation is needed.
When printing help, required options could be indicated:

For example:

Usage:
  program command --required <REQUIRED> [options] <arg>
@jonsequitur

This comment has been minimized.

Copy link
Collaborator

commented Apr 11, 2019

If we add an intrinsic concept for making an option required, that would make sense.

Another common use case that complicates this is when option A is required only when option B is provided. Thoughts?

@tmds

This comment has been minimized.

Copy link
Member

commented Apr 12, 2019

Another common use case that complicates this is when option A is required only when option B is provided. Thoughts?

Can it be solved with a validator? 😄
We also need to think, if the user can express this explicitly, how would we use it.

@jonsequitur

This comment has been minimized.

Copy link
Collaborator

commented Apr 12, 2019

It can be solved with a validator but displaying the intention of the validator in help is beyond the scope of the validator interface.

@watermelonpizza

This comment has been minimized.

Copy link
Author

commented Apr 13, 2019

Maybe the option/argument objects could have a list of required symbols as a property?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.