picocli示例,显示了多个命令的用法

时间:2019-09-27 11:35:16

标签: picocli

ive提供了一些与picocli一起很好地工作的代码:

 @Command(name = "parse", sortOptions = false, description = "parse input files and write to database")
class CommandLineArgumentParser {


@Option(names = { "-h", "--help" }, usageHelp = true, description = "display this message")
private boolean helpRequested = false;


@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;
    }
}


@SpringBootApplication
public class Application implements CommandLineRunner {

public void run(String... args) throws Exception {
    CommandLineArgumentParser commandlineparser = new CommandLineArgumentParser();

    CommandLine commandLine = new CommandLine(commandlineparser);
    try {
        commandLine.parseArgs(args);

    } catch (MissingParameterException e) {
        System.out.println(e);
        System.out.println();
        CommandLine.usage(CommandLineArgumentParser.class, System.out);
        System.exit(1);
    } catch (ParameterException e) {
        System.out.println(e);
        System.out.println();
        CommandLine.usage(CommandLineArgumentParser.class, System.out);
        System.exit(1);
    }

    if (commandLine.isUsageHelpRequested()) {
        commandLine.usage(System.out);
        return;
    } else if (commandLine.isVersionHelpRequested()) {
        commandLine.printVersionHelp(System.out);
        return;
    }

    if (commandlineparser.start == null) {
        log.warn("no start date specified, using: 01.01.2005");
        commandlineparser.start = LocalDate.of(2005, 01, 01);
    }

    if (commandlineparser.end == null) {
        LocalDate timePoint = LocalDate.now();
        log.warn("no end date specified, using today: " + timePoint.toString());
        commandlineparser.end = timePoint;
    }
}

但是我没有找到一个简单的示例来显示所使用的多个命令,例如这个命令:
https://github.com/remkop/picocli/blob/master/src/test/java/picocli/Demo.java

无法编译:

int exitCode = new CommandLine(new Demo()).execute(args);

The method execute(CommandLine, List<Object>) in the type CommandLine is not applicable for the    arguments (String[])

有人可以举一个例子说明如何使用多个命令吗?

1 个答案:

答案 0 :(得分:0)

我怀疑您正在使用旧版图书馆。 execute(String []) : int方法是在picocli 4.0中引入的。

升级并使用execute方法而不是parseArgs方法将使您从应用程序中删除大量样板代码:完成了对使用/版本帮助的请求并处理了无效的输入execute方法自动执行。

您的命令应实现Runnable或Callable,这是每个命令的业务逻辑所在的地方。

修改示例并给其一个subcommand

@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自述文件。