【问题标题】:PicoCLI: Dependent and Exclusive Arguments mixedPicoCLI:混合的依赖和排他参数
【发布时间】:2020-03-18 06:54:12
【问题描述】:

我正在尝试使用 PicoCLI 实现以下目标:

  • 选项 0(帮助,详细)
  • 选项 A
    • 从属选项 A-1
    • 从属选项 A-2
    • 从属选项 A-3
  • 选项 B
    • 需要选项 A
    • 但不允许任何选项 A-*

我不知道我是否可以使用 PicoCLI 工具进行此设置,或者我是否只是在使用自定义代码解析后进行检查。

对于这种状态,选项 A 位于需要选项 A 的 ArgGroup 中,但不需要选项 A-*。 选项 B 位于不同的 ArgGroup 中。我试图设置一些独占的东西,但我不知道如何让 ArgGroup/Exclusive 的东西按预期工作......

有什么提示吗?

【问题讨论】:

  • 所以,澄清一下,-A1 需要 -A允许(但不要求)-A2-A3 .同样,-A2需要-A,并且允许(但不要求)-A1-A3-A 选项允许但不需要 -A1-A2-A3 选项。对吗?
  • 是的,你明白了;)

标签: java picocli


【解决方案1】:

总结这些选项需要具备的关系:

  1. -B-A1-A2-A3 所有需要-A 选项
  2. -B 不允许任何 -A1-A2-A3 选项
  3. -A1-A2-A3 选项相互允许
  4. -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(" "));
    }
}

【讨论】:

    猜你喜欢
    • 2020-09-09
    • 2017-04-12
    • 2012-03-20
    • 2021-03-16
    • 1970-01-01
    • 2015-02-09
    • 2019-04-20
    • 2015-09-21
    • 1970-01-01
    相关资源
    最近更新 更多