Я подозреваю, что вы используете старую версию библиотеки.Метод execute(String []) : int
был введен в picocli 4.0.
Обновление и использование метода execute
вместо метода parseArgs
позволит вам удалить много стандартного кода из приложения: обработка запросов на использование / справку по версии и решениес неверным вводом выполняется автоматически методом execute
.
Ваши команды должны реализовывать Runnable или Callable, и именно здесь живет бизнес-логика каждой команды.
Изменение вашего примера и присвоение ему подкоманды :
@Command(name = "parse", sortOptions = false,
mixinStandardHelpOptions = true, version = “1.0”,
description = "parse input files and write to database",
subcommands = MySubcommand.class)
class CommandLineArgumentParser implements Callable<Integer> {
@Option(names = { "-s", "--startDate"}, description = "First day at which to parse data",
converter = GermanDateConverter.class, paramLabel = "dd.MM.yyyy")
public LocalDate start;
@Option(names = { "-e", "--endDate"}, description = "Last day (inclusive) at which to stop parsing",
converter = GermanDateConverter.class, paramLabel = "dd.MM.yyyy")
public LocalDate end;
private static class GermanDateConverter implements ITypeConverter<LocalDate> {
@Override
public LocalDate convert(String value) throws Exception {
LocalDate result = null;
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy");
result = LocalDate.parse(value, formatter);
if (result.getYear() < 1900) {
throw new IllegalArgumentException("year should be after 1900");
}
return result;
}
}
@Override
public Integer call() {
if (start == null) {
log.warn("no start date specified, using: 01.01.2005");
start = LocalDate.of(2005, 01, 01);
}
if (end == null) {
LocalDate timePoint = LocalDate.now();
log.warn("no end date specified, using today: " + timePoint.toString());
end = timePoint;
}
// more business logic here ...
// add finally return an exit code
int exitCode = ok ? 0 : 1;
return exitCode;
}
}
@Command(name = "foo")
class MySubcommand implements Callable<Integer> {
@Override
public Integer call() {
System.out.println("hi");
return 0;
}
}
@SpringBootApplication
public class Application implements CommandLineRunner {
public void run(String... args) throws Exception {
int exitCode = new CommandLine(
CommandLineArgumentParser.class,
new picocli.spring.PicocliSpringFactory())
.execute(args);
System.exit(exitCode);
}
}
Обратите внимание, что при использовании Spring в сочетании с подкомандами picocli вам необходимо вызвать конструктор CommandLine
с picocli.spring.PicocliSpringFactory
.
Для более полного примера Spring см. picocli-spring-boot-starter README.