Write cmd interface with Java code used picocli v4.6.3
My case: ./cmd [-a -b [-c]]
user put a,b option or got default value example:
a,b,c option got default value
request input b option and vice versa (c option still get default value)
a & b option get default value
@Command
public class CMD implements Runnable {
@Parameters
private String x;
@ArgGroup(exclusive = false)
private Group group;
static class Group {
@Option(names = "-a", required = true, defaultValue = "aa")
public static String a;
@Option(names = "-b", required = true, defaultValue = "bb")
public static String b;
@Option(names = "-c", required = false, defaultValue = "cc")
public static String c;
}
But it didn't work as I wanted I didn't have the solution
Original Answer
The picocli user manual has a detailed section on assigning default values in argument groups.
Applications need to do both of the below:
@Option
annotation, and in the initial value of the @Option
-annotated field. (Yes, that means some duplication.)@ArgGroup
-annotated fieldFor your example, that means:
@Command
public class CMD implements Runnable {
@Parameters
private String x;
@ArgGroup(exclusive = false)
private Group group = new Group();
static class Group {
@Option(names = "-a", required = true, defaultValue = "aa")
public static String a = "aa";
@Option(names = "-b", required = true, defaultValue = "bb")
public static String b = "bb";
@Option(names = "-c", required = false, defaultValue = "cc")
public static String c = "cc";
}
Update (Answer #2)
@kienbui pointed out that I missed these requirements:
(...) if
-a
is specified, then-b
becomes mandatory (user input becomes required), and similarly if-b
is specified, then-a
becomes mandatory. Otherwise, if neither-a
nor-b
is specified, none of the options are required and default values are assigned to the options that are not specified by the end user.
This can be achieved by making a separate inner arg-group for just options -a
and -b
, and removing the default values from the option declarations, but initializing them with their default values.
For example:
@Command
static class CMD implements Runnable {
@Parameters
private String x;
@ArgGroup(exclusive = false)
private Group group = new Group();
static class Group {
@ArgGroup(exclusive = false)
private InnerGroup inner = new InnerGroup("aa", "bb"); // default values
@Option(names = "-c", required = false, defaultValue = "cc")
public String c = "cc";
}
static class InnerGroup {
// default constructor, used by picocli when
// one or more options in this group are
// matched on the command line
public InnerGroup() {}
// this constructor assigns default values,
// used only when *both* options are missing
public InnerGroup(String a, String b) {
this.a = a;
this.b = b;
}
@Option(names = "-a", required = true)
public String a;
@Option(names = "-b", required = true)
public String b;
}
@Override
public void run() {
System.out.printf("a=%s, b=%s, c=%s, x=%s%n",
group.inner.a, group.inner.b, group.c, x);
}
}