Picocli:如何在父命令和子命令之间共享选项

Rem*_*pma 2 shell command-line command picocli

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

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

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

(另请参阅https://github.com/remkop/picocli/issues/580

Rem*_*pma 7

更新:使用 picocli 4.3 有两种方法可以实现此目的:


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

class Shared {
    @Option(names = "--stacktrace")
    static boolean stacktrace;
}
Run Code Online (Sandbox Code Playgroud)

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

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

    // ...
}

@Command(name = "subcommand1")
class Subcommand1 {
    @Mixin
    Shared shared = new Shared();

    // ...
}
Run Code Online (Sandbox Code Playgroud)

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

public static void main(String... args) {
    assert Shared.stacktrace == false;

    MyCommand myCommand = new MyCommand();
    CommandLine.parseArgs(myCommand, "subcommand1", "--stacktrace");

    assert Shared.stacktrace == true;
}
Run Code Online (Sandbox Code Playgroud)