PicoCLI:依赖性和排他性参数混合
PicoCLI: Dependent and Exclusive Arguments mixed
我正在尝试使用 PicoCLI 实现如下目标:
- 选项 0(帮助,详细)
- 选项A
- 相关选项 A-1
- 相关选项 A-2
- 相关选项 A-3
- 选项B
- 需要选项 A
- 但不允许任何选项 A-*
我不知道我是否可以使用 PicoCLI 工具进行此设置,或者我是否可以在使用自定义代码解析后进行检查。
对于这种情况,选项 A 在需要选项 A 的 ArgGroup 中,但选项 A-* 不是。
选项 B 在不同的 ArgGroup 中。我试图设置一些独占的东西,但我不知道如何 ArgGroup/Exclusive 东西按预期工作...
有什么提示吗?
总结这些选项需要具备的关系:
-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(" "));
}
}
我正在尝试使用 PicoCLI 实现如下目标:
- 选项 0(帮助,详细)
- 选项A
- 相关选项 A-1
- 相关选项 A-2
- 相关选项 A-3
- 选项B
- 需要选项 A
- 但不允许任何选项 A-*
我不知道我是否可以使用 PicoCLI 工具进行此设置,或者我是否可以在使用自定义代码解析后进行检查。
对于这种情况,选项 A 在需要选项 A 的 ArgGroup 中,但选项 A-* 不是。 选项 B 在不同的 ArgGroup 中。我试图设置一些独占的东西,但我不知道如何 ArgGroup/Exclusive 东西按预期工作...
有什么提示吗?
总结这些选项需要具备的关系:
-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(" "));
}
}