From b37681a65de942d8bc4cd9517b0c28b3bd9d1a7f Mon Sep 17 00:00:00 2001
From: Remko Popma
Picocli provides a number of convenience methods
that allow you to omit error handling and other boilerplate code for common use cases.
- Here is a small example application that uses the
The full user manual is hosted at http://picocli.info.
- * Another example that implements {@code Callable} and uses the {@link #call(Callable, String...) CommandLine.call} convenience API to run in a single line of code:
+ * Another example that implements {@code Callable} and uses the {@link #execute(String...) CommandLine.execute} convenience API to run in a single line of code:
* This method is used by {@link #execute(String...)}.
- * {@code IParameterExceptionHandler} and {@link IExecutionExceptionHandler} implementations
+ * {@code IParameterExceptionHandler} and {@link CommandLine.IExecutionExceptionHandler} implementations
* should use this stream to print error messages (which may include a usage help message) when an unexpected error occurs.
* Implementers responsibilities are:CommandLine.call
convenience method
+ Here is a small example application that uses the CommandLine.execute
convenience method
to do parsing and error handling in one line of code.
-@Command(name = "checksum", mixinStandardHelpOptions = true, version = "Checksum 2.0",
+@Command(name = "checksum", mixinStandardHelpOptions = true, version = "Checksum 4.0",
description = "Prints the checksum (MD5 by default) of a file to STDOUT.")
-class CheckSum implements Callable<Void> {
+class CheckSum implements Callable<Integer> {
@Parameters(index = "0", description = "The file whose checksum to calculate.")
private File file;
@@ -35,16 +35,17 @@
public static void main(String[] args) throws Exception {
// CheckSum implements Callable, so parsing, error handling and handling user
// requests for usage help or version help can be done with one line of code.
- CommandLine.call(new CheckSum(), args);
+ int exitCode = new CommandLine(new CheckSum()).execute(args);
+ // System.exit(exitCode);
}
@Override
- public Void call() throws Exception {
+ public Integer call() throws Exception {
// your business logic goes here
byte[] fileContents = Files.readAllBytes(file.toPath());
byte[] digest = MessageDigest.getInstance(algorithm).digest(fileContents);
- System.out.println(javax.xml.bind.DatatypeConverter.printHexBinary(digest));
- return null;
+ System.out.printf("%0" + (digest.length*2) + "x%n", new BigInteger(1, digest));
+ return 0;
}
}
diff --git a/src/main/java/picocli/CommandLine.java b/src/main/java/picocli/CommandLine.java
index 023d531c9..c01d2327e 100644
--- a/src/main/java/picocli/CommandLine.java
+++ b/src/main/java/picocli/CommandLine.java
@@ -101,12 +101,12 @@
* -vooutfile in1 in2
*
*
* @Command(description = "Prints the checksum (MD5 by default) of a file to STDOUT.",
- * name = "checksum", mixinStandardHelpOptions = true, version = "checksum 3.0")
- * class CheckSum implements Callable<Void> {
+ * name = "checksum", mixinStandardHelpOptions = true, version = "checksum 4.0")
+ * class CheckSum implements Callable<Integer> {
*
* @Parameters(index = "0", description = "The file whose checksum to calculate.")
* private File file;
@@ -117,16 +117,17 @@
* public static void main(String[] args) throws Exception {
* // CheckSum implements Callable, so parsing, error handling and handling user
* // requests for usage help or version help can be done with one line of code.
- * CommandLine.call(new CheckSum(), args);
+ * int exitCode = new CommandLine(new CheckSum()).execute(args);
+ * // System.exit(exitCode);
* }
*
* @Override
- * public Void call() throws Exception {
+ * public Integer call() throws Exception {
* // your business logic goes here...
* byte[] fileContents = Files.readAllBytes(file.toPath());
* byte[] digest = MessageDigest.getInstance(algorithm).digest(fileContents);
- * System.out.println(javax.xml.bind.DatatypeConverter.printHexBinary(digest));
- * return null;
+ * System.out.printf("%0" + (digest.length*2) + "x%n", new BigInteger(1,digest));
+ * return 0;
* }
* }
*
@@ -784,10 +785,10 @@ public CommandLine setUnmatchedArgumentsAllowed(boolean newValue) {
public List
+ *
+ * This interface supercedes {@link IParseResultHandler2}
+ * @since 4.0 */
+ public interface IExecutionStrategy {
+ /**
+ * "Executes" the user input and returns an exit code.
+ * Execution often means invoking a method on the selected CommandSpec's {@linkplain CommandSpec#userObject() user object}.
+ * @param parseResult the parse result from which to select one or more {@code CommandSpec} instances to execute.
+ * @return an exit code
+ * @throws ParameterException if the invoked method on the CommandSpec's user object threw a ParameterException to signify invalid user input.
+ * @throws ExecutionException if any problem occurred while executing the command. Any exceptions (other than ParameterException) should be wrapped in a ExecutionException and not thrown as is.
+ */
+ int execute(ParseResult parseResult) throws ExecutionException, ParameterException;
}
/**
@@ -1093,10 +1113,10 @@ public static interface IExceptionHandler2
* A second difference is that this method provides exit code support. * If the user object {@code Callable} or {@code Method} returns an {@code int} or {@code Integer}, - * this will be used as the exit code. Additionally, if the user object implements {@link IExitCodeGenerator IExitCodeGenerator}, + * this will be used as the exit code. Additionally, if the user object implements {@link CommandLine.IExitCodeGenerator IExitCodeGenerator}, * an exit code is obtained by calling its {@code getExitCode()} method (after invoking the user object). *
* In the case of multiple exit codes the highest value will be used (or if all values are negative, the lowest value will be used).
@@ -1418,7 +1438,7 @@ private static List
- * If an {@link IExitCodeExceptionMapper IExitCodeExceptionMapper} is {@linkplain #setExitCodeExceptionMapper(IExitCodeExceptionMapper) configured}, + * If an {@link CommandLine.IExitCodeExceptionMapper IExitCodeExceptionMapper} is {@linkplain #setExitCodeExceptionMapper(IExitCodeExceptionMapper) configured}, * this mapper is used to determine the exit code based on the exception. *
* If no {@code IExitCodeExceptionMapper} is set, by default this method will return the {@code @Command} annotation's @@ -1455,7 +1475,7 @@ public int execute(String... args) { *
* A second difference is that this method provides exit code support. * If the user object {@code Callable} or {@code Method} returns an {@code int} or {@code Integer}, - * this will be used as the exit code. Additionally, if the user object implements {@link IExitCodeGenerator IExitCodeGenerator}, + * this will be used as the exit code. Additionally, if the user object implements {@link CommandLine.IExitCodeGenerator IExitCodeGenerator}, * an exit code is obtained by calling its {@code getExitCode()} method (after invoking the user object). *
* In the case of multiple exit codes the highest value will be used (or if all values are negative, the lowest value will be used).
@@ -1547,7 +1567,7 @@ public abstract static class AbstractParseResultHandler Consider using the {@link #execute(String...)} method instead: