-
Notifications
You must be signed in to change notification settings - Fork 420
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
Options disallow values that match subcommand name #1125
Comments
We are facing the same issue. We would like to get JVM options from the user by using a
The example in here also doesn't work when you run with |
When you say Very often, you can pass Java options to the launcher script by setting an environment variable like Otherwise, you may need to specify the Also, do you need a space between the |
We are spawning new Java processes in our command line application, thus we need additional JVM options to be taken from the user. It is like
Yes, we normally expect to work with space.
Would you please verify if the example in the documentation doesn't work? Or am I missing something? |
Ok. Away from my pc now. I’ll need some time for this. |
PS. Does the problem also happen with the previous version of picocli? (4.3.2) |
The example in the documentation works with 4.3.2. However, we still get the same exception with 4.3.2 since we are using a Collection field. |
This example gets the following output with
|
@alparslanavci Is your @Option(names = "-J")
List<String> javaOptions; One idea is to do custom parameter processing for the @Command(name = "myapp")
class MyApp {
@Option(names = "-J", parameterConsumer = JavaOptionsConsumer.class)
List<String> javaOptions = new ArrayList<String>();
}
class JavaOptionsConsumer implements IParameterConsumer {
public void consumeParameters(Stack<String> args, ArgSpec argSpec, CommandSpec commandSpec) {
if (args.isEmpty()) {
throw new ParameterException(commandSpec.commandLine(), "Error: option '-J' requires a parameter");
}
String arg = args.pop();
List<String> list = argSpec.getValue();
list.add(arg);
}
} |
@remkop thanks for the suggestion! Yes, we can use this one as a workaround until the issue is fixed with the new version. Just want to confirm, we need to parse the args manually if it is provided as a list of parameters such as |
Yes that's correct; with custom parameter handling the trade off is that you gain complete freedom but you give up on functionality: all the work of unquoting and splitting parameter values becomes the responsibility of the application. |
An option to disable the error, at least for the case where option values == option names would be greatly appreciated. We're evaluating the use of picocli to convert a large old bespoke CLI app which uses option names without any sort of prefix. Sometimes the same value appears as both a value to one option and as a "flag" on its own. All enums accept case-insensitive values. Changing the interface is not an option. For this example, the command enum ItemType {
SIMPLE,
COMPLEX;
}
class Main {
@Option(names="type") ItemType type;
@Option(names="simple") boolean doSimpleVerification;
} Right now we're working around this using custom parameter consumers for the affected commands, but this is not ideal. |
@bherw I understand your situation but it may not be easy to change the parser behavior, and there is a workaround. My time to work on picocli has become extremely limited, so there are other items that I will probably work on first. If this is important to you, you can consider contributing a pull request. Something that provides a parser configuration option to allow option values matching option names and subcommands. (Maybe separate flags for each of these.) A great pull request would include tests and documentation, to minimize the work I would need to do to get this feature in. |
Disallowing any values for options does not make sense to me. Why can't a whitespace-separated option-value pair just use the next token as its value, and a conjoined option-value pair (using a separator like Is this behavior intentional, or is it just a consequence of not being able to get the parser to work correctly? |
Interesting point. So perhaps we can improve the parser. (Hopefully while staying as backwards compatible as possible...) 😅 For this example: class App {
@Option(names = "-x") String x;
@Option(names = "-y") String y;
} Currently picocli (correctly, in my opinion) shows an error for input like However, input like I am still thinking about this; there may be edge cases that I haven't considered yet, and also there may be users who do not want this behaviour, so we need a parser configuration option to switch this off again. |
Each option should have a count of expected values. count = 0 is a true/false flag option, like For options using a whitespace option-name/value separator, the parser would just grab the subsequent command-line tokens as the values for the option. If there aren't enough values, it would output an error. |
Such a count exists, it is the |
If If That should take care of allowing values to have any value. Every command-line program I've ever used allows all values for option values. I've never seen any program disallow values that begin with |
To clarify, this is the problem space as I see it:
I think we only need to consider cases 1 and 2. (If anyone thinks differently, please comment!)
This would allow all options in a command to consume arguments that match subcommands or options, respectively. Any other requirement (like, allow only some options in the command to consume subcommands/options) can be taken care of with custom parameter processing. |
@alparslanavci @bherw @rgoldberg From the release notes: Enable Consuming Option Names or SubcommandsBy default, options that take a parameter do not consume values that match a subcommand name or an option name. This release introduces two parser configuration options to change this behaviour:
When set to This means that any option will consume the maximum number of arguments possible for its arity. USE WITH CAUTION! If an option is defined as Feedback welcome! |
The parser became stricter in picocli 4.4, because of #1055.
The following values became disallowed as option values:
subcommandsRepeatable
)(Implementation note: Interpreter::assertNoMissingMandatoryParameter > varargCanConsumeNextValue > isOption)
There are use cases where applications do want to allow such values as option parameters. (See petermr/ami3#48 for some discussion.)
Consider introducing a mechanism that allows this. Some considerations:
=
or:
separator. (E.g., allow--option=--option
but not--option --option
)The text was updated successfully, but these errors were encountered: