Skip to content

Default arity should be 1, not *, for array and collection options #192

@remkop

Description

@remkop

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:

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.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions