Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Groovy CliBuilder: only last LongOpt is taken in account

Tags:

groovy

I'm trying to use the groovy CliBuilder to parse command line options. I'm trying to use multiple long options without a short option. I have the following processor:

    def cli = new CliBuilder(usage: 'Generate.groovy [options]')
    cli.with {
        h longOpt: "help", "Usage information"
        r longOpt: "root", args: 1, type: GString, "Root directory for code generation"
        x args: 1, type: GString, "Type of processor (all, schema, beans, docs)"
        _ longOpt: "dir-beans", args: 1, argName: "directory", type: GString, "Custom location for grails bean classes"
        _ longOpt: "dir-orm", args: 1, argName: "directory", type: GString, "Custom location for grails domain classes"
    }
    options = cli.parse(args)

    println "BEANS=${options.'dir-beans'}"
    println "ORM=${options.'dir-orm'}"

    if (options.h || options == null) {
        cli.usage()
        System.exit(0)
    }

According to the groovy documentation I should be able to use multiple "_" values for an option when I want it to ignore the short option name and use a long option name only. According to the groovy documentation:

Another example showing long options (partial emulation of arg 
processing for 'curl' command line):
 def cli = new CliBuilder(usage:'curl [options] <url>')
 cli._(longOpt:'basic', 'Use HTTP Basic Authentication')
 cli.d(longOpt:'data', args:1, argName:'data', 'HTTP POST data')
 cli.G(longOpt:'get', 'Send the -d data with a HTTP GET')
 cli.q('If used as the first parameter disables .curlrc')
 cli._(longOpt:'url', args:1, argName:'URL', 'Set URL to work with')

 Which has the following usage message:

 usage: curl [options] <url>
     --basic         Use HTTP Basic Authentication
  -d,--data <data>   HTTP POST data
  -G,--get           Send the -d data with a HTTP GET
  -q                 If used as the first parameter disables .curlrc
     --url <URL>     Set URL to work with
This example shows a common convention. When mixing short and long

names, the short names are often one character in size. One character options with arguments don't require a space between the option and the argument, e.g. -Ddebug=true. The example also shows the use of '_' when no short option is applicable.

Also note that '_' was used multiple times. This is supported but if any other shortOpt or any longOpt is repeated, then the behavior is undefined.

http://groovy.codehaus.org/gapi/groovy/util/CliBuilder.html

When I use the "_" it only accepts the last one in the list (last one encountered). Am I doing something wrong or is there a way around this issue?

Thanks.

like image 322
jmq Avatar asked Apr 27 '11 02:04

jmq


2 Answers

not sure what you mean it only accepts the last one. but this should work...

def cli = new CliBuilder().with {
  x 'something', args:1
  _ 'something', args:1, longOpt:'dir-beans'
  _ 'something', args:1, longOpt:'dir-orm'
  parse "-x param --dir-beans beans --dir-orm orm".split(' ')
}
assert cli.x == 'param'
assert cli.'dir-beans' == 'beans'
assert cli.'dir-orm' == 'orm'
like image 107
jpertino Avatar answered Sep 21 '22 02:09

jpertino


I learned that my original code works correctly. What is not working is the function that takes all of the options built in the with enclosure and prints a detailed usage. The function call built into CliBuilder that prints the usage is:

cli.usage()

The original code above prints the following usage line:

usage: Generate.groovy [options]
    --dir-orm <directory>   Custom location for grails domain classes
 -h,--help                  Usage information
 -r,--root                  Root directory for code generation
 -x                         Type of processor (all, schema, beans, docs)

This usage line makes it look like I'm missing options. I made the mistake of not printing each individual item separate from this usage function call. That's what made this look like it only cared about the last _ item in the with enclosure. I added this code to prove that it was passing values:

    println "BEANS=${options.'dir-beans'}"
    println "ORM=${options.'dir-orm'}"

I also discovered that you must use = between a long option and it's value or it will not parse the command line options correctly (--long-option=some_value)

like image 28
jmq Avatar answered Sep 22 '22 02:09

jmq