Масштабируемые приложения с Picocli. Вопрос о лучшей практике

Скажем, мой проект имеет много логики и имеет несколько точек входа, которые являются командами CLI.

Я отмечаю свои точки входа с @Command, инициализируй мой @Parameters а также @Option аннотированные поля и выполняют логику, которая больше не требует CLI.

Как я понимаю, мне было бы целесообразно объявить 1 main метод согласно @Command аннотированный класс, однако, я не уверен, что это хорошая идея.

Может быть какой-то CommandFactory является необходимым?

Я никогда раньше не создавал CLI-приложений и не использовал picocli, поэтому, если мой мыслительный процесс ошибочен, укажите это.

1 ответ

Решение

Это совершенно нормально иметь отдельный main метод для каждого @Command это точка входа. main метод необходим, чтобы команда могла быть вызвана автономно из командной строки.

Например:

@Command(name = "hello")
class Hello implements Runnable {
    public static void main(String[] args) {
        CommandLine.run(new Hello(), args);
    }
    public void run() { System.out.println("hello"); }
}

@Command(name = "bye")
class Bye implements Runnable {
    public static void main(String[] args) {
        CommandLine.run(new Bye(), args);
    }
    public void run() { System.out.println("bye"); }
}

Единственное исключение - когда в вашем приложении есть команды с подкомандами. В этом случае вам нужно будет только иметь main методы для команд верхнего уровня, а не для подкоманд.

Пример с подкомандами:

@Command(name = "git", subcommands = {Commit.class, Status.class})
class Git implements Runnable {
    public static void main(String[] args) { // top-level command needs main
        CommandLine.run(new Git(), args);
    }
    public void run() { System.out.println("Specify a subcommand"); }
}

@Command(name = "commit")
class Commit implements Runnable {
    @Option(names = "-m") String message;
    @Parameters File[] files;

    public void run() {
        System.out.printf("Committing %s with message '%s'%n",
                Arrays.toString(files), message);
    }
}

@Command(name = "status")
class Status implements Runnable {
    public void run() { System.out.println("All ok."); }
}

Обратите внимание, что только команда верхнего уровня нуждается в main метод, когда есть подкоманды. Даже с подкомандами фабрика не нужна.

Другие вопросы по тегам