Apache CLI:必需选项与帮助选项相矛盾. [英] Apache CLI: Required options contradicts with help option.

查看:26
本文介绍了Apache CLI:必需选项与帮助选项相矛盾.的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我根据需要定义了 2 个选项,例如:

If I have 2 options defined as required such as:

 public static void main(String [] args){
      Options options= new Options();
      Option  inputFileOp=Option.builder("i").longOpt("input").hasArg().desc("Input file").argName("file").required().build();
        options.addOption(inputFileOp);

      Option outputFileOp=Option.builder("o").longOpt("output").hasArg().desc("Output file").argName("file").required().build();
        options.addOption(outputFileOp);

和帮助选项

    Option helpOp =new Option("h",false,"Show Help");
    helpOp.setLongOpt("help");
    helpOptions.addOption(helpOp);

和解析器

DefaultParser parser = new DefaultParser();
CommandLine cmd=parser.parse(options,args);

if(cmd.hasOption(helpOp.getOpt())){
        HelpFormatter formatter = new HelpFormatter();
        formatter.printHelp( "MyApp.sh", options );
        System.exit(0);
    }

}

当用户输入例如 myApp -h .. 在解析步骤中引发异常,缺少必需的选项,而我想打印帮助数据.

When the user input for example myApp -h .. An exception is raised in the parsing step that there are missing required options, While I want to print the help data.

如何在保持这些选项按要求声明的同时允许调用帮助?

How to allow calling the help while keeping these options declared as required?

推荐答案

DefaultParser 的代码似乎总是调用 checkRequiredArgs() 方法.这似乎表明您无法一举避免这个问题.

The code for DefaultParser appears to always call the checkRequiredArgs() method. Which seems to indicate that you cannot, in one fell swoop, avoid the problem.

我们过去解决这种情况的方法,也许是一种次优的方式,是对命令行进行两次解析.解析速度很快,因此开销最小.

The way we have addressed this situation in the past, perhaps in a suboptimal fashion, is to parse the command line twice. The parsing is fast, so the overhead it minimal.

我们创建了一个方法 checkForHelp(String[] args) 接受 (String[] args).它将only 帮助选项添加到选项中,解析命令行,然后确定是否指定了帮助.如果是,则打印帮助并退出程序.否则,将处理完整的选项集.这种方法允许按预期处理所需的字段.请注意,帮助选项也必须添加到主列表中.

We created a method checkForHelp(String[] args) that takes the (String[] args). It adds only the help option to an options, parses the command line, and then ascertains whether help is specified. If so, the help is printed, and the program exits. Otherwise, the full set of options is processed. This approach allows for the required fields to be processed as expected. Note that the help option must also be added in the main list.

  public static Option helpOption = Option.builder("h")
          .longOpt("help")
          .required(false)
          .hasArg(false)
          .build();

  public static boolean checkForHelp(String[] args) throws ParseException  { 
    boolean hasHelp = false;

    Options options = new Options();


    try {
      options.addOption(helpOption);

      CommandLineParser parser = new DefaultParser();

      CommandLine cmd = parser.parse(options, args);

      if (cmd.hasOption(helpOption.getOpt())) {
          hasHelp = true;
      }

    }
    catch (ParseException e) {
      throw e;
    }

    return hasHelp;
  }

然后在 main 方法中,类似于:

Then in the main method, something akin to:

    options.addOption(hostOption);
    options.addOption(portOption);
    options.addOption(serviceNameOption);
    options.addOption(helpOption); // <-- must also be here to avoid exception

    try {
        if (checkForHelp(args)) {
            HelpFormatter fmt = new HelpFormatter();
            fmt.printHelp("Help", options);
            return;
        }

        CommandLineParser parser = new DefaultParser();
        CommandLine cmd = parser.parse(options, args);


        if (cmd.hasOption("host")) {
            host = cmd.getOptionValue("host");
            System.out.println(host); // gets in here but prints null
        }
        if (cmd.hasOption("port")) {
            port = ((Number) cmd.getParsedOptionValue("port")).intValue();
            System.out.println(port); // gets in here but throws a null
                                      // pointer exception

        }
        if (cmd.hasOption("service_name")) {
            serviceName = cmd.getOptionValue("service_name");
            System.out.println(serviceName); // gets in here but prints null
        }
    }
    catch (Exception e) {
        e.printStackTrace();
    }

编辑:事实证明,这种方法类似于此处提供的答案:Commons CLI 所需组.我想我感觉更好,因为我们的方法有其他人支持我们的信念.

EDIT: as it turns out, this approach is similar to the answer provided here: Commons CLI required groups. I guess I feel better that our approach has others supporting what we believed.

EDIT2:在快速测试中,我相信通过使用OptionGroup"可以避免具有必需选项的问题.这是修改后的 checkForHelp,它通过将所有选项添加到 OptionGroup 来工作.在我的快速测试中,它避免了存在的问题,例如 ("--arg1 --help").

EDIT2: In a quick test, I believe the problem of having required options may be avoided by using an "OptionGroup". Here is a revised checkForHelp that works by adding all of the options to an OptionGroup. In my quick testing, it avoids the problem that was present if one did, e.g., ("--arg1 --help").

public static boolean checkForHelp(String[] args) throws ParseException
{
    boolean hasHelp = false;

    Options options = new Options();


    try {
        options.addOption(hostOption);  //has required set
        options.addOption(portOption);
        options.addOption(serviceNameOption);
        options.addOption(helpOption);            

        // create an option group
        OptionGroup og = new OptionGroup();
        og.addOption(hostOption);
        og.addOption(portOption);
        og.addOption(serviceNameOption);
        og.addOption(helpOption);

        CommandLineParser parser = new DefaultParser();

        CommandLine cmd = parser.parse(options, args, false);

        if (cmd.hasOption(helpOption.getOpt()) || cmd.hasOption(helpOption.getLongOpt())) {
            hasHelp = true;
        }

    }
    catch (ParseException e) {
        throw e;
    }

    return hasHelp;
}

这篇关于Apache CLI:必需选项与帮助选项相矛盾.的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆