【问题标题】:picocli : parse arguments without boiler platepicocli : 解析没有样板的参数
【发布时间】:2020-05-22 00:09:27
【问题描述】:

我通常将所有命令行选项存储到不同的类中,例如 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 类在技术上不应实现 CallableRunnable。我可以使 MyApp 成为 CallableRunnable。但是对于 CommandLinenew 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 中拥有执行控制权?

我确定我错过了一些直接的东西。

【问题讨论】:

    标签: picocli


    【解决方案1】:

    实现这一点的最简单方法是在MyApp 中将CliArguments 设为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 mixin 中定义的选项成为MyApp mixee 的一部分。 此外,CliArgs 中定义的任何@Command 属性都将成为MyApp 命令的一部分。

    你现在可以运行了:

    java MyApp -x
    

    这将打印出来

    -x=true
    -y=false
    

    由于 mixin 有 @Command(mixinStandardHelpOptions = true)MyApp 命令也有 --help--version 选项,它们可以正常工作。

    【讨论】:

    • 谢谢,@Mixin 是我想念的东西。顺便说一句,github 示例 CommandWithMixin.java 丢失了。
    • 感谢您的确认。 GitHub 示例缺少什么?我可以看到mixin类CommonOption.java,还是不是你的意思?
    • Github 在 CommandWithMixin.java 文件中出现服务器错误。现在我可以看到它。没有问题。谢谢,阿吉安。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多