meyerjp3
meyerjp3

Reputation: 197

Can picocli subcommands have options with the same name?

I have a program that executes different types of statistical analysis. I would like to define a subcommand for each type of analysis. The parent command would be the main entry point into the program. I get an error message that says "option should be specified only once" when my subcommands have options with the same name. The problem seems to be how I am calling the subcommands. In the example below, input1 and input2 work correctly. When I try to use both subcommands simultaneously (input3), I get an error message.

The code below demonstrates the problem. If the input contains both subcommands (i.e. input3), I get the error message "option '-id' at index 0 () should be specified only once".

How can I call both subcommands simultaneously as in input3?

import picocli.CommandLine;

import java.util.concurrent.Callable;

@CommandLine.Command(name = "myprogram", subcommands = {TestCase.FrequencyCommand.class, TestCase.HistogramCommand.class})
public class TestCase  implements Callable<Void> {

    public TestCase(){

    }

    public Void call() {
        System.out.println("Main program called");
        return null;
    }

    public static void main(String[] args){

        String[] input1 = {"frequency", "-id", "1001", "-table", "ex1"};
        String[] input2 = {"histogram", "-id", "1002", "-table", "ex5" };
        String[] input3 = {"frequency", "-id", "1001", "-table", "ex1", "histogram", "-id", "1002", "-table", "ex5" };

        CommandLine commandLine = new CommandLine(new TestCase());
        System.out.println("==Test1==");
        commandLine.execute(input1);
        System.out.println();

        System.out.println("==Test2==");
        commandLine.execute(input2);
        System.out.println();

        System.out.println("==Test3==");
        commandLine.execute(input3);
        System.out.println();

    }




    @CommandLine.Command(name = "frequency", description = "Frequency analysis.")
    static class FrequencyCommand implements Callable<Void> {

        @CommandLine.Option(names = {"-id"}, arity = "1..*", description = "Unique case identifier")
        public String id;

        @CommandLine.Option(names = "-table", arity = "1..*", description = "Database table")
        public String table;

        public FrequencyCommand(){

        }

        public Void call() {
            System.out.println("Frequency");
            System.out.println("ID = " + id);
            System.out.println("Table = " + table);
            return null;
        }
    }

    @CommandLine.Command(name = "histogram", description = "Histogram plot.")
    static class HistogramCommand implements Callable<Void> {

        @CommandLine.Option(names = {"-id"}, arity = "1..*", description = "Unique case identifier")
        public String id;

        @CommandLine.Option(names = "-table", arity = "1..*", description = "Database table")
        public String table;

        public HistogramCommand(){

        }

        public Void call() {
            System.out.println("Histogram");
            System.out.println("ID = " + id);
            System.out.println("Table = " + table);
            return null;
        }
    }

}

The output I expect to see is:

==Test1==
Frequency
ID = 1001
Table = ex1

==Test2==
Histogram
ID = 1002
Table = ex5

==Test3==
Frequency
ID = 1001
Table = ex1
Histogram
ID = 1002
Table = ex5

Upvotes: 2

Views: 393

Answers (1)

Remko Popma
Remko Popma

Reputation: 36754

The last example invokes two subcommands, frequency and histogram, which are siblings (they have the same parent command).

This is not supported yet as of picocli 4.0.0-alpha-3: currently picocli expects subcommands to be a hierarchy.

However, support for this is on the todo list, see GitHub tickets #454 and #319.

Pull requests are welcome if you want to help speed things up. :-)

Upvotes: 1

Related Questions