-
Notifications
You must be signed in to change notification settings - Fork 441
Description
Currently if an option for a list or array field doesn't have an explicit arity
attribute, the default is to be greedy: consume as many arguments as possible until the next option or until the --
end-of-options delimiter is encountered.
This causes a number of problems:
- ambiguity between multi-value options and positional parameters (see How to define an option to accept only one value, but allow to use it multiple times? #190; unfortunately bug Arity should not limit the total number of values put in an array or collection #191 means that the only way to resolve this ambiguity is for end users to specify the
--
end-of-options delimiter on the command line) - it is counter-intuitive for many Unix users who expect an option to have only one argument
- it makes it difficult to implement mixing options and positional parameters on the command line (Add support for options _following_ positional parameters #130)
Example
To illustrate, consider the following application:
class Args {
@Option(names="-o") List<String> options;
@Parameters List<String> positionalParams;
public static void main(String... args) {
System.out.printf("Options: %s%n", options);
System.out.printf("Positional: %s%n", positionalParams);
}
}
Current (incorrect)
Currently (as of v1.0.1) this input gives the following output:
<command> -o val1 val2 val3
# current (bad) behavior
Options: [val1, val2, val3]
Positional: []
This default behavior is counterintuitive for applications that also have positional parameters. It becomes impossible to see where the options stop and the positional parameters begin unless the user specifies the --
end-of-options delimiter.
Correct
Instead, we want the parser to behave like this:
<command> -o val1 val2 val3
# expected behavior
Options: [val1]
Positional: [val2, val3]
That would be consistent with how most Unix tools work. Most Unix tools would expect the option to consume only one argument. The option can then be specified multiple times in order to collect multiple values. E.g.,
<command> -o val1 -o val2 -o val3
Solution
This ticket proposes to change the default behavior to consume only one argument for list/array options that don't have an explicit arity
attribute defined.
Users will be able get the current greedy behavior by explicitly specifying arity="1..*"
.
This will solve the above problems but may cause disruption for existing users/applications who rely on the current behaviour. I am not happy about that, but I believe this change is necessary to keep moving picocli forward. I hope that bumping the version number to 2.0 to signal an incompatible change will help reduce the disruption.