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

Long boolean options with arity 0 still allow parameters. #509

Closed
zegelin opened this issue Oct 8, 2018 · 5 comments
Closed

Long boolean options with arity 0 still allow parameters. #509

zegelin opened this issue Oct 8, 2018 · 5 comments
Labels
theme: parser An issue or change related to the parser type: bug 🐛
Milestone

Comments

@zegelin
Copy link

zegelin commented Oct 8, 2018

Given a option definition:

@CommandLine.Option(names = {"--no-global-labels"}, arity = "0")
public void setNoGlobalLabels(final boolean noGlobalLabels) {}

This still allows --no-global-labels=false.

For non-boolean long options arity = "0" probably doesn't make sense. But for options like this it'd be nice to have picocli enforce the arity rather than have to check the boolean parameter and throw an exception if its false.

@remkop
Copy link
Owner

remkop commented Oct 8, 2018

I can see this is inconsistent, thanks for raising it. I’ll take a look.

@remkop
Copy link
Owner

remkop commented Oct 9, 2018

I assumed that people would only specify arity for boolean options to optionally allow a parameter (as in arity = "0..1"), I did not foresee your use case of strict validation to prevent end users from specifying a boolean value.

Here is what currently happens:

  • During the construction stage, all options are assigned a non-null arity. If omitted, the arity is derived from the type.
  • For boolean types, the derived arity is zero.
  • During parsing, if the parser finds a value attached to the option (as in --no-global-labels=false), picocli concludes that the "actual arity" is arity="1".

At the moment, picocli does not distinguish between an omitted arity and an explicitly specified arity = "0" for boolean options.

Still looking at how to fix this.

@remkop
Copy link
Owner

remkop commented Oct 9, 2018

I have a potential solution that involves keeping track of whether the arity was explicitly specified in the option definition.

This test now passes:

@Test
public void testArityZeroForBooleanOption() {
    class App {
        @Option(names = "--explicit", arity = "0") boolean explicit;
        @Option(names = "--implicit") boolean implicit;
    }
    try {
        new CommandLine(new App()).parseArgs("--implicit=false --explicit=false".split(" "));
        fail("--explicit option should not accept parameters");
    } catch (ParameterException ex) {
        assertEquals("option '--explicit' (<explicit>) should be specified without 'false' parameter", ex.getMessage());
    }
}

Still checking for regressions...

@remkop
Copy link
Owner

remkop commented Oct 10, 2018

Fixed in master.

Is this a critical issue for you? (That is, do you need a 3.6.2 release for this, or can it wait a few weeks for the 3.7 release?)

@zegelin
Copy link
Author

zegelin commented Oct 10, 2018

@remkop Thanks for the quick-fix. I can wait till 3.7 since I have interm a work-around (throw if value = false).

@remkop remkop added the theme: parser An issue or change related to the parser label Apr 2, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
theme: parser An issue or change related to the parser type: bug 🐛
Projects
None yet
Development

No branches or pull requests

2 participants