remkop / picocli

Picocli is a modern framework for building powerful, user-friendly, GraalVM-enabled command line apps with ease. It supports colors, autocompletion, subcommands, and more. In 1 source file so apps can include as source & avoid adding a dependency. Written in Java, usable from Groovy, Kotlin, Scala, etc.
https://picocli.info
Apache License 2.0
4.93k stars 424 forks source link

Error - Expected parameter for option when one option value starts with another option #2340

Open radcortez opened 1 month ago

radcortez commented 1 month ago

Consider:

@CommandLine.Command(name = "dashed")
public class DashedOption implements Callable<Integer> {
    @CommandLine.Option(names = "-x")
    String x;

    @CommandLine.Option(names = "--required", required = true)
    String required;

    @Override
    public Integer call() throws IOException {
        return 0;
    }

    public static void main(String[] args) {
        new CommandLine(new DashedOption()).execute(new String[]{"--required=-1"});
        new CommandLine(new DashedOption()).execute(new String[]{"--required=-"});
        new CommandLine(new DashedOption()).execute(new String[]{"--required=-a"});
        new CommandLine(new DashedOption()).execute(new String[]{"--required=-x"});
    }
}

Output:

Expected parameter for option '--required' but found '-x'
Usage: dashed --required=<required> [-x=<x>]
      --required=<required>

  -x=<x>

When one option value starts with another option it causes the error Expected parameter for option '--required' but found '-x'. Notice that it is perfectly fine to pass dashed values to a particular option value, but it fails if that value starts with another option.

remkop commented 1 month ago

The picocli parser does not distinguish between = or whitespace as the separator between options and their option parameter.

You will need to do some custom processing.

Please take a look at 11.15. Custom Parameter Processing in the user manual.

remkop commented 1 month ago

I looked at the linked Quarkus issue and now I'm a bit confused.

I thought the error would only occur when the user specified an exact option name as the value for another option, but it seems that the issue also occurs even if the value starts with an option name.

Away from my PC now, I'll take another look.

Meanwhile, before diving into Custom Processing, please check out this parser configuration option (11.9.2. Enable Consuming Option Names or Subcommands). This may solve the issue more simply.

radcortez commented 1 month ago

I thought the error would only occur when the user specified an exact option name as the value for another option, but it seems that the issue also occurs even if the value starts with an option name.

Yes, correct. Sorry, I should have been more clear on that one. It does happen when the option value starts with another option. So:

new CommandLine(new DashedOption()).execute(new String[]{"--required=-xabc"});

This will also fail.

Meanwhile, before diving into Custom Processing, please check out this parser configuration option (11.9.2. Enable Consuming Option Names or Subcommands).

Thanks. I'll have a look.