Parse command-line options in Groovy

Learn to add options to your Groovy applications.
45 readers like this.
Woman sitting in front of her computer

Ray Smith

A recent article provided an introduction to parsing command-line options in Java. Because I really like Groovy, and because Groovy is well suited for scripting, and because it's fun to compare Java and Groovy solutions, I decided to paraphrase Seth's article, but using Groovy.

Install Groovy

Groovy is based on Java, so it requires a Java installation. Both a recent and decent version of Java and Groovy might be in your Linux distribution's repositories. Alternately, you can install Groovy by following the instructions on the groovy-lang.org.

A nice alternative for Linux users is SDKMan, which can be used to get multiple versions of Java, Groovy, and many other related tools. For this article, I'm using my distro's OpenJDK11 release and SDKMan's latest Groovy release.

Parsing command-line options in Groovy

When we create a script—a kind of short, often informal program—to be run from the command line, we normally follow the practice of passing arguments to the script on the command line. A good example of this is the ls command, used to list all the files and subfolders in a given folder, perhaps showing attributes and sorted in reverse order of last modification date, as in:

$ ls -lt /home/me

To show the contents of my home folder like this:

total 252
drwxr-xr-x 5 me me 4096 Aug 10 12:23 Downloads
drwx------ 11 me me 4096 Aug 10 08:59 Dropbox
drwxr-xr-x 27 me me 12288 Aug 9 11:58 Pictures
-rw-rw-r-- 1 me me 235 Jul 28 16:22 wb.groovy
drwxr-xr-x 2 me me 4096 Jul 20 22:04 Desktop
drwxrwxr-x 2 me me 4096 Jul 20 15:16 Fixed
drwxr-xr-x 2 me me 16384 Jul 19 08:49 Music
-rw-rw-r-- 1 me me 433 Jul 7 13:24 foo
drwxr-xr-x 6 me me 4096 Jun 29 10:25 Documents
drwxr-xr-x 2 me me 4096 Jun 14 22:15 Templates
-rw-rw-r-- 1 me me 803 Jun 14 11:33 bar

Of course, arguments to commands can be handled by inspecting them and deciding what to do in each case; but this ends up being a duplication of effort that can be avoided by using a library designed for that purpose.

Seth's Java article introduces the Apache Commons CLI library, a great API for handling command-line options. In fact, this library is so great that the good people who develop Groovy make it available by default in the Groovy installation. Therefore, once you have Groovy installed, you have access to this library through groovy.cli.picocli.CliBuilder, which is already imported for you by default.

Here's a Groovy script that uses this CLI builder to achieve the same results as Seth's Java program:

1 def cli = new CliBuilder(usage: 'ho.groovy [-a] -c')
2 cli.with {
3    a longOpt: 'alpha', 'Activate feature alpha'
4    c longOpt: 'config', args:1, argName: 'config', required: true, 'Set config file'
5 }
6 def options = cli.parse(args)
7 if (!options) {
8    return
9 }
10 if (options.a) {
11    println' Alpha activated'
12 }
13 if (options.c) {
14    println "Config set to ${options.c}"
15 }

I've included line numbers here to facilitate the discussion. Save this script without the line numbers in a file called ho.groovy.

On line 1, we define the variable cli and set it to a new instance of CliBuilder with a defined usage attribute. This is a string that will be printed if the usage() method is called.

On lines 2-5, we use the with() method that Groovy adds to objects, together with the DSL defined by CliBuilder, to set up the option definitions.

On line 3, we define the option 'a', setting its longOpt field to 'alpha' and its description to 'Activate feature alpha'.

Similarly, on line 4, we define the option 'c', setting its longOpt field to 'config' and specifying that this option takes one argument whose name is 'config'. Moreover, this is a required option (sounds funny, I know), and its description is 'Set config file'.

Pausing briefly here for a bit of background, you can read all about these various options at the CliBuilder link above. More generally, things written in the form longOpt: 'alpha' are Groovy notation for key-value entries to be put in a Map instance, which you can read about here. Each key, in this case, corresponds to a method of the same name provided by the CliBuilder. If you're wondering what's going on with a line like:

a longOpt: 'alpha', 'Activate feature alpha'

then it may be useful to mention that Groovy allows us to drop parentheses in certain circumstances; so the above is equivalent to:

a(longOpt: 'alpha', 'Activate feature alpha')

i.e., it's a method call. Moreover, Groovy allows both positional and named parameters, the latter using that key: value syntax.

Onward! On lines 6-9, we call the parse() method of the CliBuilder instance cli, passing the args—an array of String values created by the Groovy run-time and containing the arguments from the command line. This method returns a Map of the options where the keys are the short-form of the predefined options—in this case, 'a' and 'c'. If the parsing fails, then parse() emits the usage message, a reasonable error message, and returns a null value, so we don't have to use a try-catch block (which one doesn't see as often in Groovy). So here—line 8—we just return since all our work is done for us.

On lines 10-12, we check to see if option 'a' was included on the command line and if it is, print a message saying so.

Similarly, on lines 13-15, we check to see if option 'c' was included on the command line and if so, print a message showing the argument provided to it.

Running the command

Let’s run the script a few times; first with no arguments:

$ groovy ho.groovy
error: Missing required option: c
usage: ho.groovy [-a] -c
 -a,--alpha Activate feature alpha
 -c,--config <config> Set config file
$

Notice the complaint about missing the required option 'c'.

Then with the 'c' option but no argument:

$ groovy ho.groovy -c
error: Missing argument for option: c
usage: ho.groovy [-a] -c
 -a,--alpha
Activate feature alpha
 -c,--config <config> Set config file
$

Cool, the CliBuilder instance method parse() noticed no argument was provided to 'c'.

Finally, let's try with both options and an argument to 'c', in their long form:

$ groovy ho.groovy --alpha --config bar
Alpha activated
Config set to bar
$

Looks good!

Since the idea of the 'c' option is to provide a config file, we could also tell the CliBuilder instance that the type of this argument is File, and it will return that instead of a String. But we'll leave that for another day.

So, there you have it—command-line option parsing in Groovy.

Groovy resources

The Groovy website has a lot of great documentation. Another great Groovy resource is Mr. Haki, and specifically this lovely article on CliBuilder.

Another great reason to learn Groovy is Grails, a wonderfully productive full-stack web framework built on top of excellent components like Hibernate, Spring Boot, and Micronaut.

What to read next
Chris Hermansen portrait Temuco Chile
Seldom without a computer of some sort since graduating from the University of British Columbia in 1978, I have been a full-time Linux user since 2005, a full-time Solaris and SunOS user from 1986 through 2005, and UNIX System V user before that.

Comments are closed.

Creative Commons LicenseThis work is licensed under a Creative Commons Attribution-Share Alike 4.0 International License.