3

我尝试实现自己的 CLI,并希望使用 picocli 来解析命令的参数。这就是为什么我根本不希望 picocli 在控制台中写入。所以我创建了MyCommand带有一些选项和参数注释的类。现在我希望能够做这样的事情:

val myCommand = CommandLine.populateCommand(MyCommand(), args)
myCommand.execute();
val output = myCommand.getOutput();
val errors: List<String> = myCommand.getErrors();

前三行没有问题,但我不确定如何处理第四行。现在populateCommand只是抛出所有异常,捕获它们不是一种选择,因为抛出的异常将停止我的管道计算。Picocli 文档建议对要存储的异常使用解析器宽松模式ParseResult,但这意味着我必须使用commandLine.parseWithHandlers难以满足我需求的方法。
我错过了什么吗?也许我可以使用populateCommand并将异常存储在某个地方?
这是populateCommand引发的异常之一的堆栈跟踪:

Exception in thread "main" picocli.CommandLine$MissingParameterException: Missing required parameter for option '-A' (<afterContext>)
    at picocli.CommandLine$Interpreter.assertNoMissingParameters(CommandLine.java:8059)
    at picocli.CommandLine$Interpreter.applyOption(CommandLine.java:7534)
    at picocli.CommandLine$Interpreter.processStandaloneOption(CommandLine.java:7446)
    at picocli.CommandLine$Interpreter.processArguments(CommandLine.java:7355)
    at picocli.CommandLine$Interpreter.parse(CommandLine.java:7226)
    at picocli.CommandLine$Interpreter.parse(CommandLine.java:7116)
    at picocli.CommandLine.parse(CommandLine.java:824)
    at picocli.CommandLine.populateCommand(CommandLine.java:777)
4

1 回答 1

1

忽略解析错误是不寻常的,但在创建您自己的交互式CLI 控制台时可能很有用,而不是单个命令。我的回答假设这是您的想法。

一种想法是使用parseArgs方法而不是populateCommand方法。如果您已将解析器配置为宽松,则此方法返回 a ParseResult,您可以从中获取 picocli 在解析过程中遇到的错误。

例如:

val myCommand = MyCommand();
val commandLine = CommandLine(myCommand);

// tell parser to be lenient 
commandLine.getCommandSpec().parser().collectErrors(true);

// parse user input, query result for errors 
val parseResult = commandLine.parseArgs(args); 
val parseErrors: List<Exception> = parseResult.errors();

// ignoring the errors for now...
myCommand.execute();
val output = myCommand.getOutput();
val appErrors: List<String> = myCommand.getErrors();

请注意,如果有任何解析错误,这意味着用户指定的输入无效。因此,您的命令可能未正确初始化。该execute方法需要更加健壮以处理部分初始化的选项/位置参数。

提示:如果您正在创建自己的交互式CLI 控制台(而不是单个命令),您可能对JLine 2(需要 Java 5 或更高版本)或JLine 3(需要 Java 8 或更高版本)感兴趣。Picocli 提供picocli-shell-jline2picocli-shell-jline3模块,这些模块具有PicocliJLineCompleter显示 picocli 命令的上下文相关完成候选者。(每个模块的自述文件都有一个示例。)使用 picocli 定义其命令的应用程序不再需要为其命令和选项手动编码 Completers。( Micronaut CLI中使用了它的早期版本。)

于 2019-02-06T23:24:18.993 回答