【问题标题】:Picocli: how to share options between parent command and subcommandsPicocli:如何在父命令和子命令之间共享选项
【发布时间】:2019-01-15 22:37:49
【问题描述】:

如何支持所有(或部分)命令和子命令的共享选项?例如,如果最终用户在命令行参数的任何位置提供--stacktrace,则打印的任何错误都将包括堆栈跟踪。

我们可以使用 Mixin 来定义布尔 --stacktrace 选项,并在所有(子)命令中包含此 Mixin,或者使用继承并让所有命令子类化定义布尔 --stacktrace 选项的类,但无论哪种方式,这将为每个命令定义一个单独的布尔选项。哪个选项为真取决于用户将--stacktrace 放在参数中的哪个位置,因此确定是否提供了--stacktrace 意味着遍历所有父命令并查看是否有任何为真。

如果有一种更方便的方法来检测用户是否指定了这样的共享选项,那就太好了。

(另见https://github.com/remkop/picocli/issues/580

【问题讨论】:

    标签: shell command-line command picocli


    【解决方案1】:

    更新:使用 picocli 4.3 有两种方法可以完成此操作:


    实现此目的的一种方法是将布尔字段设为静态:

    class Shared {
        @Option(names = "--stacktrace")
        static boolean stacktrace;
    }
    

    您仍然需要子类化或使用 mixin 在每个命令和子命令中定义此选项:

    @Command(subcommands = {Subcommand1.class, Subcommand2.class /*, ...*/}
    class MyCommand {
        @Mixin
        Shared shared = new Shared();
    
        // ...
    }
    
    @Command(name = "subcommand1")
    class Subcommand1 {
        @Mixin
        Shared shared = new Shared();
    
        // ...
    }
    

    这种设计的好处是现在有一个地方可以让应用程序检测最终用户是否指定了--stacktrace:静态布尔字段:

    public static void main(String... args) {
        assert Shared.stacktrace == false;
    
        MyCommand myCommand = new MyCommand();
        CommandLine.parseArgs(myCommand, "subcommand1", "--stacktrace");
    
        assert Shared.stacktrace == true;
    }
    

    【讨论】:

    • 我在使用它时遇到的两个陷阱:将@Option 添加到静态字段对我不起作用,我需要一个非静态设置方法。此外,当使用您描述的继承时,我无法在 超类 中使用 @Mixin static Foo fooclass Foo { @Option Bar bar },我需要 class Foo { @Option static Bar bar } 来获得所需的行为。
    • 要明确第二个陷阱:class Shared { @Mixin static Foo foo }class Foo { @Option Bar bar }@Command class MyCommand extends Shared {} 不起作用。
    • 我更新了picocli 4.3的答案。
    • 这看起来很棒,尤其是继承的选项!从文档来看,MIXEE 看起来有点混乱,但是一旦我把手弄脏并尝试了它就可以了;)
    猜你喜欢
    • 1970-01-01
    • 2011-07-25
    • 2021-11-19
    • 1970-01-01
    • 2019-10-24
    • 1970-01-01
    • 2018-11-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多