Как я могу обработать ошибки в picocli?
Я пытаюсь реализовать свой собственный 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)
1 ответ
Игнорирование ошибок синтаксического анализа является необычным, но может быть полезно при создании вашей собственной интерактивной консоли CLI, в отличие от одной команды. Мой ответ предполагает, что это то, что вы имеете в виду.
Одна идея состоит в том, чтобы использовать parseArgs
метод вместо populateCommand
метод. Этот метод возвращает 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-jline2 и picocli-shell-jline3, которые имеют PicocliJLineCompleter
который показывает контекстно-зависимые кандидаты на завершение для команд picocli. (В файле readme каждого модуля есть пример.) Приложения, использующие picocli для определения своих команд, больше не нуждаются в ручном кодировании Completers для своих команд и опций. (Ранняя версия этого используется в CLI Micronaut.)