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

查看:81
本文介绍了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();
    }

编辑:事实证明,这种方法类似于此处提供的答案:

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天全站免登陆