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.

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)
    }
}

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

Share

Related posts:

  1. Different Flavors of Embedded Groovy in Java Apps or “How To Make your Java Groovier!”
  2. Hooking into the Jenkins(Hudson) API
  3. Grails-UI DataTable using XML for a model

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?

[Reply]

TheKaptain Reply:

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

[Reply]

2 | 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}

[Reply]

TheKaptain Reply:

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]

[Reply]

3 | 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!

[Reply]

TheKaptain Reply:

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.

[Reply]

TheKaptain Reply:

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

[Reply]

4 | 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.

[Reply]

Comment Form

Get Adobe Flash playerPlugin by wpburn.com wordpress themes

About

Tales of development, life and the folly that goes along with both.

Tags

On Twitter

Powered by Twitter Tools

profile for TheKaptain at Stack Overflow, Q&A for professional and enthusiast programmers