-
Notifications
You must be signed in to change notification settings - Fork 445
Executing Commands
Picocli 4.0 introduced new API to execute commands. Let’s take a quick look at what changed.
Many command line applications return an exit code to signify success or failure. Zero often means success, a non-zero exit code is often used for errors, but other than that, meanings differ per application.
The new CommandLine.execute method returns an int, and applications can use this return value to call System.exit if desired. For example:
public static void main(String... args) {
CommandLine cmd = new CommandLine(new App());
int exitCode = cmd.execute(args);
System.exit(exitCode);
}Older versions of picocli had some limited exit code support where picocli would call System.exit, but this is now deprecated.
@Command-annotated classes that implement Callable and @Command-annotated methods can simply return an int or Integer value that will be returned from CommandLine.execute. For example:
@Command(name = "greet")
class Greet implements Callable<Integer> {
public Integer call() {
System.out.println("hi");
return 1;
}
@Command
int shout() {
System.out.println("HI!");
return 2;
}
}Commands with a user object that implements Runnable can implement the IExitCodeGenerator interface to generate an exit code. For example:
@Command(name = "wave")
class Wave implements Runnable, IExitCodeGenerator {
public void run() {
System.out.println("wave");
}
public int getExitCode() {
return 3;
}
}By default, the execute method returns 64 for invalid input, and 70 when an exception occurred in the Runnable, Callable or command method (EX_USAGE and EX_SOFTWARE, respectively, from Linux sysexits.h). This can be customized with the @Command annotation. For example:
@Command(exitCodeOnInvalidInput = 123,
exitCodeOnExcecutionException = 456)Additionally, applications can configure a IExitCodeExceptionMapper to map a specific exception to an exit code:
class MyMapper implements IExitCodeExceptionMapper {
public int getExitCode(Throwable t) {
if (t instance of FileNotFoundException) {
return 74;
}
return 1;
}
}The new CommandLine.execute and CommandLine.tryExecute methods are instance methods. The older run, call and invoke methods are static methods. Static methods don’t allow configuration. The new API lets applications configure the parser or other aspects before execution. For example:
public static void main(String... args) {
CommandLine cmd = new CommandLine(new App());
cmd.setCaseInsensitiveEnumValuesAllowed(true);
cmd.setAllowOverwrite(true);
cmd.setExpandAtFiles(true);
cmd.execute(args);
}