Подводя итог взаимосвязям, которые должны иметь эти параметры:
-B
, -A1
, -A2
и -A3
требуется параметр -A
-B
запрещает любой из параметров -A1
, -A2
и -A3
- параметры
-A1
, -A2
и -A3
разрешают друг друга
- параметр
-A
разрешает (но не требует) параметры -B
, -A1
, -A2
и -A3
Одних аннотаций picocli будет недостаточно для декларативного выражения всех этих отношений, потребуется некоторая пользовательская проверка.
Таким образом, мы могли бы также упростить и создать единую группу аргументов, поскольку мы не можем выразить требование 2 (-B является исключающим с -A1, -A2, -A3) одновременно с требованием 1 и 3 (-B, -A1, -A2 и -A3 все требуют -A и -A1, -A2, -A3 разрешают друг друга).
Одна группа, такая как [-A [-B] [-A1] [-A2] [-A3]]
, позаботится о некоторых проверках: обо всем, кроме требования 2 (-B является эксклюзивным с -A1, -A2, -A3). Для требования 2 нам нужно закодировать некоторую пользовательскую проверку в приложении (пример ниже).
Для вашего варианта использования может быть полезно иметь собственный синопсис, который точно отражает взаимосвязь между параметрами. Что-то вроде этого:
Usage: app [-hV] [-A [-B]]
app [-hV] [-A [-A1] [-A2] [-A3]]
Пример кода для достижения этого:
import picocli.CommandLine;
import picocli.CommandLine.*;
import picocli.CommandLine.Model.CommandSpec;
@Command(name = "app", mixinStandardHelpOptions = true,
synopsisHeading = "",
customSynopsis = {
"Usage: app [-hV] [-A [-B]]",
" app [-hV] [-A [-A1] [-A2] [-A3]]",
})
public class App implements Runnable {
static class MyGroup {
@Option(names = "-A", required = true) boolean a;
@Option(names = "-B") boolean b;
@Option(names = "-A1") boolean a1;
@Option(names = "-A2") boolean a2;
@Option(names = "-A3") boolean a3;
boolean isInvalid() {
return b && (a1 || a2 || a3);
}
}
@ArgGroup(exclusive = false)
MyGroup myGroup;
@Spec CommandSpec spec;
public void run() {
if (myGroup != null && myGroup.isInvalid()) {
String msg = "Option -B is mutually exclusive with -A1, -A2 and -A3";
throw new ParameterException(spec.commandLine(), msg);
}
System.out.printf("OK: %s%n", spec.commandLine().getParseResult().originalArgs());
}
public static void main(String[] args) {
//new CommandLine(new App()).usage(System.out);
//test: these are all valid
new CommandLine(new App()).execute();
new CommandLine(new App()).execute("-A -B".split(" "));
// requires validation in the application to disallow
new CommandLine(new App()).execute("-A -B -A1".split(" "));
// picocli validates this, gives: "Error: Missing required argument(s): -A"
new CommandLine(new App()).execute("-B -A1".split(" "));
}
}
person
Remko Popma
schedule
18.03.2020
-A1
требует-A
и разрешает (но не требует)-A2
и-A3
. Точно так же-A2
требует-A
и разрешает (но не требует)-A1
и-A3
. Параметр-A
позволяет, но не требует использования параметров-A1
,-A2
и-A3
. Это правильно? - person Remko Popma   schedule 18.03.2020