picocli:在不使用样板的情况下解析参数

时间:2020-05-22 00:09:27

标签: picocli

我通常将所有命令行选项存储在不同的类中,例如 CliArguments 。这样可以避免在主类中产生噪音。这就是我对 picocli 的看法:

public final class MyApp {

    private static final CliArguments cliArgs = new CliArguments();

    private MyApp() {}

    public static void main (String[] args) {
      if (parseArgs (args)) {
         new MyApp().execute();
      }
    }

    /* want to avoid this boiler plate */
    private static boolean parseArgs(String[] args) {
      CommandLine cmd = new CommandLine ( cliArgs );
      try {
        cmd.parseArgs( args );
        if (cmd.isUsageHelpRequested()) {
          cmd.usage( cmd.getOut() );
          return false;
        }
        else if ( cmd.isVersionHelpRequested() ) {
          cmd.printVersionHelp (cmd.getOut());
          return false;
        }
        logger.info("{}", cliArgs);
        return true;
     }
     catch ( ParameterException ex ) {
       logger.error ("Failure to parse : {}", ex);
       return false;
     }
   }

   private void execute() {
     // execution logic
   }
}

如何避免使用样板方法pargeArgs(String[])?从技术上讲, CliArguments 类不应实现 Callable Runnable 。我可以将 MyApp 设置为 Callable Runnable 。但是对于 CommandLine ,不是 new MyApp()命令,是 new CliArguments()

如果我想做这样的事情:

   final int exitCode = new CommandLine(new MyApp()).execute(args);
   if (0 != exitCode) {
     logger.error("Failed to parse");
     System.exit(exitCode);
   }

如何将所有@Option规范推到另一个类 CliArguments ,同时仍在 MyApp 中保留执行控制权?

我确定我会直接丢失一些东西。

1 个答案:

答案 0 :(得分:1)

最简单的方法是在CliArguments中将MyApp设为mixin。然后,我们可以将业务逻辑放入MyApp中,并将其设为RunnableCallable,以便我们可以使用new CommandLine(new MyApp()).execute(args)引导应用程序。

例如:

@Command(mixinStandardHelpOptions = true, version = "1.0.0")
public class CliArgs {
    @Option(names = "-x") boolean x;
    @Option(names = "-y") boolean y;
}

@Command(name = "myapp", description = "...")
public class MyApp implements Runnable {

    // options defined in the mixin are added to this command
    // also, @Command attributes from the mixin are applied to this command
    @Mixin
    CliArgs cliArgs;

    public void run() {
        System.out.printf("-x=%s%n", cliArgs.x);
        System.out.printf("-y=%s%n", cliArgs.y);
    }

    public void main(String... args) {
        System.exit(new CommandLine(new MyApp()).execute(args));
    }
}

CliArgs混合中定义的选项成为MyApp混合对象的一部分。 另外,在@Command中定义的所有CliArgs属性都将成为MyApp命令的一部分。

您现在可以运行:

java MyApp -x

这将打印

-x=true
-y=false

由于mixin具有@Command(mixinStandardHelpOptions = true),因此MyApp命令还具有--help--version选项,它们可以按您期望的方式工作。

相关问题