解析多个 picocli(子)命令和 shell

Jan*_*sen 2 java picocli

如何构建一个Spring Boot 2.3多命令 CLI 应用程序,该应用程序可以使用单个命令、@script 并在picocli中交互运行?它的行为应该像这样:

manager -u <user> -p <pass> [list|create|delete] # run and exit
manager -u <user> -p <pass> @script              # run and exit
manager -u <user> -p <pass>                      # run shell
Run Code Online (Sandbox Code Playgroud)

需要用户名-u和密码,三个命令( 、和)各有不同的选项和参数。-plistcreatedelete

Jan*_*sen 5

Spring Boot 应用程序很简单:

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        System.exit(SpringApplication.exit(
            SpringApplication.run(Application.class, args))
        );
    }

}
Run Code Online (Sandbox Code Playgroud)

具有返回值的Spring BootCommandLineRunner也很简单,调用picocliCommandLine来解析和执行命令:

@Component
public class ApplicationRunner implements CommandLineRunner, ExitCodeGenerator {
    private int exitCode;

    @Override
    public void run(String... args) throws Exception {
        exitCode = new CommandLine(new ConnectCommand()).execute(args);
    }

    @Override
    public int getExitCode() {
        return exitCode;
    }

}
Run Code Online (Sandbox Code Playgroud)

它启用picocli的 @-file 支持,并使用“标准”选项ConnectCommand(、等)启用帮助和版本信息:showAtFileInUsageHelp = truemixinStandardHelpOptions-h--help

@Command(
    name = "manager",
    description = "The manager description",
    showAtFileInUsageHelp = true,
    mixinStandardHelpOptions = true,
    subcommands = {
        ListCommand.class,
        CreateCommand.class,
        DeleteCommand.class
    })
@Component 
public class ConnectCommand implements Runnable, ExitCodeGenerator {
    @Option(
        names        = {"-u", "--username"},
        description  = "The username")
    private String username;

    @Option(
        names        = {"-p", "--password"},
        description  = "The password")
    private String password;

    private int exitCode;

    @Override
    public void run() {
        // WIP: kick-off shell
    }

    @Override
    public int getExitCode() {
        return exitCode;
    }

}
Run Code Online (Sandbox Code Playgroud)

并且(子)命令都采用这种形式(根据需要撒入picocli@Option) :@Parameters

@Command(
    name = "list",
    mixinStandardHelpOptions = true,
    header = "list stuff")
@Component
class ListCommand implements Runnable{
    @Override
    public void run() {
        System.out.println("listing...");
    }

}
Run Code Online (Sandbox Code Playgroud)

这样,帮助现在看起来像:

Usage: manager [-hV] [-u=username] [-p=password] [@<filename>...] [COMMAND]
The manager description
      [@<filename>...]    One or more argument files containing options.
  -u, --username=name     The username
  -p, --password=pass     The password
  -h, --help              Show this help message and exit.
  -V, --version           Print version information and exit.
Commands:
  list    list stuff
  create  create stuff
  delete  delete stuff
Run Code Online (Sandbox Code Playgroud)

运行单个命令即可:

java -jar manager.jar -u=myname -p=mypass list
listing...
Run Code Online (Sandbox Code Playgroud)

运行包含“list”的@文件也可以:

java -jar manager.jar -u=myname -p=mypass @listing
listing...
Run Code Online (Sandbox Code Playgroud)

这是一个示例存储库。现在我们需要折叠外壳......