做黄页网站要告我,wordpress pdo mysql扩展,信用公示信息系统(全国),wordpress really staticcommons cli最初于2002年发布的Apache Commons CLI可能是使用最广泛的Java命令行解析器#xff0c;但是它的API显示了它的年龄。 寻找具有最少样板代码的现代方法的应用可能对picocli感兴趣。 为什么要花麻烦的钱进行迁移#xff0c;以及如何将基于Commons CLI的应用程序迁移… commons cli 最初于2002年发布的Apache Commons CLI可能是使用最广泛的Java命令行解析器但是它的API显示了它的年龄。 寻找具有最少样板代码的现代方法的应用可能对picocli感兴趣。 为什么要花麻烦的钱进行迁移以及如何将基于Commons CLI的应用程序迁移到picocli Picocli提供了一种流畅的API具有强大的输入功能ANSI颜色的使用帮助自动补全功能以及许多其他功能。 让我们以Checkstyle为例。 为什么要迁移 从Commons CLI迁移到picocli是否值得解决 从一个命令行解析器转到另一个命令行解析器有什么好处 这不仅仅是重新装修我们应用程序的客厅吗 最终用户体验 对最终用户有什么好处 命令行完成 。 基于Picocli的应用程序可以在bash和zsh shell以及基于JLine的交互式shell应用程序中具有命令行完成功能 。 漂亮的易读的用法帮助消息。 Commons CLI生成的使用帮助有点简单。 picocli开箱即用地生成帮助该帮助使用ANSI样式和颜色进行对比以强调命令选项和参数等重要信息。 使用注释可以轻松自定义帮助消息的布局。 此外如果您需要其他帮助还有一个帮助API。 有关一些示例屏幕截图请参见picocli 自述文件 。 通过 -files或“ argument files”支持非常大的命令行 。 有时用户需要指定比操作系统或外壳程序支持的命令行更长的命令行。 当picocli遇到以字符开头的参数时它将文件的内容扩展到参数列表中。 这允许应用程序处理任意长度的命令行。 开发人员经验 作为开发人员对您有什么好处 通常picocli应用程序的代码要比Commons CLI的代码少得多。 picocli批注允许应用程序以声明性的方式定义选项和位置参数所有信息都放在一个位置。 此外picocli还提供了许多便利例如类型转换和自动帮助这些便利照顾了一些机制因此应用程序可以将更多精力放在业务逻辑上。 本文的其余部分将更详细地说明这一点。 文档 picocli具有广泛的用户手册和详细的javadoc 。 故障排除 。 Picocli具有内置的跟踪工具以方便进行故障排除。 最终用户可以使用系统属性picocli.trace来控制跟踪级别。 支持的级别为OFF WARN INFO和DEBUG 。 默认跟踪级别为WARN 。 未来扩展 最后除了立即获得回报之外从Commons CLI迁移到picocli还可以获得任何未来的好处吗 Picocli具有许多高级功能 。 您的应用程序可能尚未使用这些功能但是如果您想将来扩展应用程序picocli支持嵌套子命令 以及子子命令到任何深度可重复使用的mixins 可轻松与 Dependency Injection容器集成以及一个不断发展的工具框架可从picocli CommandSpec模型生成源代码文档和配置文件。 最终picocli得到了积极维护 而Commons CLI似乎在16年内发布了6个版本几乎处于停滞状态。 迁移示例CheckStyle 命令行应用程序需要做三件事 定义支持的选项 解析命令行参数 处理结果 让我们以CheckStyle的com.puppycrawl.tools.checkstyle.Main命令行实用程序为例比较在Commons CLI和picocli中如何完成此操作。 完整的源代码之前和之后的迁移是在GitHub上。 定义选项和位置参数 使用Commons CLI定义选项 Commons CLI有多种定义选项的方式 Options.addOption 构造一个new Options(…)并在此对象不建议使用的OptionBuilder类和推荐的Option.Builder类上调用方法。 Checkstyle Main类使用Options.addOption方法。 首先为选项名称定义一些常量 /** Name for the option s. */
private static final String OPTION_S_NAME s;/** Name for the option t. */
private static final String OPTION_T_NAME t;/** Name for the option --tree. */
private static final String OPTION_TREE_NAME tree;... // and more. Checkstyle Main has 26 options in total. Main.buildOptions方法使用以下常量来构造和返回Commons CLI Options对象该对象定义了受支持的选项 private static Options buildOptions() {final Options options new Options();options.addOption(OPTION_C_NAME, true, Sets the check configuration file to use.);options.addOption(OPTION_O_NAME, true, Sets the output file. Defaults to stdout);...options.addOption(OPTION_V_NAME, false, Print product version and exit);options.addOption(OPTION_T_NAME, OPTION_TREE_NAME, false,Print Abstract Syntax Tree(AST) of the file);...return options;
}使用Picocli定义选项 在picocli中您可以使用类似于Commons CLI方法的构建器以编程方式定义支持的选项也可以使用注释以声明方式定义支持的选项。 对于并非事先知道所有选项的动态应用程序Picocli的编程API可能会有用。 如果您对编程方法感兴趣请查看CommandSpec OptionSpec和PositionalParamSpec类。 另请参阅Programmatic API 。 在本文中我们将使用picocli批注。 对于CheckStyle示例这看起来类似于以下内容 Option(names -c, description Sets the check configuration file to use.)
private File configurationFile;Option(names -o, description Sets the output file. Defaults to stdout)
private File outputFile;Option(names -v, versionHelp true, description Print product version and exit)
private boolean versionHelpRequested;Option(names {-t, --tree}, description Print Abstract Syntax Tree(AST) of the file)
private boolean printAST;比较方式 陈述式 使用Commons CLI您可以通过调用具有String值的方法来构建规范。 此类API的一个缺点是良好的样式会迫使客户端代码定义常量以避免“神奇的值”就像Checkstyle Main类尽职尽责地那样。 使用picocli所有信息都集中在一个地方。 注释仅接受String文字因此定义和用法会自动放在一起而无需声明常量。 这样可以使代码更简洁更少。 强类型 Commons CLI使用布尔标志来表示该选项是否带有参数。 Picocli使您可以直接使用类型。 根据类型picocli“知道”该选项需要多少个参数 boolean字段没有参数 Collection Map和array字段可以有零个到任意数量的参数任何其他类型意味着这些选项只需要一个参数论据。 可以对其进行自定义请参阅arity 但是大多数情况下默认值就足够了。 Picocli鼓励您将enum类型用于带有有限有效值集的选项或位置参数。 picocli不仅会为您验证输入还可以使用Option(description Valid values: ${COMPLETION-CANDIDATES})在使用帮助消息中显示所有值 。 枚举还允许命令行补全功能为选项值建议补全候选值。 更少的代码 Picocli 将选项参数String值转换为字段类型。 它不仅可以节省应用程序的工作量而且还可以对用户输入进行最小程度的验证。 如果转换失败则会引发ParameterException并显示用户友好的错误消息。 让我们看一个例子看看这有多有用。 Checkstyle Main类定义了-x --exclude-regexp exclude --exclude-regexp选项该选项允许用于指定要排除的目录的多个正则表达式。 使用Commons CLI您需要将在命令行上匹配的String值转换为应用程序java.util.regex.Pattern对象 /*** Gets the list of exclusions from the parse results.* param commandLine object representing the result of parsing the command line* return List of exclusion patterns.*/
private static ListPattern getExclusions(CommandLine commandLine) {final ListPattern result new ArrayList();if (commandLine.hasOption(OPTION_X_NAME)) {for (String value : commandLine.getOptionValues(OPTION_X_NAME)) {result.add(Pattern.compile(value));}}return result;
} 根据合同在picocli中您只需在ListPattern 或Pattern[]数组字段上声明该选项。 由于picocli具有java.util.regex.Pattern的内置转换器因此只需声明该选项即可。 转换代码完全消失了。 如果在命令行上指定了一个或多个-x选项Picocli将实例化并填充列表。 /** Option that allows users to specify a regex of paths to exclude. */
Option(names {-x, --exclude-regexp},description Regular expression of directory to exclude from CheckStyle)
private ListPattern excludeRegex;选项名称 Commons CLI支持“短”和“长”选项例如-t和--tree 。 这并不总是您想要的。 Picocli允许一个选项具有任意数量的名称和前缀。 例如这在picocli中会很好 Option(names {-cp, -classpath, --class-path})位置参数 在Commons CLI中您无法预先定义位置参数。 相反其CommandLine解析结果类具有方法getArgs 该方法将位置参数作为String数组返回。 Checkstyle Main类使用它来创建要处理的File对象的列表。 在picocli中 位置参数是一等公民例如命名选项。 不仅可以强类型化它们而且位于不同位置的参数可以具有不同的类型并且每个参数将在用法帮助消息中列出单独的条目和描述。 例如Checkstyle Main类需要处理的文件列表因此我们声明一个字段并使用Parameters对其进行Parameters 。 arity 1..*属性意味着必须至少指定一个文件否则picocli将显示有关缺少参数的错误消息。 Parameters(paramLabel file, arity 1..*, description The files to process)
private ListFile filesToProcess;帮助选项 在Commons CLI中用必需的选项创建一个具有--help选项的应用程序是非常困难的。 Commons CLI对帮助选项没有特殊处理当用户指定command --help时它将抱怨缺少必需的选项。 Picocli具有对常见和自定义 帮助选项的内置支持。 解析命令行参数 Commons CLI具有一个CommandLineParser接口该接口带有parse方法该方法返回代表解析结果的CommandLine 。 然后应用程序调用CommandLine.hasOption(String)来查看是否设置了标志或者调用CommandLine.hasOption(String) CommandLine.getOptionValue(String)来获取选项值。 Picocli在解析命令行参数时填充带注释的字段。 Picocli的parse…方法也返回ParseResult可以上指定的选项并且什么的价值他们有但大多数应用程序实际上并不需要使用查询ParseResult类因为它们可以简单地检查该注入的注释值解析期间的字段。 处理结果 经营理念上白色隔离 解析器完成后应用程序需要运行其业务逻辑但是首先要检查一些事情 是否需要版本信息或使用帮助 如果是这样请打印出所需的信息并退出。 用户输入是否无效 打印出一条包含详细信息的错误消息打印使用帮助消息并退出。 最终运行业务逻辑–处理业务逻辑引发的错误。 使用Commons CLI这看起来像这样 int exitStatus;
try {CommandLine commandLine new DefaultParser().parse(buildOptions(), args);if (commandLine.hasOption(OPTION_VERSION)) { // --versionSystem.out.println(Checkstyle version: version());exitStatus 0;} else if (commandLine.hasOption(OPTION_HELP)) { // --helpprintUsage(System.out);exitStatus 0;} else {exitStatus runBusinessLogic(); // business logic}
} catch (ParseException pex) { // invalid inputexitStatus EXIT_WITH_CLI_VIOLATION;System.err.println(pex.getMessage());printUsage(System.err);
} catch (CheckstyleException ex) { // business logic exceptionexitStatus EXIT_WITH_CHECKSTYLE_EXCEPTION_CODE;ex.printStackTrace();
}
System.exit(exitStatus); Picocli提供了一些方便的方法来解决以上大部分问题。 通过使您的命令实现Runnable或Callable 应用程序可以专注于业务逻辑。 最简单地说它可能看起来像这样 public class Main implements CallableInteger {public static void main(String[] args) {CommandLine.call(new Main(), args);}public Integer call() throws CheckstyleException {// business logic here}
} Checkstyle Main类需要控制退出代码并且对错误处理有一些严格的内部要求因此我们最终没有使用便捷方法并且使解析结果处理与Commons CLI极为相似。 在picocli待办事项清单上可以改善这个领域。 使用帮助信息 Picocli在支持的平台上的使用帮助消息中使用ANSI颜色和样式。 这不仅看起来不错而且还减轻了用户的认知负担 对比度使重要的信息如命令选项和参数从周围的文本中脱颖而出。 应用程序还可以在使用帮助消息的描述或其他部分中使用带有简单标记的ANSI颜色和样式例如|bg(red) text with red background| 。 请参阅用户手册的相关部分 。 对于CheckStyle我们将其保持在最低限度而CheckStyle的结果输出如下所示 总结最后的提示 请注意即使使用帮助消息仅显示带有双连字符的选项Commons CLI的默认解析器也可以识别单连字符 - 和双连字符 -- 长选项。 您需要确定是否继续支持此操作。 在picocli中Option(names -xxx, hidden true)如果您想模仿与Commons CLI完全相同的行为则可以使用Option(names -xxx, hidden true)声明带有单个连字符的长选项用法中未显示 picocli 中的隐藏选项帮助信息。 结论 从Commons CLI迁移到picocli可以为最终用户提供更好的用户体验并且可以为开发人员带来显着的好处即提高其可维护性和未来扩展的潜力。 迁移是手动过程但相对简单。 更新CheckStyle项目接受了本文中所做更改的请求请求。 从CheckStyle 8.15开始其命令行工具将使用picocli。 CheckStyle维护人员对结果感到满意 Checkstyle从Apache CLI迁移到picocli将在8.15中发布最后CLI参数的文档现在已经以声明性的方式在代码中井井有条地组织起来而Checkstyle的CLI遵循CLI最佳实践。 — CheckStyle维护者Roman Ivanov 翻译自: https://www.javacodegeeks.com/2018/11/migrating-commons-cli-picocli.htmlcommons cli