commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Paul King <paul.king.as...@gmail.com>
Subject Re: [OT][CLI] JCommander Add-ons
Date Mon, 31 Oct 2016 04:32:00 GMT
For Groovy users, in the upcoming Groovy 2.5 release, Groovy's CliBuilder
provides an annotation-based layer on top of [cli]. Most of CliBuilder
relies heavily on Groovy being there but the annotation layer on top much
less so apart from the Closure converters. In any case, it's an example of
providing an annotation-based option while leaving the api part of [cli] in
place as it exist now.

Some groovydoc (search for annotation style):

http://docs.groovy-lang.org/docs/next/html/gapi/groovy/util/CliBuilder.html

Some examples from the Groovy test code (search for @Option):

https://github.com/apache/groovy/blob/master/src/test/groovy/util/CliBuilderTest.groovy

Groovy documentation:

http://docs.groovy-lang.org/docs/next/html/documentation/#_clibuilder

Just three examples (pulled out of above) in case you don't want to click
the links.

Your cli arguments can be specified using an interface spec and can have
inline closures for converters if needed:

import groovy.cli.*

interface ConvertSpec {
    @Option(convert={ it.toLowerCase() }) String a()
    @Option(convert={ it.toUpperCase() }) String b()
    @Option(convert={ Date.parse("yyyy-MM-dd", it) }) Date d()
    @Unparsed List remaining()
}

Date newYears = Date.parse("yyyy-MM-dd", "2016-01-01")
def argz = '''-a John -b Mary -d 2016-01-01 and some more'''.split()
def cli = new CliBuilder()
def options = cli.parseFromSpec(ConvertSpec, argz)
assert options.a() == 'john'
assert options.b() == 'MARY'
assert options.d() == newYears
assert options.remaining() == ['and', 'some', 'more']

Your spec can be an existing class and it supports Groovy's type checking
if you need it:

class MyTypedSpec {
    @Option String name
    @Option int age
    @Unparsed List remaining
}

@TypeChecked
void testTypeCheckedClass() {
    def argz = "--name John --age 21 and some more".split()
    def cli = new CliBuilder()
    def options = new MyTypedSpec()
    cli.parseFromInstance(options, argz)
    String n = options.name     // will be type checked
    int a = options.age             // will be type checked
    assert n == 'John' && a == 21
    assert options.remaining == ['and', 'some', 'more']
}

It can also be used directly from scripts as follows (showing some of
the builtin types and enum support):

import groovy.cli.*
import java.math.RoundingMode

// override commandline args for testing
def args = "--name John --flag --born 1980 --discount 3.5 --pi 3.14159
--biography cv.txt --roundingMode DOWN and some more".split()
@OptionField String name
@OptionField boolean flag
@OptionField Integer born
@OptionField float discount
@OptionField BigDecimal pi
@OptionField File biography
@OptionField RoundingMode roundingMode
@UnparsedField List remaining
new CliBuilder().parseFromInstance(this, args)
assert name == 'John'
assert flag
assert born == 1980
assert discount == 3.5f
assert pi == 3.14159G
assert biography == new File('cv.txt')
assert roundingMode == RoundingMode.DOWN
assert remaining == ['and', 'some', 'more']



Cheers, Paul.


On Mon, Oct 31, 2016 at 5:30 AM, Gary Gregory <garydgregory@gmail.com>
wrote:

> For the curious,
>
> I'd love to see [cli] evolve into something like JCommander [1] and it's
> annotation-based system.
>
> In the meantime, I use JCommander mostly but some [cli] in some old
> projects that are in maintenance mode. JCommander is great but is not
> perfect or complete, so I created some add-ons here
> https://github.com/garydgregory/jcommander-addons
>
> Any thoughts or feedback are welcome.
>
> Thank you,
> Gary
>
> [1] http://jcommander.org/
>
> --
> E-Mail: garydgregory@gmail.com | ggregory@apache.org
> Java Persistence with Hibernate, Second Edition
> <https://www.amazon.com/gp/product/1617290459/ref=as_li_
> tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1617290459&
> linkCode=as2&tag=garygregory-20&linkId=cadb800f39946ec62ea2b1af9fe6a2b8>
>
> <http:////ir-na.amazon-adsystem.com/e/ir?t=garygregory-20&l=am2&o=1&a=
> 1617290459>
> JUnit in Action, Second Edition
> <https://www.amazon.com/gp/product/1935182021/ref=as_li_
> tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1935182021&
> linkCode=as2&tag=garygregory-20&linkId=31ecd1f6b6d1eaf8886ac902a24de418%22
> >
>
> <http:////ir-na.amazon-adsystem.com/e/ir?t=garygregory-20&l=am2&o=1&a=
> 1935182021>
> Spring Batch in Action
> <https://www.amazon.com/gp/product/1935182951/ref=as_li_
> tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1935182951&
> linkCode=%7B%7BlinkCode%7D%7D&tag=garygregory-20&linkId=%7B%
> 7Blink_id%7D%7D%22%3ESpring+Batch+in+Action>
> <http:////ir-na.amazon-adsystem.com/e/ir?t=garygregory-20&l=am2&o=1&a=
> 1935182951>
> Blog: http://garygregory.wordpress.com
> Home: http://garygregory.com/
> Tweet! http://twitter.com/GaryGregory
>

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message