Groovy 2.5 CliBuilder更新(第1部分)

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

这篇分为两部分的文章重点介绍了新功能。

第2部分将说明如何利用CliBuilder的基础库的某些高级功能。

CliBuilder更新cygwin

以前的CliBuilder版本使用Apache Commons CLI作为基础解析器库。 从Groovy 2.5开始,有一个基于picocli解析器的CliBuilder的替代版本。

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

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

接下来,让我们看一下Groovy 2.5 CliBuilder中的一些新功能。

打字选项

CliBuilder续订类型

选项可以是布尔标志,也可以采用一个或多个选项参数。 在以前的CliBuilder版本中,您必须指定args: 1表示需要一个参数的选项,或args: '+'表示接受多个参数的选项。

此版本的CliBuilder添加了对类型化选项的支持。 这在处理解析结果时很方便,但是此外,从类型推断参数的数量,因此,如果指定了type ,则可以省略args

例如:

def cli = new CliBuilder()
cli.a(type: String, 'a-arg')
cli.b(type: boolean, 'b-arg')
cli.c(type: Boolean, 'c-arg')
cli.d(type: int, 'd-arg')
cli.e(type: Long, 'e-arg')
cli.f(type: Float, 'f-arg')
cli.g(type: BigDecimal, 'g-arg')
cli.h(type: File, 'h-arg')
cli.i(type: RoundingMode, 'i-arg')

def argz = '''-a John -b -d 21 -e 1980 -f 3.5 -g 3.14159
    -h cv.txt -i DOWN and some more'''.split()

def options = cli.parse(argz)
assert options.a == 'John'
assert options.b
assert !options.c
assert options.d == 21
assert options.e == 1980L
assert options.f == 3.5f
assert options.g == 3.14159
assert options.h == new File('cv.txt')
assert options.i == RoundingMode.DOWN
assert options.arguments() == ['and', 'some', 'more']

支持的类型

基于Commons CLI的CliBuilder支持原语,数值类型,文件,枚举和数组(使用StringGroovyMethods#asType(String,Class) )。 基于picocli的CliBuilder支持以上功能

添加更多类型

如果内置类型不能满足您的需求,则可以轻松注册自定义转换器。 指定convert闭包以将String参数转换为任何其他类型。 例如:

import java.nio.file.Paths
import java.time.LocalTime

def cli = new CliBuilder()
cli.a(convert: { it.toUpperCase() }, 'a-arg')    (1)
cli.p(convert: { Paths.get(it) }, 'p-arg')       (2)
cli.t(convert: { LocalTime.parse(it) }, 't-arg') (3)

def options = cli.parse('-a abc -p /usr/home -t 15:31:59'.split())
assert options.a == 'ABC'
assert options.p.absolute && options.p.parent == Paths.get('/usr')
assert options.t.hour == 15 && options.t.minute == 31
  1. 将一个字符串转换为另一个
  2. 选项值将转换为java.nio.file.Path
  3. 选项值转换为java.time.LocalTime

注解

CliBuilder更新Java批注

从此发行版开始,Groovy提供了用于处理命令行参数的注释API。

应用程序可以使用@groovy.cli.Option命名字段或方法来命名选项,使用@groovy.cli.Unparsed位置参数。 当解析器将命令行参数与选项名称或位置参数匹配时,该值将转换为正确的类型并注入到字段或方法中。

接口的注释方法

使用批注的一种方法是在接口的“类似getter的”方法(返回值的方法)上。 例如:

import groovy.cli.*

interface IHello {
    @Option(shortName='h', description='display usage') Boolean help()   (1)
    @Option(shortName='u', description='user name')     String user()    (2)
    @Unparsed(description = 'positional parameters')    List remaining() (3)
}
  1. 如果在命令行上指定了-h--help则方法返回true
  2. 方法返回为-u--user选项指定的参数值。
  3. 该方法会将所有剩余参数作为列表返回。

如何使用此界面(使用picocli版本演示其用法帮助):

import groovy.cli.picocli.CliBuilder

def cli = new CliBuilder(name: 'groovy Greeter')
def argz = '--user abc'.split()
IHello hello = cli.parseFromSpec(IHello, argz)
assert hello.user() == 'abc'

hello = cli.parseFromSpec(GreeterI, ['--help', 'Some', 'Other', 'Args'] as String[])
assert hello.help()
cli.usage()
assert hello.remaining() == ['Some', 'Other', 'Args']

这将打印以下用法帮助消息:

Usage: groovy Greeter [-h] [-u=<user>] [<remaining>...]
      [<remaining>...]   positional parameters
  -u, --user=<user>      user name
  -h, --help             display usage

调用parseFromSpecCliBuilder读取注释,解析命令行参数并返回接口的实例。 接口方法返回在命令行上匹配的选项值。

注释类的属性或设置器方法

使用批注的另一种方法是在类的属性或“类设定者”方法(具有单个参数的void方法)上。 例如:

class Hello {
    @Option(shortName='h', description='display usage') (1)
    Boolean help

    private String user
    @Option(shortName='u', description='user name')     (2)
    void setUser(String user) {
        this.user = user
    }
    String getUser() { user }

    @Unparsed(description = 'positional parameters')    (3)
    List remaining
}
    1. help布尔属性设置为true ,如果-h--help在命令行上指定。
    2. 使用-u--user选项参数值调用setUser属性setter方法。
    3. remaining属性设置为包含剩余args(如果有)的新List

带注释的类可以如下使用:

String[] argz = ['--user', 'abc', 'foo']

def cli = new CliBuilder(usage: 'groovy Greeter [option]') (1)
Hello greeter = cli.parseFromInstance(new Hello(), argz)   (2)
assert greeter.user == 'abc'                               (3)
assert greeter.remaining == ['foo']                        (4)
    1. 创建一个CliBuilder实例。
    2. 从带注释的实例中提取选项,解析参数,然后填充并返回提供的实例。
    3. 验证是否已将字符串选项值分配给该属性。
    4. 验证剩余的参数属性。

调用parseFromInstanceCliBuilder再次读取注释,解析命令行参数,最后返回实例。 带注释的字段和设置方法使用与关联选项匹配的值进行初始化。

脚本注释

CliBuilder续订脚本注释

Groovy 2.5还为Groovy脚本提供了新的注释。

@OptionField等同于组合@groovy.transform.Field@Option ,而@UnparsedField等同于组合@Field@Unparsed

使用这些批注将脚本变量转换为字段,以便CliBuilder可以填充变量。 例如:

import groovy.cli.OptionField
import groovy.cli.UnparsedField

@OptionField String user
@OptionField Boolean help
@UnparsedField List remaining

String[] argz = ['--user', 'abc', 'foo']

new CliBuilder().parseFromInstance(this, argz)
assert user == 'abc'
assert remaining == ['foo']

键入的位置参数

此版本的CliBuilder对强类型的位置参数提供了一些有限的支持。

如果所有位置参数都具有相同的类型,则@Unparsed注释可以与String[]以外的其他数组类型一起使用。 同样,在Commons CLI版本中使用StringGroovyMethods#asType(String,Class)完成类型转换,而CliBuilder的picocli版本支持这些类型的超集

此功能仅适用于注释API,不适用于动态API。 这是可以捕获强类型的位置参数的接口示例:

interface TypedPositionals {
    @Unparsed Integer[] nums()
}

下面的代码演示了类型转换:

def argz = '12 34 56'.split()
def cli = new CliBuilder()
def options = cli.parseFromSpec(TypedPositionals, argz)
assert options.nums() == [12, 34, 56]

陷阱/不兼容

CliBuilder更新不兼容

在某些方面,新版本的CliBuilder与以前的版本或彼此不兼容。

属性

CliBuilder的Commons CLI版本和CliBuilder的早期版本公开了org.apache.commons.cli.Options类型的options属性,该属性可用于配置基础的Commons CLI解析器,而无需通过CliBuilder API。 此属性在picocli版本的CliBuilder中不可用。 读取或写入此属性的应用程序必须导入groovy.cli.commons.CliBuilder或修改该应用程序。

此外,CliBuilder的picocli版本中不提供org.apache.commons.cli.HelpFormatter类型的formatter属性。 如果您的应用程序使用此属性,请考虑改为使用usageMessage属性,或导入groovy.cli.commons.CliBuilder

Picocli和Commons CLI版本中的属性

picocli版本的CliBuilder具有parser属性,该属性公开了picocli.CommandLine.Model.ParserSpec对象,该对象可用于配置解析器行为。

Commons CLI版本的CliBuilder和早期版本的CliBuilder公开了类型为org.apache.commons.cli.CommandLineParserparser属性。 picocli版本的CliBuilder中不提供此功能。

如果您的应用程序使用parser属性来设置其他Commons CLI解析器,请考虑改为使用posix属性,或导入groovy.cli.commons.CliBuilder

Commons CLI DefaultParser识别以单连字符longOption选项名称(例如-option )和以双连字符--option选项(例如--option )。 这并不总是很明显,因为用法帮助消息仅显示longOption选项名称的双连字符前缀。

为了向后兼容,CliBuilder的picocli版本具有acceptLongOptionsWithSingleHyphen属性:如果解析器应识别带有单连字符和双连字符前缀的长选项名称,则将此属性设置为true 。 默认值为false ,因此只能识别带有双连字符前缀的长选项名称( --option )。

等等,还有更多...

本文的第2部分介绍了如何利用CliBuilder的基础库的某些高级功能。 在这里,您可以使命令行应用程序真正发光。 敬请期待...

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值