The Kaptain on … stuff

04 Oct, 2009

Groovy CliBuilder with multiple arguments

Posted by: TheKaptain In: Development

I’ve been writing a lot of Groovy scripts lately and have developed quite a fondness for the CliBuilder along the way.
There’s lots of great examples on the internet, but I could only find one place that demonstrated how to easily consume an unknown number of parameters as a List and that was a copy of the CliBuilderTest I found on Koders. There’s also some explanation for the different behavior inherent in the Apache Commons Cli libraries V1.0 and V1.1 that CliBuilder encapsulates(there is a 1.2 version, but from the documentation it seems CliBuilder may not be fully compatible with it).

Here’s a GroovyTestCase that exercises CliBuilder with multiple arguments.

[groovy language=”true” stripbrs=”true”]
package org.kar
import org.apache.commons.cli.Option
/**
* Demonstrates usage of the CliBuilder with multiple arguments to create a List.
*/
class CliBuilderDemoTest
extends GroovyTestCase {
/**
* You can specify multiple arguments one at a time.
*/
void testMultiOption() {
CliBuilder cli = new CliBuilder()
cli.with {
a longOpt: ‘arguments’, args: 2, required: true, ‘Two arguments’
}
def args = [‘-a’, ‘arg1’, ‘-a’, ‘arg2’]
def options = cli.parse(args)

assert (options)
assertEquals(‘First arg is available with the -a option. ‘, ‘arg1’, options.a)
assertEquals(‘Should be two args, in order, available with the addition of an "s" to the option.’,
[‘arg1’, ‘arg2’], options.as)
}

/**
* You can specify multiple arguments together in a block, with a defined separator(in this case a comma).
*/
void testMultiOptionWithSeparator() {
CliBuilder cli = new CliBuilder()
cli.with {
a longOpt: ‘arguments’, args: 2, required: true, valueSeparator: ‘,’ as char,
‘Two arguments, separated by a comma’
}
def args = [‘-a’, ‘arg1,arg2’]
def options = cli.parse(args)

assert (options)
assertEquals(‘First arg is available with the -a option. ‘, ‘arg1’, options.a)
assertEquals(‘Should be two args, in order.’, [‘arg1’, ‘arg2’], options.as)
}

/**
* You can also have any number of arguments by specifying UNLIMITED_VALUES.
*/
void testUnlimitedArgs() {
CliBuilder cli = new CliBuilder()
cli.with {
a longOpt: ‘arguments’, args: Option.UNLIMITED_VALUES, required: true, valueSeparator: ‘,’ as char,
‘Two arguments, separated by a comma’
}
def args = [‘-a’, ‘arg1,arg2,arg3’]
def options = cli.parse(args)

assert (options)
assertEquals(‘First arg is available with the -a option. ‘, ‘arg1’, options.a)
assertEquals(‘Should be a list of args, in order.’, [‘arg1’, ‘arg2’, ‘arg3’], options.as)

def args2 = [‘-a’, ‘argOnly’]
def options2 = cli.parse(args2)

assert (options)
assertEquals(‘First arg is available with the -a option.’, ‘argOnly’, options2.a)
assertEquals(‘Should be a list of args, with a single entry.’, [‘argOnly’], options2.as)

def args3 = []
//this will automagically print the usage string and any validation errors to System.out
def options3 = cli.parse(args3)
assertNull(options3)
}
}

[/groovy]

Anyhow, hope that the next guy finds this info useful – it certainly has made my recent work writing Groovy scripts much easier!

8 Responses to "Groovy CliBuilder with multiple arguments"

1 | jianping

February 3rd, 2011 at 9:35 am

Avatar

Good post, Kelly. Why is Option.UNLIMITED_VALUES not documented anywhere?

2 | TheKaptain

February 3rd, 2011 at 9:41 am

Avatar

The Apache cli library is actually fairly well documented, including the Options JP, but as I recall I did have to look around the inet awhile to find good examples:
http://commons.apache.org/cli/introduction.html

3 | jianping

February 3rd, 2011 at 11:44 am

Avatar

use unlimited option with default valueSeparator space seems to have some problem: I got extra ‘–‘ between the first and second parameters:

-o out -i f1 f2 f3

{code}

def cli = new CliBuilder(usage: “help”)
cli.o(argName:’outputFile’, longOpt:’output’, required:true, args:1, ‘Output File’)
cli.i(argName:’inputFiles’, longOpt:’inputs’, required:true, args: Option.UNLIMITED_VALUES, ‘Input Files’)

// process the args from the second element, leaving the name of the command out.
def options = cli.parse(args)

if (!options)
{
return
}

println (options.is)

{code}

4 | TheKaptain

February 3rd, 2011 at 6:08 pm

Avatar

Hmmm, not sure what’s happening there. Using Groovy 1.7.6 with exactly this code I get the following(expected) output.

groovy test.groovy -o out -i f1 f2 f3
[f1, f2, f3]

5 | Pavel

November 6th, 2011 at 7:25 am

Avatar

Hi! Is there a way to create mutually exclusive options using CliBuilder (like using OptionGroup in apache cli) ?

Thank you!

6 | TheKaptain

November 6th, 2011 at 10:54 am

Avatar

It should be, although I can’t find a convenient example. Under the hood you’re using the common-cli-1.2 jar, so you should be able to do everything it supports, although the syntax might not work directly on the builder.

7 | TheKaptain

November 6th, 2011 at 11:09 am

Avatar

There’s actually an example of using the commons-cli directly(without CliBuilder) in the Groovy source code that might help you as well:
https://github.com/groovy/groovy-core/blob/master/src/main/org/codehaus/groovy/tools/GrapeMain.groovy

8 | Starr

November 24th, 2011 at 7:30 pm

Avatar

I would really like to thank you such a lot of for your job you have made in writing this blog post. I am hoping the same top work from you later on also.

Comment Form