使用帮助参数时覆盖 required() 参数

mor*_*iel 5 java command-line-interface apache-commons apache-commons-cli

我通过以下方式添加解析器选项:

options = new Options()
                .addOption(Option.builder(CONFIG_PARAM)
                        .required()
                        .hasArg(true)
                        .argName(CONFIG_PARAM_NAME + "_path")
                        .desc(CONFIG_PARAM_DESC)
                        .longOpt(CONFIG_PARAM_NAME)
                        .build())
                (...)
                .addOption(Option.builder(HELP_PARAM)
                        .hasArg(false)
                        .longOpt(HELP_PARAM_NAME)
                        .desc(HELP_PARAM_DESC)
                        .build());
Run Code Online (Sandbox Code Playgroud)

现在,我想允许用户仅使用帮助命令,例如。

mypreciousapp --help
Run Code Online (Sandbox Code Playgroud)

使用上述解决方案,这是不可能的 - 我收到有关缺少所需参数的信息

Missing required options: c
Run Code Online (Sandbox Code Playgroud)

有什么方法可以标记帮助参数,以便它可以覆盖所需的参数,并允许单独使用它?我可以手动执行此操作,但首先我想知道 CLI 库中是否有这样的选项。

cen*_*tic 1

目前似乎 commons-cli 不支持这一点,所以我将创建一个不需要参数的第二个选项对象,并在进行完整解析之前首先解析/检查它,如下所示:

public static void main(String[] args) {
    // define the options with required arguments as needed
    Options opts = new Options()
            .addOption(Option.builder("p")
                    .required()
                    .hasArg(true)
                    .argName("arg")
                    .desc("description  ")
                    .longOpt("param")
                    .build())
            .addOption(Option.builder("h")
                    .hasArg(false)
                    .longOpt("help")
                    .desc("help description")
                    .build());

    // first check if usage-output was requested
    if (handleHelp(args, opts)) {
        return;
    }

    // now handle the full options
    CommandLineParser parser = new DefaultParser();
    final CommandLine cmdLine;
    try {
        cmdLine = parser.parse(opts, args);
    } catch (ParseException ex) {
        System.out.println("Syntax error: " + ex.getMessage());

        printHelp(opts);

        return;
    }

    // now handle options and do your work
}

private boolean handleHelp(String[] args, Options opts) {
    Options helpOpts = new Options()
            .addOption(Option.builder("p")
                    //.required()
                    .hasArg(true)
                    .argName("arg")
                    .desc("description  ")
                    .longOpt("param")
                    .build())
            .addOption(Option.builder("h")
                    .hasArg(false)
                    .longOpt("help")
                    .desc("help description")
                    .build());

    CommandLineParser helpParser = new DefaultParser();
    final CommandLine cmdLine;
    try {
        cmdLine = helpParser.parse(helpOpts, args);
    } catch (ParseException ex) {
        System.out.println("Syntax error: " + ex.getMessage());

        printHelp(opts);

        return true;
    }

    if(cmdLine.hasOption("h")) {
        printHelp(opts);

        return true;
    }

    return false;
}

private void printHelp(Options opts) {
    try (PrintWriter pw = new PrintWriter(System.out)) {
        HelpFormatter formatter = new HelpFormatter();

        formatter.printHelp(pw, 80, "myapp", "test-header", opts,
                formatter.getLeftPadding(), formatter.getDescPadding(), "test-footer", true);
    }
}
Run Code Online (Sandbox Code Playgroud)