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

Contention between optional option and required parameter #981

Closed
mohdpasha opened this issue Apr 1, 2020 · 5 comments
Closed

Contention between optional option and required parameter #981

mohdpasha opened this issue Apr 1, 2020 · 5 comments
Labels
theme: parser An issue or change related to the parser

Comments

@mohdpasha
Copy link

The example I am using has three options followed by one required parameter. The options could be used in any order. One of the options is a String with arity="0..1". This is an optional string. When this option is used as the last of the options (with the option used but a value not specified) followed by the required String parameter, the value which should go to the REQUIRED parameter is going to the OPTIONAL option instead. MissingParameterException is being thrown. This is not expected behavior. I would consider this a bug. I can provide additional details if the scenario is unclear. Thank you.

@remkop
Copy link
Owner

remkop commented Apr 1, 2020

Hi, yes, this is how picocli currently handles options with an optional parameter.

The picocli parser is “greedy” when it handles optional parameters: it looks at the value following the option name, and if that value is likely to be a parameter (not another option or subcommand) then picocli will process the value as a parameter for that option.

(See also a similar discussion on #979.)

(Update: I raised Investigate feasibility of parser backtracking for ambiguous options (#980) for this.)

We could try to improve the logic for determining if a value is “likely to be a parameter”, but this is not straightforward. It requires looking forward at all remaining arguments to see if all required positional parameters (there may be more than one) will get a value. This means parsing all the way to the end before deciding on how to treat the value following an optional option: so we would need to implement a backtracking parser, and while this is on the TODO list, it may take a while before I can get to it.

Possible Solutions/Workarounds

One way to deal with this is to point out this ambiguity in the documentation of your application. End users can disambiguate the input by specifying either the -- end-of-options delimiter or another option between the optional option and the required parameter. It is after all quite possible that the end user intended the value to be a parameter for the option and actually did forget to specify the required positional parameter.

An alternative you could consider is removing the ambiguity from your application. For example, an optional option could be replaced by a boolean option plus an option that requires a parameter.

@mohdpasha
Copy link
Author

So, the optional option has three possibilities:

  1. Not used (-x was not used)
  2. Used without a value (-x)
  3. Used with a value (-x value)

These are all valid for arity 0..1.

In throwing a MissingParameterException, your logic is throwing out #2 as a valid possibility. To me, that translates as a bug because it goes against the specification.

@remkop
Copy link
Owner

remkop commented Apr 2, 2020

I will update the documentation to clarify what picocli's behaviour is in this scenario. I don't think it is mentioned anywhere at the moment.

@remkop
Copy link
Owner

remkop commented Apr 2, 2020

Until #980 is implemented, the best I can do is clarify the current behaviour.

I added section Options with an Optional Parameter to the user manual.

@remkop remkop added the theme: parser An issue or change related to the parser label Apr 2, 2020
remkop added a commit that referenced this issue Apr 21, 2020
* added section Variable Arity Limitations
* moved contents from section Options with an Optional Parameter into section Optional Values
@remkop
Copy link
Owner

remkop commented Feb 15, 2022

Closing this issue.
This is a known and (thanks to your feedback) documented drawback of defining commands that have both an option with an optional parameter and a positional parameter.

However, picocli now offers parser plugins for custom parameter processing.
The documentation for the IParameterPreprocessor plugin has an example showing a solution for this exact use case.

Hopefully that offers sufficient flexibility for people to build applications meeting their requirements.

@remkop remkop closed this as completed Feb 15, 2022
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
Projects
None yet
Development

No branches or pull requests

2 participants