Java: Apache commons-cli 如何处理相互依赖的选项
Java: Apache commons-cli how to handle options that depend on each other
我有点受 Apache commons-cli v1.3 的困扰,我还没有找到解决以下问题的实用方法:
我有一个命令行工具 - 根据指定的参数 - 创建一个字符串(或从本地文件读取它),可能对其进行内联编辑,并可选择显示,将所述字符串写入本地文件或发送它通过对服务器的 HTTP 请求。
所以我有 "c" 用于 "create"、"r" 用于 "read"、"e" 用于 "edit" 的选项(通过 cli) , "d" 用于显示, "w" 用于 "write", "p" 用于 "push to server"
显然有些组合是可能的。例如。应该可以创建此字符串并将其推送而无需读取或写入 from/to 文件。还有,应该可以不用push就可以创建和写入等等...
所以参数的语义是:
("c" OR ("r" ["e"])) ["d" "w" "p"]
显然,当 String "c"reated 时,它一定不能 "r"ead。 "c"吃饭时,我会使用来自 cli-parser 的交互式输入。 "r"阅读时,我希望允许用户通过来自 cli 的交互式输入进行 "e"编辑。其余参数有点可选。
下一个:"r"读时,需要指定一个filename/path。还有,当"w"写的时候,这个是必须的。无论如何,应该可以指定要读取的文件和要写入的第二个文件。所以文件名会有两个参数,它们都是可选的。
生成的语法如下所示:
tool -cp
tool -rp "filenametoread"
tool -rdwp "filenametoread" "filenametowrite"
tool -cw "filenametowrite"
等等。
我有点迷路了。如何将 commons-cli 配置为根据指定的参数(选项)需要两个文件名参数?这甚至可能吗?
不幸的是,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());
}
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"你不需要在你自己的代码中管理它。
我有点受 Apache commons-cli v1.3 的困扰,我还没有找到解决以下问题的实用方法:
我有一个命令行工具 - 根据指定的参数 - 创建一个字符串(或从本地文件读取它),可能对其进行内联编辑,并可选择显示,将所述字符串写入本地文件或发送它通过对服务器的 HTTP 请求。
所以我有 "c" 用于 "create"、"r" 用于 "read"、"e" 用于 "edit" 的选项(通过 cli) , "d" 用于显示, "w" 用于 "write", "p" 用于 "push to server"
显然有些组合是可能的。例如。应该可以创建此字符串并将其推送而无需读取或写入 from/to 文件。还有,应该可以不用push就可以创建和写入等等...
所以参数的语义是:
("c" OR ("r" ["e"])) ["d" "w" "p"]
显然,当 String "c"reated 时,它一定不能 "r"ead。 "c"吃饭时,我会使用来自 cli-parser 的交互式输入。 "r"阅读时,我希望允许用户通过来自 cli 的交互式输入进行 "e"编辑。其余参数有点可选。
下一个:"r"读时,需要指定一个filename/path。还有,当"w"写的时候,这个是必须的。无论如何,应该可以指定要读取的文件和要写入的第二个文件。所以文件名会有两个参数,它们都是可选的。
生成的语法如下所示:
tool -cp
tool -rp "filenametoread"
tool -rdwp "filenametoread" "filenametowrite"
tool -cw "filenametowrite"
等等。
我有点迷路了。如何将 commons-cli 配置为根据指定的参数(选项)需要两个文件名参数?这甚至可能吗?
不幸的是,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());
}
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"你不需要在你自己的代码中管理它。