0

我对 Apache commons-cli v1.3 有点苦恼,但我还没有找到解决以下问题的实用解决方案:

我有一个命令行工具 - 根据指定的参数 - 创建一个字符串(或从本地文件中读取它),可能对其进行内联编辑,并可选择显示、将所述字符串写入本地文件或通过 HTTP 请求发送它到服务器。

所以我有选项“c”代表“create”,“r”代表“read”,“e”代表“edit”(通过 cli),“d”代表显示,“w”代表“write”,以及“ p”代表“推送到服务器”

显然,一些组合是可能的。例如,应该可以创建此字符串并推送它,而无需从文件读取或写入它。此外,应该可以在不推送的情况下创建和编写,等等......

所以参数的语义是:

("c" OR ("r" ["e"])) ["d" "w" "p"]

显然,当 String 被“c”读取时,它一定不能被“r”读取。当“c”reating 时,我会使用来自 cli-parser 的交互式输入。当“r”阅读时,我想允许用户通过 cli 的交互式输入“e”dit。其余参数是可选的。

下一个:“r”阅读时,需要指定文件名/路径。此外,在“写作”时,这是必要的。无论如何,应该可以指定要读取的文件和要写入的第二个文件。所以文件名会有两个参数,它们都是可选的。

生成的语法如下所示:

tool -cp
tool -rp "filenametoread"
tool -rdwp "filenametoread" "filenametowrite"
tool -cw "filenametowrite"

等等。

我在这里有点迷路了。如何将 commons-cli 配置为具有两个文件名参数,根据指定的参数(选项)需要这些参数?这甚至可能吗?

4

2 回答 2

2

不幸的是,Commons CLI 无法指定这样的相互依赖的选项。要处理这个问题,您需要自己if进行检查。例如,像这样

CommandLineParser parser = new PosixParser();
Options options = new Options();
options.addOption(new Option("h", "help", false, "display this message"));
options.addOption(new Option("c", "create", true, "Create a file"));
options.addOption(new Option("r", "read", truee, "Read a file"));
options.addOption(new Option("e", "edit", false, "Edit a file"));
options.addOption(new Option("d", "display", false, "Display a file"));
options.addOption(new Option("w", "write", false, "Write a file"));
options.addOption(new Option("p", "push", false, "Push a file"));

try {
    CommandLine commandLine = parser.parse(options, args);
    if (commandLine.hasOption("h")) {
        showHelp(options);
        System.exit(0);
    }
    // validate the commandline
    // obviously, these can be split up to give more helpful error messages
    if ((!(commandLine.hasOption("c") ^ (commandLine.hasOption("r") || commandLine.hasOption("e"))))
        || !(commandLine.hasOption("d") ^ commandLine.hasOption("w") ^ commandLine.hasOption("p"))) {
        throw new ParseException("Invalid combination");
    }
    if ((!commandLine.hasOption("c") && !commandLine.hasOption("r")) {
        throw new ParseException("Missing required arg");
    }

    // rest of the logic
} catch (ParseException pe) {
    throw new ParseException("Bad arguments\n" + pe.getMessage());
}
于 2015-08-09T03:39:48.490 回答
0

commons-cli 库有一个流利的包装器:https ://github.com/bogdanovmn/java-cmdline-app

它有这样的能力:

new CmdLineAppBuilder(args)
  .withArg("integer-opt", "integer option description")
  .withArg("string-opt", "string option description")
  .withFlag("bool-flag", "bool-flag description")

  .withDependencies("bool-flag", "integer-opt", "string-opt")

  .withEntryPoint(cmdLine -> {})
.build().run();

这意味着如果您指定“bool-flag”选项,您还必须指定它的依赖项:“integer-opt”和“string-opt”您不需要在自己的代码中管理它。

于 2020-04-06T12:01:30.233 回答