Groovy 2.5 CliBuilder更新(第2部分)

Apache Groovy 2.5中更新了用于快速简洁地构建命令行应用程序的CliBuilder类。

这是由两部分组成的系列文章的第二部分,该系列文章重点介绍了新内容。 如果您错过了它, 第1部分在这里。

本文展示了CliBuilder基础库的一些高级功能。

CliBuilder

1部分的快速回顾: groovy.util.CliBuilder类已弃用。 相反,现在在不同的模块中有两种CliBuilder实现,一种以Apache Commons CLI作为底层解析器库,另一种基于picocli解析器。

建议应用程序显式导入groovy.cli.picocli.CliBuildergroovy.cli.commons.CliBuildergroovy.util.CliBuilder类已弃用,并委托Commons CLI版本以实现向后兼容。

新功能可能只会添加到picocli版本中,并且Groovy的未来版本中可能会删除groovy.util.CliBuilder 。 Commons CLI版本适用于依赖CliBuilder Commons CLI实现内部的应用程序,并且无法轻松迁移到picocli版本。

接下来,让我们看一下这些基础命令行解析库提供的一些高级功能。

Apache Commons CLI功能

有时您可能想使用基础解析库的高级功能。 例如,您可能有一个带有互斥选项的命令行应用程序。 以下代码显示了如何使用Apache Commons CLI OptionGroup API实现此目的:

import groovy.cli.commons.CliBuilder
import org.apache.commons.cli.*

def cli = new CliBuilder()
def optionGroup = new OptionGroup()
optionGroup.with {
  addOption cli.option('s', [longOpt: 'silent'], 's option')
  addOption cli.option('v', [longOpt: 'verbose'], 'v option')
}
cli.options.addOptionGroup optionGroup

assert !cli.parse('--silent --verbose'.split()) (1)
  1. 解析此输入将失败,因为指定了两个互斥选项。

Picocli CliBuilder功能

强类型列表

CliBuilder列表

具有多个值的选项通常使用数组或列表来捕获值。 数组可以是强类型的,即包含除String之外的元素。 CliBuilder的picocli版本使您可以对列表执行相同的操作。 auxiliaryType指定元素应转换为的类型。 例如:

import groovy.cli.picocli.CliBuilder

def cli = new CliBuilder()
cli.T(type: List, auxiliaryTypes: Long, 'typed list')  (1)

def options = cli.parse('-T 1 -T 2 -T 3'.split())      (2)
assert options.Ts == [ 1L, 2L, 3L ]                    (3)
  1. 定义一个可以具有多个整数值的选项。
  2. 命令行示例。
  3. 选项值为List<Integer>

强类型地图

picocli版本的CliBuilder为Map选项提供了本机支持。 这就像将Map指定为选项类型一样简单。 默认情况下,键和值都存储为Map中的字符串,但是可以使用auxiliaryType指定键和值应转换为的类型。

import groovy.cli.picocli.CliBuilder

def cli = new CliBuilder()
cli.D(args: 2,   valueSeparator: '=', 'Commons CLI style map')                 (1)
cli.X(type: Map, 'picocli style map support')                                  (2)
cli.Z(type: Map, auxiliaryTypes: [TimeUnit, Integer].toArray(), 'typed map')   (3)

def options = cli.parse('-Da=b -Dc=d -Xx=y -Xi=j -ZDAYS=2 -ZHOURS=23'.split()) (4)
assert options.Ds == ['a', 'b', 'c', 'd']                                      (5)
assert options.Xs == [ 'x':'y', 'i':'j' ]                                      (6)
assert options.Zs == [ (DAYS as TimeUnit):2, (HOURS as TimeUnit):23 ]          (7)
  1. Commons CLI通过指定每个选项必须具有两个参数(带有一些分隔符)来提供类似地图的选项。
  2. picocli版本的CliBuilder具有对Map选项的本地支持。
  3. 可以为强类型映射指定键类型和值类型。
  4. 命令行示例。
  5. Commons CLI样式选项提供[key,value,key,value…]对象的列表。
  6. picocli样式选项将结果作为Map<String, String>
  7. 指定auxiliaryTypes类型后,地图的键和值将转换为指定的类型,从而为您提供Map<TimeUnit, Integer>

详细简介的使用帮助

CliBuilder一直支持usage属性来显示命令的用法帮助简介:

// the old way
new CliBuilder(usage: 'myapp [options]').usage()

上面的程序打印:

Usage: myapp [options]

这仍然有效,但是picocli版本具有更好的name属性替代方案。 如果指定name ,而不是usage ,picocli将显示在方括号简洁提要所有选项[]可选元素和省略号…​对于可以重复一次或多次的元素。 例如:

def cli = new CliBuilder(name: 'myapp') // detailed synopsis
cli.a('option a description')
cli.b('option b description')
cli.c(type: List, 'option c description')
cli.usage()

上面的程序打印:

Usage: myapp [-ab] [-c=PARAM]...
the new way
  -a           option a description
  -b           option b description
  -c= PARAM    option c description

使用任何选项名称

图片来源:(c)PsychoShadow – www.bigstockphoto.com

以前,如果一个选项具有多个名称且带有一个连字符,那么您只能选择多次声明该选项:

// before: split -cp, -classpath into two options
def cli = new CliBuilder(usage: 'groovyConsole [options] [filename]')
cli.classpath('Where to find the class files')
cli.cp(longOpt: 'classpath', 'Aliases for '-classpath')

picocli版本的CliBuilder支持names属性,该属性可以具有可以带有任何前缀的任意数量的选项名称。 例如:

// after: an option can have many names with any prefix
def cli = new CliBuilder(usage: 'groovyConsole [options] [filename]')
cli._(names: ['-cp', '-classpath', '--classpath'], 'Where to find the class files')

细粒度的使用帮助消息

Picocli提供了对使用帮助消息格式的细粒度控制,并且此功能通过usageMessage CliBuilder属性公开。

使用消息有很多部分:标题,大纲,描述,参数,选项以及最后的页脚。 每个部分都有一个标题,该标题位于其部分的第一行之前。 例如:

import groovy.cli.picocli.CliBuilder

def cli = new CliBuilder()
cli.name = "groovy clidemo"
cli.usageMessage.with {                (1)
    headerHeading("Header heading:%n") (2)
    header("header 1", "header 2")     (3)
    synopsisHeading("%nUSAGE: ")
    descriptionHeading("%nDescription heading:%n")
    description("description 1", "description 2")
    optionListHeading("%nOPTIONS:%n")
    footerHeading("%nFooter heading:%n")
    footer("footer 1", "footer 2")
}
cli.a(longOpt: 'aaa', 'a-arg')         (4)
cli.b(longOpt: 'bbb', 'b-arg')
cli.usage()
  1. 使用usageMessage CliBuilder属性自定义使用帮助信息。
  2. 标题可以包含字符串格式说明符,例如%n换行符。
  3. 部分是多行的:每个字符串将在单独的行上呈现。
  4. 定义一些选项。

这将输出以下输出:

Header heading:
header 1
header 2

USAGE: groovy clidemo [-ab]

Description heading:
description 1
description 2

OPTIONS:
  -a, --aaa    a-arg
  -b, --bbb    b-arg

Footer heading:
footer 1
footer 2

ANSI颜色的使用帮助

开箱即用的用法帮助消息中的命令名称,选项名称和参数标签均以ANSI样式和颜色呈现 。 可以使用系统属性配置这些元素的配色方案。

除此之外,您还可以使用简单的标记符号在说明和使用帮助消息的其他部分中使用颜色和样式。 下面的示例演示:

def cli = new groovy.cli.picocli.CliBuilder(name: 'myapp')
cli.usageMessage.with {
    headerHeading("@|bold,red,underline Header heading|@:%n")
    header($/@|bold,green \
  ___ _ _ ___      _ _    _
 / __| (_) _ )_  _(_) |__| |___ _ _
| (__| | | _ \ || | | / _` / -_) '_|
 \___|_|_|___/\_,_|_|_\__,_\___|_|
|@/$)
    synopsisHeading("@|bold,underline Usage|@: ")
    descriptionHeading("%n@|bold,underline Description heading|@:%n")
    description("Description 1", "Description 2")      // after the synopsis
    optionListHeading("%n@|bold,underline Options heading|@:%n")
    footerHeading("%n@|bold,underline Footer heading|@:%n")
    footer($/@|bold,blue \
   ___                         ___   ___
  / __|_ _ ___  _____ ___  _  |_  ) | __|
 | (_ | '_/ _ \/ _ \ V / || |  / / _|__ \
  \___|_| \___/\___/\_/ \_, | /___(_)___/
                        |__/             |@/$)
}
cli.a('option a description')
cli.b('option b description')
cli.c(type: List, 'option c description')
cli.usage()

上面的代码提供以下输出:

CliBuilder

(对于ASCII图片,请登录http://patorjk.com/software/taag/ 。)

新的

错误

当用户提供无效输入时,picocli版本的CliBuilder会向新的errorWriter属性(默认设置为System.err )写入一条错误消息和使用帮助消息。 当用户请求帮助时,应用程序调用CliBuilder.usage() ,用法帮助消息将打印到writer属性(默认为System.out )。

早期版本的CliBuilder使用writer属性来提供无效输入和用户请求的帮助。

为什么要这样改变? 这有助于命令行应用程序作者遵循标准做法,并将诊断输出与程序输出分开:如果将Groovy程序的输出通过管道传输到另一个程序,则将错误消息发送到STDERR可以防止下游程序无意间尝试解析错误输出。 另一方面,当用户通过--help--version请求帮助时,应将输出发送到STDOUT,因为用户可能希望将输出通过管道传递给lessgrep类的实用程序。

为了向后兼容,将writer属性设置为另一个值还将把errorWriter设置为相同的值。 (如果需要,您仍然可以在以后将errorWriter设置为另一个值。)

结论

Groovy 2.5 CliBuilder提供了许多令人兴奋的新功能。 尝试一下,让我们知道您的想法!

这是由两部分组成的文章的第2部分。 如果您错过了,这里是第1部分

有关更多信息,请访问Groovy 网站和GitHub 项目 ,以及picocli 网站picocli GitHub项目 如果您喜欢所看到的,请给项目加注星标!

翻译自: https://www.javacodegeeks.com/2018/06/groovy-clibuilder-renewal-part-2.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值