Class PicocliBaseScript2

  • All Implemented Interfaces:
    GroovyObject, Callable<Object>

    public abstract class PicocliBaseScript2
    extends Script
    implements Callable<Object>

    Base script class that provides picocli declarative (annotation-based) command line argument processing for Groovy scripts, updated for picocli version 4 and greater.

    Scripts may install this base script via the PicocliScript2 annotation or via the standard Groovy @groovy.transform.BaseScript(picocli.groovy.PicocliBaseScript2) annotation, but the @PicocliScript2 annotation is preferred since it enables scripts to use the @Command annotation.

    Example usage

     @Command(name = "greet", description = "Says hello.", mixinStandardHelpOptions = true, version = "greet 0.1")
     @PicocliScript2
     import picocli.groovy.PicocliScript2
     import picocli.CommandLine.Command
     import picocli.CommandLine.Option
     import groovy.transform.Field
    
     @Option(names = ['-g', '--greeting'], description = 'Type of greeting')
     @Field String greeting = 'Hello'
    
     println "${greeting} world!"
     

    Before the script body is executed, the PicocliBaseScript2 base class parses the command line and initializes @Field variables annotated with @Option or @Parameters. It also takes care of error handling and common use cases like requests for usage help.

    See the run() method for a detailed break-down of the steps the base class takes before and after the statements in the script body are executed.

    Customization

    Scripts can override beforeParseArgs(CommandLine) to change the parser configuration, or set custom exception handlers etc.

    Scripts can override afterExecution(CommandLine, int, Exception) to call System.exit or return a custom result.

    PicocliBaseScript2 vs PicocliBaseScript

    This class has the following improvements over PicocliBaseScript:

    • Adds support for @Command-annotated methods to define subcommands in scripts.
    • Adds support for help subcommands (both the built-in CommandLine.HelpCommand and custom implementations).
    • Adds support for exit codes.
    • Consistency with Java picocli. The new PicocliBaseScript2 base class delegates to the CommandLine::execute method introduced in picocli 4.0. This allows scripts to leverage new features of the picocli library, as well as future enhancements, more easily. By contrast, the old PicocliBaseScript base class implemented its own execution strategy, which over time fell behind the core picocli library.
    Since:
    4.6
    • Field Detail

      • COMMAND_LINE

        public static final String COMMAND_LINE
        Name of the property that holds the CommandLine instance for this script ("commandLine").
        See Also:
        Constant Field Values
    • Constructor Detail

      • PicocliBaseScript2

        public PicocliBaseScript2()
    • Method Detail

      • call

        public abstract Object call()
        The script body.
        Specified by:
        call in interface Callable<Object>
        Returns:
        The result of the script evaluation.
      • run

        public Object run()

        Parses the command line and initializes @Field variables annotated with @Option or @Parameters before executing the script body. Also takes care of error handling and common use cases like requests for usage help.

        Execution

        Here is a break-down of the steps the base class takes before the statements in the script body are executed:

        1. Call getOrCreateCommandLine() to create a new CommandLine with this script instance as the annotated command object. The CommandLine instance is cached in the commandLine property (so it can be referred to in script code with this.commandLine). Scripts may override.
        2. Call beforeParseArgs(CommandLine) to install custom handlers for invalid user input or exceptions are installed. Scripts may override.
        3. Call CommandLine.execute(String...) method with the script arguments. This results in the following:
          • Assuming the user input was valid, this initialises all @Field variables annotated with CommandLine.Option or CommandLine.Parameters.
          • Otherwise, if the user input was invalid, the command line arguments are printed to standard err, followed by an error message and the usage message. Then, the script exits (see step 4 below). This may be customized by overriding beforeParseArgs(CommandLine) and setting a custom CommandLine.IParameterExceptionHandler on the CommandLine instance.
          • Otherwise, if the user input requested version help or usage help, the version string or usage help message is printed to standard err and the script exits (see step 4 below).
          • The script may define subcommands. In that case only the last specified subcommand is invoked. This may be customized by overriding beforeParseArgs(CommandLine) and setting a custom CommandLine.IExecutionStrategy on the CommandLine instance.
          • If no subcommand was specified, the script body is executed.
        4. Store the exit code returned by CommandLine.execute in the exitCode property of this script.
        5. Call afterExecution(CommandLine, int, Exception) to handle script exceptions and return the script result: If an exception occurred during execution, this exception is rethrown, wrapped in a GroovyRuntimeException. Otherwise, the result of the script is returned, either as a list (in case of multiple results), or as a single object.

        Exit Code

        Scripts that want to control the exit code of the process that executed the script can override the afterExecution(CommandLine, int, Exception) method and call System.exit. For example:

         @Override
         protected Object afterExecution(CommandLine commandLine, int exitCode, Exception exception) {
             exception?.printStackTrace();
             System.exit(exitCode);
         }
        Specified by:
        run in class Script
        Returns:
        The result of the script evaluation.
      • afterExecution

        protected Object afterExecution​(CommandLine commandLine,
                                        int exitCode,
                                        Exception exception)
        This method is called after the script has been executed, and may do one of three things:
        • Call System.exit with the specified exit code.
        • Throw a GroovyRuntimeException with the specified exception.
        • Return the result of the script execution.

        By default, this method will throw a GroovyRuntimeException if the specified exception is not null, and otherwise returns the result of the script execution.

        Scripts may override this method to call System.exit or do something else.

        Parameters:
        commandLine - encapsulates the picocli model of the command and subcommands
        exitCode - the exit code that resulted from executing the script's command and/or subcommand(s)
        exception - null if the script executed successfully without throwing any exceptions, otherwise this is the exception thrown by the script
        Returns:
        the script result; this may be a list of results, a single object, or null. If multiple commands/subcommands were executed, this method may return a List, which may contain some null values. For a single command, this method will return the return value of the script, which is often the value of the last expression in the script.
      • getScriptArguments

        public String[] getScriptArguments()
        Returns the script arguments as an array of strings. The default implementation is to get the "args" property.
        Returns:
        the script arguments as an array of strings.
      • getOrCreateCommandLine

        protected CommandLine getOrCreateCommandLine()
        Returns the CommandLine for this script. If there isn't one already, then this method returns the result of the createCommandLine() method.
        Returns:
        the CommandLine for this script.
      • beforeParseArgs

        protected CommandLine beforeParseArgs​(CommandLine customizable)
        Customizes the specified CommandLine instance to set a custom IParameterExceptionHandler and a custom IExecutionExceptionHandler, subclasses can override to customize further.

        This method replaces the default IParameterExceptionHandler with a custom one that prints the command line arguments before calling the default parameter exception handler.

        This method replaces the default IExecutionExceptionHandler with a custom one that stores any exception that occurred during execution into the exception property of this script, and returns the configured exit code. This exception is later passed to the afterExecution(CommandLine, int, Exception) method.

        Parameters:
        customizable - the CommandLine instance that models this command and its subcommands
        Returns:
        the customized CommandLine instance (usually, but not necessarily, the same instance as the method parameter)
      • createCommandLine

        public CommandLine createCommandLine()
        Create and returns a new CommandLine instance. This method sets the command name in the usage help message to the script's class simple name (unless annotated with some other command name with the @Command(name = "...") annotation).

        Subclasses may override to register custom type converters or programmatically add subcommands.

        Returns:
        A CommandLine instance.