Search code examples
groovypicocli

Create CLI tool in Groovy with Picocli


I am using Picocli with Groovy to create a CLI tool I followed the example here: https://picocli.info/picocli-2.0-groovy-scripts-on-steroids.html

This example works well. But can't get a simple working example of multiple sub commands in Groovy. I want to execute it from the jar like: java -jar picapp -count [number of times] java -jar picapp -names[List of name/s]

so:

java -jar picapp count 3 
outputs: 
hi, hi , hi

java -jar picapp names bob john
outputs:
hi bob
hi john

I guess I am trying to implement the functionality in a this format: https://github.com/remkop/picocli/blob/master/picocli-examples/src/main/java/picocli/examples/subcommands/SubCmdsViaMethods.java

The Groovy code below doesn't compile:

@Grab('info.picocli:picocli:2.0.3')
import picocli.CommandLine;
import picocli.CommandLine.Command;
import picocli.CommandLine.Model.CommandSpec;
import picocli.CommandLine.Parameters;
import picocli.CommandLine.ParameterException;
import picocli.CommandLine.Spec;
import java.util.Locale;
@Command(name = "hi", subcommands = { CommandLine.HelpCommand.class },
        description = "hi")

public class picapp implements Runnable {

    @Command(name = "count", description = "count")
    void country(@Parameters(arity = "1..*", paramLabel = "count",
            description = "count") int count) {
        count.times {
            println("hi $it...")
        }
    }
    @Command(name = "names", description = "names")
    void language(@Parameters(arity = "1..*", paramLabel = "names",
            description = "name") String[] names) {
        println 'CmdLineTool says \n\tWelcome:'
        names.each {
            println '\t\t' + it
        }
    }

    @Override
    public void run() {
        throw new ParameterException(spec.commandLine(), "Specify a subcommand");
    }

    public static void main(String[] args) {
        CommandLine cmd = new CommandLine(new SubCmdsViaMethods());
        if (args.length == 0) {
            cmd.usage(System.out);
        }
        else {
            cmd.execute(args);
        }
    }
}

Solution

  • The problem is that picocli version 2.0.3 is old and does not support the execute method. The execute method was introduced in picocli 4.0.

    It is recommended to always use the latest picocli version. (Consider upgrading automatically with tools like dependabot.)