Picocli is a modern framework for building powerful, user-friendly, GraalVM-enabled command line apps with ease. It supports colors, autocompletion, subcommands, and more. In 1 source file so apps can include as source & avoid adding a dependency. Written in Java, usable from Groovy, Kotlin, Scala, etc.

Overview

picocli

GitHub Release Build Status codecov Follow @remkopopma Follow @picocli Follow picocli on StackShare

picocli - a mighty tiny command line interface

Picocli aims to be the easiest-to-use way to create rich command line applications that can run on and off the JVM. Considering picocli? Check what happy users say about picocli.

Picocli is a modern library and framework, written in Java, that contains both an annotations API and a programmatic API. It features usage help with ANSI colors and styles, TAB autocompletion and nested subcommands. In a single file, so you can include it in source form. This lets users run picocli-based applications without requiring picocli as an external dependency.

Picocli-based applications can be ahead-of-time compiled to a GraalVM native image, with extremely fast startup time and lower memory requirements, which can be distributed as a single executable file. Picocli comes with an annotation processor that automatically Graal-enables your jar during compilation.

Picocli applications can be very compact with no boilerplate code: your command (or subcommand) can be executed with a single line of code. Simply implement Runnable or Callable, or put the business logic of your command in a @Command-annotated method.

Picocli Demo help message with ANSI colors

Picocli makes it easy to follow Command Line Interface Guidelines.

How it works: annotate your class and picocli initializes it from the command line arguments, converting the input to strongly typed data. Supports git-like subcommands (and nested sub-subcommands), any option prefix style, POSIX-style grouped short options, custom type converters, password options and more.

Picocli distinguishes between named options and positional parameters and allows both to be strongly typed. Multi-valued fields can specify an exact number of parameters or a range (e.g., 0..*, 1..2). Supports Map options like -Dkey1=val1 -Dkey2=val2, where both key and value can be strongly typed. Parser tracing facilitates troubleshooting. Command-line argument files (@-files) allow applications to handle very long command lines.

Generates polished and easily tailored usage help and version help, using ANSI colors where possible. Requires at minimum Java 5, but is designed to facilitate the use of Java 8 lambdas. Tested on all Java versions between 5 and 15-ea (inclusive).

Picocli-based command line applications can have TAB autocompletion, interactively showing users what options and subcommands are available. When an option has completionCandidates or has an enum type, autocompletion can also suggest option values. Picocli can generate completion scripts for bash and zsh, and offers picocli-shell-jline2 and picocli-shell-jline3 modules with JLine Completer implementations for building interactive shell applications.

Unique features in picocli include support for negatable options, advanced quoted values, and argument groups. Argument groups can be used to create mutually exclusive options, mutually dependent options, option sections in the usage help message and repeating composite arguments like ([-a=<a> -b=<b> -c=<c>] (-x | -y | -z)).... For advanced use cases, applications can access the picocli command object model with the @Spec annotation, and implement custom parameter processing for option parameters if the built-in logic is insufficient.

Picocli-based applications can easily integrate with Dependency Injection containers. The Micronaut microservices framework has built-in support for picocli. Picocli ships with a picocli-spring-boot-starter module that includes a PicocliSpringFactory and Spring Boot auto-configuration to use Spring dependency injection in your picocli command line application. The user manual has examples of integrating with Guice, Spring Boot, Micronaut, Quarkus and with containers that comply to CDI 2.0 specification (JSR 365).

Releases

Documentation

Older

Articles & Presentations

English

русский

Español

Français

Português

日本語

中文

Mailing List

Join the picocli Google group if you are interested in discussing anything picocli-related and receiving announcements on new releases.

Credit

Reallinfo designed the new picocli logo! Many thanks!

Commitments

This project follows semantic versioning and adheres to the Zero Bugs Commitment.

Adoption

  • Picocli is now part of Groovy. From Groovy 2.5, all Groovy command line tools are picocli-based, and picocli is the underlying parser for Groovy's CliBuilder DSL.
  • Picocli is now part of Micronaut. The Micronaut CLI has been rewritten with picocli, and Micronaut has dedicated support for running microservices standalone with picocli.
  • Picocli is now part of JUnit 5. JUnit 5.3 migrated its ConsoleLauncher from jopt-simple to picocli to support @-files (argument files); this helps users who need to specify many tests on the command line and run into system limitations.
  • Debian now offers a libpicocli-java package. Thanks to Miroslav Kravec.
  • Picocli is used in the Intuit Karate standalone JAR / executable.
  • Picocli is part of Ballerina. Ballerina uses picocli for all its command line utilities.
  • Picocli is used in the CheckStyle standalone JAR / executable from Checkstyle 8.15.
  • Picocli is included in the OpenJDK Quality Outreach list of Free Open Source Software (FOSS) projects that actively test against OpenJDK builds.
  • Picocli is used in the Apache Hadoop Ozone/HDDS command line tools, the Apache Hive benchmark CLI, Apache Ignite TensorFlow, and Apache Sling Feature Model Converter.
  • Picocli is listed on StackShare. Please add it to your stack and add/upvote reasons why you like picocli!
  • Picocli is used in Pinterest ktlint.
  • Picocli is used in Spring IO nohttp-cli.
  • The MinecraftPicocli library allows the use of picocli in Minecraft Forge.
  • Simple Java Mail now offers a picocli-based CLI.
  • jbang not only uses picocli internally, but also has a CLI template to generate an initial script: use jbang --init=cli helloworld.java to generate a sample picocli-enabled jbang script. See asciinema.
  • Picocli is the main library used in the CookieTemple cli-java template for building GraalVM native CLI executables in Java. See this preview.
  • Picocli is mentioned in Command Line Interface Guidelines.

Glad to see more people are using picocli. We must be doing something right. :-)

Help to promote picocli

If you like picocli, there are a few things you can do to help:

  • Give picocli a star on GitHub!
  • Tweet about picocli! What do you like about it? How has it helped you? How is it different from the alternatives?
  • Upvote my Quora answer to "What is the best way to parse command-line arguments with Java?"
  • Upvote my StackOverflow answer to "How do I parse command line arguments in Java?"

If you like picocli and your project is on GitHub, consider adding this badge to your README.md: picocli

[![picocli](https://img.shields.io/badge/picocli-4.6.1-green.svg)](https://github.com/remkop/picocli)

Example

Annotate fields with the command line parameter names and description. Optionally implement Runnable or Callable to delegate error handling and requests for usage help or version help to picocli. For example:

import picocli.CommandLine;
import picocli.CommandLine.Option;
import picocli.CommandLine.Parameters;
import java.io.File;

@Command(name = "example", mixinStandardHelpOptions = true, version = "Picocli example 4.0")
public class Example implements Runnable {

    @Option(names = { "-v", "--verbose" },
      description = "Verbose mode. Helpful for troubleshooting. Multiple -v options increase the verbosity.")
    private boolean[] verbose = new boolean[0];

    @Parameters(arity = "1..*", paramLabel = "FILE", description = "File(s) to process.")
    private File[] inputFiles;
    
    public void run() {
        if (verbose.length > 0) {
            System.out.println(inputFiles.length + " files to process...");
        }
        if (verbose.length > 1) {
            for (File f : inputFiles) {
                System.out.println(f.getAbsolutePath());
            }
        }
    }
    
    public static void main(String[] args) {
        // By implementing Runnable or Callable, parsing, error handling and handling user
        // requests for usage help or version help can be done with one line of code.

        int exitCode = new CommandLine(new Example()).execute(args);
        System.exit(exitCode);
    }
}

Implement Runnable or Callable, and your command can be executed in one line of code. The example above uses the CommandLine.execute method to parse the command line, handle errors, handle requests for usage and version help, and invoke the business logic. Applications can call System.exit with the returned exit code to signal success or failure to their caller.

$ java Example -v inputFile1 inputFile2

2 files to process...

The CommandLine.execute method automatically prints the usage help message if the user requested help or when the input was invalid.

Usage help message with ANSI colors

This can be customized in many ways. See the user manual section on Executing Commands for details.

Usage Help with ANSI Colors and Styles

Colors, styles, headers, footers and section headings are easily customized with annotations. For example:

Longer help message with ANSI colors

See the source code.

Usage Help API

Picocli annotations offer many ways to customize the usage help message.

If annotations are not sufficient, you can use picocli's Help API to customize even further. For example, your application can generate help like this with a custom layout:

Usage help message with two options per row

See the source code.

Download

You can add picocli as an external dependency to your project, or you can include it as source. See the source code. Copy and paste it into a file called CommandLine.java, add it to your project, and enjoy!

Gradle

implementation 'info.picocli:picocli:4.6.1'

Maven

<dependency>
  <groupId>info.picocli</groupId>
  <artifactId>picocli</artifactId>
  <version>4.6.1</version>
</dependency>

Scala SBT

libraryDependencies += "info.picocli" % "picocli" % "4.6.1"

Ivy

<dependency org="info.picocli" name="picocli" rev="4.6.1" />

Grape

@Grapes(
    @Grab(group='info.picocli', module='picocli', version='4.6.1')
)

Leiningen

[info.picocli/picocli "4.6.1"]

Buildr

'info.picocli:picocli:jar:4.6.1'

JBang

//DEPS info.picocli:picocli:4.6.1
Comments
  • Provide convenience API for global options (was: Feature request: inheriting mixins in subcommands)

    Provide convenience API for global options (was: Feature request: inheriting mixins in subcommands)

    I made a base class BaseCliApplication that all my CLI applications will extend. The base class does all the special picocli setup needed and other things for CLI applications. The class adds a --debug option that turns on debug-level logging:

    /**
     * Enables or disables debug mode, which is disabled by default.
     * @param debug The new state of debug mode.
     */
    @Option(names = {"--debug", "-d"}, description = "Turns on debug level logging.")
    protected void setDebug(final boolean debug) {
      …
    }
    

    Unfortunately in my Foo CLI application subclass, I introduce a subcommand bar using a method:

    @Command(description = "Do the bar thing.")
    public void bar(…) {
      …
    }
    

    Picocli doesn't seem to pick up the --debug switch in the subcommand. If I attempt to use the command foo bar, it tells me:

    Unknown option: --debug
    Usage: foo bar
    Do the bar thing.
    

    Is there a @Command parameter that I can use to say "this switch applies to all subcommands"? Or is there a way to specify for a subcommand that the --debug switch should work for it as well?

    I looked for documentation for mixins, but I only found information on how to include them if they are already defined. I'm not sure how to define a mixin. How can I say that the setDebug() method is a mixin? (Frankly I'd rather use the first approach: some way to say "this switch applies to all subcommands".)

    Thanks in advance.

    type: enhancement :sparkles: type: API :electric_plug: 
    opened by garretwilson 67
  • Add module picocli-jpms (was: Include module-info.class for full JPMS modularization and jlink support)

    Add module picocli-jpms (was: Include module-info.class for full JPMS modularization and jlink support)

    Currently the picocli jar is an automatic module (manifest has Automatic-Module-Name: info.picocli).

    A JLink trimmed binary image needs explicit modules. This means the jar needs to include a module-info.class.

    Update: this is a common misunderstanding. See the comment below for a tutorial for creating a JLink binary image with an automatic module.

    module-info.class trade-offs

    It is possible to compile only the module-info.java file with Java 9 and include it in the picocli jar where all other classes are compiled with Java 5.

    However, there are quite a few tools that scan all classes in a Jar and that would choke on the module-info.class (whether it is in the root of the jar or in META-INF/versions/9/). For example: jandex, and Apache Commons BCEL.

    Consider producing a picocli-jpms-3.x.x.jar that has the same contents as picocli-3.x.x.jar but in addition a module-info.class. Users looking to create a JLink custom runtime image can use the picocli-jpms jar.

    Solution

    The comment below is a brief tutorial for creating a JLink binary image with an automatic module. No module-info.class required in picocli or in the application.

    Todo: do a more formal write-up and add it to the picocli documentation.

    type: enhancement :sparkles: type: doc :blue_book: theme: module 
    opened by remkop 61
  • Support for interactive shell using picocli

    Support for interactive shell using picocli

    Just started using picocli for a simple command line app, and find it amazingly easy to use and cool. I have also been experimenting with having interactive shell in my program which once launched will also allow execution of several subcommands. I am using cliche for this. Though it seems like picocli should be already able to handle this. Am I missing some obvious way of putting CommandLine in a loop to continuously parse for subcommands.

    Happy to contribute if there is an agreeable change which could make it work that way.

    status: help-wanted theme: shell 
    opened by anshunjain 47
  • (WIP)  Add support for quoting parameters

    (WIP) Add support for quoting parameters

    This adds a class (CommandTokenzer) that takes text, and splits it based on customizable whitespace characters, and has support for quoting/escaping spaces with customizable quote and escape characters. The methods are intended to be similar to that of StreamTokenizer (hence the name). See here for some more details.

    Note that currently the class is not used, as it is not finalized yet and (as I mentioned in the issue) I have to edit CommandLine.java with a normal text editor, not my IDE, so it is easier to keep it separate until completion.

    opened by BeeeWall 42
  • Customize value assigned when option specified without value

    Customize value assigned when option specified without value

    The goal of the feature request is to provide the ability to specify a custom value to be used when a command line option is specified without any value.

    See #279.

    type: enhancement :sparkles: type: API :electric_plug: 
    opened by pditommaso 41
  • API to know all the commands

    API to know all the commands

    Looking for an API to know all the commands defined. This can be helpful to print help message of all the commands in case customer asks for global help of all the commands

    type: question :grey_question: status: declined type: doc :blue_book: type: API :electric_plug: 
    opened by nagkumar 36
  • Add useful error messages when using list of arguments

    Add useful error messages when using list of arguments

    When having a list of arguments of a certain type, and the type conversion fails at one argument the TypeConversionException is converted to a UnmachedException - leading to a generic error text such as; Unmatched argument at index 2: 'Bad input'. I made a small example to show the different cases:

    public class BadErrorMsg {
    	
    	// Case 1
    	@Option(names="-t",
    			split="\\s",
    			converter = MyConverter.class
    			)
    	public List<MyType> args;
    	
    	// Case 2
    //	@Option(names="-t",
    //			converter = MyConverter.class
    //			)
    //	public MyType args;
    	
    	static class MyType {
    		
    		String lowCaseStr;
    		
    		private MyType(String txt){
    			lowCaseStr = txt;
    		}
    		
    		public static class MyConverter implements ITypeConverter<MyType>{
    
    			@Override
    			public MyType convert(String arg) throws Exception {
    				if (!arg.toLowerCase().equals(arg))
    					throw new TypeConversionException("Text must be lower case");
    				
    				return new MyType(arg);
    			}
    			
    		}
    		public String toString() {return lowCaseStr;}
    	}
    	
    	public static void main(String[] args) {
    		BadErrorMsg msgs = new BadErrorMsg();
    		// Case 1 - list
    		new CommandLine(msgs).execute("-t","some txt", "Bad input");
    //		Results in message: Unmatched argument at index 2: 'Bad input'
    		// Case 2 - single argument
    //		new CommandLine(msgs).execute("-t","Bad input");
    //		Results in message: Invalid value for option '-t' (<args>): Text must be lower case
    
    	}
    
    }
    

    It would be useful to have a way to discern between what is a truly unmatched input (e.g. a miss-spelled argument that is sent to the ITypeConverter by mistake) and simply that the input is poorly formatted. I understand that in the general case this might be hard to tell, but if the ITypeConverter have the logic to decide between the two cases it can give a better/more useful help text. Furthermore, if the 'Bad input' is given as the first argument to -t it will provide the more useful error message and not the Unmatched message.

    type: enhancement :sparkles: type: question :grey_question: theme: parser 
    opened by StaffanArvidsson 30
  • Allow repeatable subcommands?

    Allow repeatable subcommands?

    I came here looking for a solution for a problem similar to #358 - the need for a syntax for lists of multi-field entries - but had a different solution in mind. These solutions are not mutually exclusive, so I elected to open a new ticket for it.

    My idea is to have repeatable subcommands. So - if we take the example from #358 - print will be the main command and have, say, file as a subcommand. We will write it like so:

    print --paper A4 \
        file A.pdf \
        file B.pdf --count 3 \
        file C.pdf --count 3 --rotate left \
        file D.pdf \
        file E.pdf --rotate right
    

    This will create 6 CommandLine objects:

    • PrintCommand(paper = "A4")
    • FileCommand(name = "A.pdf", count = , rotate = )
    • FileCommand(name = "B.pdf", count = 3, rotate = )
    • FileCommand(name = "C.pdf", count = 3, rotate = "left")
    • FileCommand(name = "D.pdf", count = , rotate = )
    • FileCommand(name = "E.pdf", count = , rotate = "right")

    A bit more verbose than @kravemir's original syntax (since you need to specify the options for each file) but much more readable IMHO.

    I tried to do it by making file a subcommand of itself:

    CommandLine printCommand = new CommandLine(new PrintCommand());
    CommandLine fileCommand = new CommandLine(new FileCommand());
    printCommand.addSubcommand(fileCommand);
    fileCommand.addSubcommand(fileCommand);
    

    And it did parse that command line - but it was always using the same FileCommand object so I only got E.pdf's parameters. Maybe if a CommandLine could receive a factory for objects, and construct a new one for each subcommand it parses?

    type: enhancement :sparkles: type: API :electric_plug: theme: parser 
    opened by idanarye 30
  • Add abbreviation recognition for subcommands and options

    Add abbreviation recognition for subcommands and options

    Currently using code snippet from @remkop #732 with minor changes.

    For ease of debugging, the AbbreviationMatcher class ~~is in separate file for now~~.

    ~~This is a draft, no javadoc are added yet, and tests may not cover all cases~~.

    Feedbacks are welcomed!

    This draft's goal is to resolve #10 and resolve #732.

    Edit: All javadoc have been added, and diff coverage is 94.79%.

    type: enhancement :sparkles: type: API :electric_plug: theme: parser 
    opened by NewbieOrange 29
  • When compiling to a native image with Graal, no colors are shown

    When compiling to a native image with Graal, no colors are shown

    I've managed to compile my Java-based CLI with Graal following the steps described in

    https://picocli.info/picocli-on-graalvm.html

    It works great, except for one thing: when the help is shown, no colors are displayed.

    image

    This is the same output produced by the JAR.

    image

    type: bug :bug: 
    opened by helpermethod 29
  • AutoComplete Command not found

    AutoComplete Command not found

    Hello and thank you for this beautiful library. I am new to picocli, so I want to implement a menu with autocomplete possibility. My code is the following :

    @Command(name = "licenserES", version = "Help demo v1.0.0", header = "%nAutomatic License Helper%n",
            description = "Prints usage help and version help when requested.%n",
            subcommands = {GenerateKey.class, Sign.class, Verify.class})
    public class LicenseCommandLine implements Callable<Void> {
    
        @Option(names = {"--help", "-h"}, usageHelp = true, description = "Print usage help and exit.")
        boolean help;
        @Option(names = {"--generateKey", "-g"}, description = "Generates a key.")
        boolean gk;
        @Option(names = {"--sign", "-s"}, description = "Signs the license.")
        boolean sl;
        @Option(names = {"--verify", "-v"}, description = "Verifies the license.")
        boolean v;
        @Option(names = {"--exit", "-e"}, description = "Exit the app.")
        boolean exit;
    
        public static void main(String[] args) {
            args = new String[]{"--help" };
            LicenseCommandLine licenseCommandLine = new LicenseCommandLine();
            new CommandLine(licenseCommandLine).parseWithHandler(new RunAll(), args);
        }
    
        @Override
        public Void call() {
            System.out.println("Menu LicenseCLI");
            return null;
        }
    }
    

    When I run this class from IDE, it works fine, it shows me the menu:

    Automatic License Helper
    
    Usage: licenserES [-eghsv] [COMMAND]
    Prints usage help and version help when requested.
    
      -e, --exit          Exit the app.
      -g, --generateKey   Generates a key.
      -h, --help          Print usage help and exit.
      -s, --sign          Signs the license.
      -v, --verify        Verifies the license.
    Commands:
      --generateKey  Generate the Key.
      --sign         Sign the license.
      --verify       Verify license passed as an argument
    

    After I generated my licenserES_completion, and the source of this script. AutoComplete works fine if a write licenserES ---> it will show me these options, but if I type licenserES --help ...it keeps saying licenserES command not found. Any sugestions on this? Or maybe you have a good example. Thanks in advance !

    type: question :grey_question: 
    opened by mrdantutunaru 28
  • Bump kotlin-gradle-plugin from 1.7.20 to 1.8.0

    Bump kotlin-gradle-plugin from 1.7.20 to 1.8.0

    Bumps kotlin-gradle-plugin from 1.7.20 to 1.8.0.

    Release notes

    Sourced from kotlin-gradle-plugin's releases.

    Kotlin 1.8.0-RC2

    Changelog

    Compiler

    • KT-55357 IllegalStateException when reading a class that delegates to a Java class with a definitely-not-null type with a flexible upper bound
    • KT-55068 Kotlin Gradle DSL: No mapping for symbol: VALUE_PARAMETER SCRIPT_IMPLICIT_RECEIVER on JVM IR backend
    • KT-51284 SAM conversion doesn't work if method has context receivers
    • KT-55065 Kotlin Gradle DSL: Reflection cannot find class data for lambda, produced by JVM IR backend

    Tools. Compiler plugins. Serialization

    • KT-55340 Argument for kotlinx.serialization.UseSerializers does not implement KSerializer or does not provide serializer for concrete type

    Tools. Gradle

    • KT-55334 kaptGenerateStubs passes wrong android variant module names to compiler
    • KT-55255 Gradle: stdlib version alignment fails build on dynamic stdlib version.
    • KT-55363 [K1.8.0-Beta] Command line parsing treats plugin parameters as source files

    Checksums

    File Sha256
    kotlin-compiler-1.8.0-RC2.zip 149492cac31a94e8ee5173035520bb31286f6f6eb004cc0306b47127f7a72ce9
    kotlin-native-linux-x86_64-1.8.0-RC2.tar.gz 859031d2f8dc86398a3484a9103eea3dffbe546be658063bff69913c2d1d7233
    kotlin-native-macos-x86_64-1.8.0-RC2.tar.gz cb25632ddc061c04a0a7a23a3afdf9dcc5a8c5d4a536fd8b5396be700ad87b38
    kotlin-native-macos-aarch64-1.8.0-RC2.tar.gz 9ba55a4e4ca3fc263d9758bd5f5ded732c0ef53fae7920a495715907c9a43c33
    kotlin-native-windows-x86_64-1.8.0-RC2.zip 2c6a2b11523929563845b945faa8b7c481727d0408d18e41dcd48bf6bdf7e570

    Kotlin 1.8.0-RC

    Changelog

    Compiler

    • KT-55108 IR interpreter: Error occurred while optimizing an expression: VARARG
    • KT-54884 "StackOverflowError: null" caused by Enum constant name in constructor of the same Enum constant
    • KT-55013 State checker use-after-free with XCode 14.1
    • KT-54275 K2: "IllegalArgumentException: KtParameter is not a subtype of class KtAnnotationEntry for factory REPEATED_ANNOTATION"

    JavaScript

    • KT-55097 KJS / IR + IC: Using an internal function from a friend module throws an unbound symbol exception
    • KT-54934 KJS / IR + IC: Suspend abstract function stubs are generated with unstable lowered ic signatures
    • KT-54895 KJS / IR + IC: broken cross module references for function default param wrappers

    Language Design

    • KT-48516 Forbid @Synchronized annotation on suspend functions

    ... (truncated)

    Changelog

    Sourced from kotlin-gradle-plugin's changelog.

    1.7.21

    Compiler

    • KT-54463 Delegating to a field with a platform type causes java.lang.NoSuchFieldError: value$delegate
    • KT-54509 Ir Interpreter: unable to evaluate string concatenation with "this" as argument
    • KT-54004 Builder type inference does not work correctly with variable assignment and breaks run-time
    • KT-54393 Change in behavior from 1.7.10 to 1.7.20 for java field override.
    • KT-54615 JVM: Internal error in file lowering: java.lang.AssertionError: Error occurred while optimizing an expression
    • KT-54581 JVM: "VerifyError: Bad type on operand stack" with generic inline function and when inside try-catch block
    • KT-53146 JVM IR: unnecessary checkcast of null leads to NoClassDefFoundError if the type isn't available at runtime
    • KT-54600 NPE on passing nullable Kotlin lambda as Java's generic SAM interface with super type bound
    • KT-54707 "VerifyError: Bad type on operand stack" in inline call chain on a nullable array value
    • KT-54650 Binary incompatible ABI change in Kotlin 1.7.20
    • KT-54802 "VerifyError: Bad type on operand stack" for inline functions on arrays

    Native. Runtime. Memory

    • KT-54498 Deprecation message of 'FreezingIsDeprecated' is not really helpful

    Tools. Gradle. Multiplatform

    • KT-54387 Remove MPP alpha stability warning
    • KT-48436 False positive "The Kotlin source set androidAndroidTestRelease was configured but not added to any Kotlin compilation"

    Tools. JPS

    • KT-45474 False positive NO_ELSE_IN_WHEN on sealed class with incremental compilation
    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    type: dependency :books: java 
    opened by dependabot[bot] 0
  • Bump kotlin-script-runtime from 1.7.20 to 1.8.0

    Bump kotlin-script-runtime from 1.7.20 to 1.8.0

    Bumps kotlin-script-runtime from 1.7.20 to 1.8.0.

    Release notes

    Sourced from kotlin-script-runtime's releases.

    Kotlin 1.8.0-RC2

    Changelog

    Compiler

    • KT-55357 IllegalStateException when reading a class that delegates to a Java class with a definitely-not-null type with a flexible upper bound
    • KT-55068 Kotlin Gradle DSL: No mapping for symbol: VALUE_PARAMETER SCRIPT_IMPLICIT_RECEIVER on JVM IR backend
    • KT-51284 SAM conversion doesn't work if method has context receivers
    • KT-55065 Kotlin Gradle DSL: Reflection cannot find class data for lambda, produced by JVM IR backend

    Tools. Compiler plugins. Serialization

    • KT-55340 Argument for kotlinx.serialization.UseSerializers does not implement KSerializer or does not provide serializer for concrete type

    Tools. Gradle

    • KT-55334 kaptGenerateStubs passes wrong android variant module names to compiler
    • KT-55255 Gradle: stdlib version alignment fails build on dynamic stdlib version.
    • KT-55363 [K1.8.0-Beta] Command line parsing treats plugin parameters as source files

    Checksums

    File Sha256
    kotlin-compiler-1.8.0-RC2.zip 149492cac31a94e8ee5173035520bb31286f6f6eb004cc0306b47127f7a72ce9
    kotlin-native-linux-x86_64-1.8.0-RC2.tar.gz 859031d2f8dc86398a3484a9103eea3dffbe546be658063bff69913c2d1d7233
    kotlin-native-macos-x86_64-1.8.0-RC2.tar.gz cb25632ddc061c04a0a7a23a3afdf9dcc5a8c5d4a536fd8b5396be700ad87b38
    kotlin-native-macos-aarch64-1.8.0-RC2.tar.gz 9ba55a4e4ca3fc263d9758bd5f5ded732c0ef53fae7920a495715907c9a43c33
    kotlin-native-windows-x86_64-1.8.0-RC2.zip 2c6a2b11523929563845b945faa8b7c481727d0408d18e41dcd48bf6bdf7e570

    Kotlin 1.8.0-RC

    Changelog

    Compiler

    • KT-55108 IR interpreter: Error occurred while optimizing an expression: VARARG
    • KT-54884 "StackOverflowError: null" caused by Enum constant name in constructor of the same Enum constant
    • KT-55013 State checker use-after-free with XCode 14.1
    • KT-54275 K2: "IllegalArgumentException: KtParameter is not a subtype of class KtAnnotationEntry for factory REPEATED_ANNOTATION"

    JavaScript

    • KT-55097 KJS / IR + IC: Using an internal function from a friend module throws an unbound symbol exception
    • KT-54934 KJS / IR + IC: Suspend abstract function stubs are generated with unstable lowered ic signatures
    • KT-54895 KJS / IR + IC: broken cross module references for function default param wrappers

    Language Design

    • KT-48516 Forbid @Synchronized annotation on suspend functions

    ... (truncated)

    Changelog

    Sourced from kotlin-script-runtime's changelog.

    1.7.21

    Compiler

    • KT-54463 Delegating to a field with a platform type causes java.lang.NoSuchFieldError: value$delegate
    • KT-54509 Ir Interpreter: unable to evaluate string concatenation with "this" as argument
    • KT-54004 Builder type inference does not work correctly with variable assignment and breaks run-time
    • KT-54393 Change in behavior from 1.7.10 to 1.7.20 for java field override.
    • KT-54615 JVM: Internal error in file lowering: java.lang.AssertionError: Error occurred while optimizing an expression
    • KT-54581 JVM: "VerifyError: Bad type on operand stack" with generic inline function and when inside try-catch block
    • KT-53146 JVM IR: unnecessary checkcast of null leads to NoClassDefFoundError if the type isn't available at runtime
    • KT-54600 NPE on passing nullable Kotlin lambda as Java's generic SAM interface with super type bound
    • KT-54707 "VerifyError: Bad type on operand stack" in inline call chain on a nullable array value
    • KT-54650 Binary incompatible ABI change in Kotlin 1.7.20
    • KT-54802 "VerifyError: Bad type on operand stack" for inline functions on arrays

    Native. Runtime. Memory

    • KT-54498 Deprecation message of 'FreezingIsDeprecated' is not really helpful

    Tools. Gradle. Multiplatform

    • KT-54387 Remove MPP alpha stability warning
    • KT-48436 False positive "The Kotlin source set androidAndroidTestRelease was configured but not added to any Kotlin compilation"

    Tools. JPS

    • KT-45474 False positive NO_ELSE_IN_WHEN on sealed class with incremental compilation
    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    type: dependency :books: java 
    opened by dependabot[bot] 0
  • Support fallbackValue with arity=

    Support fallbackValue with arity="0..*"

    Please support fallbackValue with "zero-based" arities other than 0..1, in particular with 0..*.

    To see why this might be useful, consider the following @Option definition:

    enum DebugFacility { FOO, BAR, BAZ, ALL }
    
    @Option(
        names = { "--debug" },
        paramLabel = "FACILITY", //
        split = ",",
        arity = "0..*", //
        fallbackValue = "ALL", //
        description = "The facilities for which to log debug information (one or more of ${COMPLETION-CANDIDATES}). "
            + "If none are given, debug information will be logged for ${FALLBACK-VALUE} categories.")
    public void setDebugFacilities(Collection<DebugFacility> facilities) { ... }
    

    This should support the following scenarios

    --debug FOO               -> FOO
    --debug FOO --debug BAR   -> FOO, BAR
    --debug FOO,BAR           -> FOO, BAR
    --debug all               -> ALL (i.e., FOO, BAR, BAZ)
    --debug                   -> ALL (i.e., FOO, BAR, BAZ)
    

    The last one unfortunately doesn't work, as the fallbackValue does not get passed to setDebugFacilities; it merely gets an empty facilities Collection.

    And we can't insert ALL programmatically in setDebugFacilities, either. To see why, consider the following scenario:

    --debug FOO --debug       -> ALL (i.e., FOO, BAR, BAZ)
    

    Here, the parameterless --debug simply results in another call of setDebugFacilities with FOO as single parameter. In other words, one cannot detect the parameterless case

    Maybe there is a workaround that I am unable to see, but IMHO fallbackValue support for any "zero-based" arity might be the most idiomatic solution. WDYT?

    opened by sewe 6
  • Bump ossf/scorecard-action from 2.0.6 to 2.1.2

    Bump ossf/scorecard-action from 2.0.6 to 2.1.2

    Bumps ossf/scorecard-action from 2.0.6 to 2.1.2.

    Release notes

    Sourced from ossf/scorecard-action's releases.

    v2.1.2

    What's Changed

    Fixes

    Full Changelog: https://github.com/ossf/scorecard-action/compare/v2.1.1...v2.1.2

    v2.1.1

    Scorecard version

    This release use Scorecard's v4.10.1

    Full Changelog: https://github.com/ossf/scorecard-action/compare/v2.1.0...v2.1.1

    v2.1.0

    What's Changed

    Scorecard version

    This release uses scorecard v4.10.0.

    Improvements

    Documentation

    New Contributors

    Full Changelog: https://github.com/ossf/scorecard-action/compare/v2.0.6...v2.1.0

    Commits
    • e38b190 Bump docker tag for release. (#1055)
    • 7da02bf Bump scorecard to v4.10.2 to remove a CODEOWNERS printf statement. (#1054)
    • 013c0f8 :seedling: Bump actions/dependency-review-action from 3.0.1 to 3.0.2
    • f93c094 :seedling: Bump github/codeql-action from 2.1.36 to 2.1.37
    • ce8978e :seedling: Bump actions/upload-artifact from 3.1.0 to 3.1.1
    • 5ce49db :seedling: Bump actions/setup-go from 3.4.0 to 3.5.0
    • 15c10fc Update tag to v2.1.1 (#1047)
    • f96da1a :seedling: Update scorecard for the panic (#1045)
    • 813a825 Complete the list of required actions (#1044)
    • be62ea8 Update RELEASE.md (#1042)
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    type: dependency :books: github_actions 
    opened by dependabot[bot] 0
  • Bump github/codeql-action from 2.1.29 to 2.1.37

    Bump github/codeql-action from 2.1.29 to 2.1.37

    Bumps github/codeql-action from 2.1.29 to 2.1.37.

    Changelog

    Sourced from github/codeql-action's changelog.

    CodeQL Action Changelog

    [UNRELEASED]

    No user facing changes.

    2.1.37 - 14 Dec 2022

    • Update default CodeQL bundle version to 2.11.6. #1433

    2.1.36 - 08 Dec 2022

    • Update default CodeQL bundle version to 2.11.5. #1412
    • Add a step that tries to upload a SARIF file for the workflow run when that workflow run fails. This will help better surface failed code scanning workflow runs. #1393
    • Python automatic dependency installation will no longer consider dependecy code installed in venv as user-written, for projects using Poetry that specify virtualenvs.in-project = true in their poetry.toml. #1419.

    2.1.35 - 01 Dec 2022

    No user facing changes.

    2.1.34 - 25 Nov 2022

    • Update default CodeQL bundle version to 2.11.4. #1391
    • Fixed a bug where some the init action and the analyze action would have different sets of experimental feature flags enabled. #1384

    2.1.33 - 16 Nov 2022

    • Go is now analyzed in the same way as other compiled languages such as C/C++, C#, and Java. This completes the rollout of the feature described in CodeQL Action version 2.1.27. #1322
    • Bump the minimum CodeQL bundle version to 2.6.3. #1358

    2.1.32 - 14 Nov 2022

    • Update default CodeQL bundle version to 2.11.3. #1348
    • Update the ML-powered additional query pack for JavaScript to version 0.4.0. #1351

    2.1.31 - 04 Nov 2022

    • The rb/weak-cryptographic-algorithm Ruby query has been updated to no longer report uses of hash functions such as MD5 and SHA1 even if they are known to be weak. These hash algorithms are used very often in non-sensitive contexts, making the query too imprecise in practice. For more information, see the corresponding change in the github/codeql repository. #1344

    2.1.30 - 02 Nov 2022

    • Improve the error message when using CodeQL bundle version 2.7.2 and earlier in a workflow that runs on a runner image such as ubuntu-22.04 that uses glibc version 2.34 and later. #1334

    2.1.29 - 26 Oct 2022

    • Update default CodeQL bundle version to 2.11.2. #1320

    2.1.28 - 18 Oct 2022

    • Update default CodeQL bundle version to 2.11.1. #1294

    ... (truncated)

    Commits
    • 959cbb7 Merge pull request #1436 from github/update-v2.1.37-d58039a1
    • 10ca836 Update changelog for v2.1.37
    • d58039a Merge pull request #1435 from github/orhantoy/add-CODE_SCANNING_REF-tests
    • 37a4496 Merge pull request #1433 from github/henrymercer/use-codeql-2.11.6
    • b7028af Make sure env is reset between tests
    • f629dad Merge branch 'main' into henrymercer/use-codeql-2.11.6
    • ccee4c6 Add tests for CODE_SCANNING_REF
    • 899bf9c Merge pull request #1432 from github/henrymercer/init-post-telemetry
    • dd7c3ef Remove debugging log statements
    • b7b875e Reuse existing fields in post-init status report
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    type: dependency :books: github_actions 
    opened by dependabot[bot] 0
  • Bump actions/setup-java from 3.6.0 to 3.9.0

    Bump actions/setup-java from 3.6.0 to 3.9.0

    Bumps actions/setup-java from 3.6.0 to 3.9.0.

    Release notes

    Sourced from actions/setup-java's releases.

    v3.9.0

    In scope of this release we add support for .java-version file (actions/setup-java#426). For more information about its usage please refer to the documentation.

        steps:
          - uses: actions/checkout@v3
          - name: Setup java
            uses: actions/setup-java@v3
            with:
              distribution: '<distribution>'
              java-version-file: .java-version
          - run: java HelloWorldApp.java
    

    v3.8.0

    In scope of this release we added logic to pass the token input through on GHES for Microsoft Build of OpenJDK (actions/setup-java#395) and updated minimatch dependency.

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    type: dependency :books: github_actions 
    opened by dependabot[bot] 0
Releases(v4.7.0)
  • v4.7.0(Oct 31, 2022)

    Picocli 4.7.0

    The picocli community is pleased to announce picocli 4.7.0.

    This release includes bugfixes and enhancements.

    A potentially breaking change is that the parser now treats char[] as a single-value type.

    From this release, applications can programmatically set the trace level, and use tracing in custom components.

    Applications can improve startup time by setting system property picocli.disable.closures to true to disable support for closures in annotations.

    Many more fixes and enhancements, see the sections below for more details.

    This is the seventy-ninth public release. Picocli follows semantic versioning. Artifacts in this release are signed by Remko Popma (6601 E5C0 8DCC BB96).

    Table of Contents

    New and Noteworthy

    Tracing API

    From picocli 4.7.0, applications can programmatically set the trace level, and use tracing in custom components.

    In addition to setting system property picocli.trace, applications can now change the trace level via the Tracer::setLevel method. For example:

    CommandLine.tracer().setLevel(CommandLine.TraceLevel.INFO);
    

    The new public method CommandLine.tracer() returns the singleton Tracer object that is used internally by picocli, and can also be used by custom component implementations to do tracing. For example:

    class MyIntConverter implements ITypeConverter<Integer> {
        public Integer convert(String value) {
            try {
                return Integer.parseInt(value);
            } catch (NumberFormatException ex) {
                CommandLine.tracer().info(
                        "Could not convert %s to Integer, returning default value -1", value);
                return -1;
            }
        }
    }
    

    Enable Consuming Option Names or Subcommands

    By default, options that take a parameter do not consume values that match a subcommand name or an option name.

    This release introduces two parser configuration options to change this behaviour:

    • CommandLine::setAllowOptionsAsOptionParameters allows options to consume option names
    • CommandLine::setAllowSubcommandsAsOptionParameters allows options to consume subcommand names

    When set to true, all options in the command (options that take a parameter) can consume values that match option names or subcommand names.

    This means that any option will consume the maximum number of arguments possible for its arity.

    USE WITH CAUTION!

    If an option is defined as arity = "*", this option will consume all remaining command line arguments following this option (until the End-of-options delimiter) as parameters of this option.

    Unsorted Synopsis

    By default, the synopsis displays options in alphabetical order. Picocli 4.7.0 introduces a sortSynopsis = false attribute to let the synopsis display options in the order they are declared in your class, or sorted by their order attribute.

    @Command(sortSynopsis = false)
    

    Parser change for char[] options

    Prior to 4.7, the picocli parser treated options and positional parameters with type char[] as array (multi-value) options, except for interactive options. However, it is more intuitive to treat all char[] options as single-value options, similar to String options.

    For end users, this means that existing applications that use non-interactive char[] options will no longer allow multiple characters to be specified separately on the command line. That is, input like -c A -c B -c C will be rejected and the user needs to specify -c ABC instead.

    Applications that want to preserve the previous behaviour will need to change their code to use java.lang.Character[] instead of char[].

    Fixed issues

    • [#1599] API: The picocli-codegen artifact is now an explicitly declared named JPMS module with a module-info.class.
    • [#1611] API: The picocli-groovy artifact is now an explicitly declared named JPMS module with a module-info.class.
    • [#1610] API: The picocli-shell-jline2 is now an explicitly declared named JPMS module with a module-info.class.
    • [#1609] API: The picocli-shell-jline3 is now an explicitly declared named JPMS module with a module-info.class.
    • [#1608] API: The picocli-spring-boot-starter is now an explicitly declared named JPMS module with a module-info.class. NOTE: its module name changed to info.picocli.spring.boot from info.picocli.spring.
    • [#1614] API: Change picocli-spring-boot-starter JPMS module name to info.picocli.spring.boot from info.picocli.spring.
    • [#1600] API: Add requires static java.sql to picocli module-info.
    • [#1471] API: Provide a programmatic way to configure Picocli's TraceLevel. Thanks to ekinano for raising this.
    • [#1125] API: Add parser configuration to allow options to consume values that match subcommand names or option names.
    • [#1396][#1401] API: Support generic types in containers (e.g. List, Map). Thanks to Michał Górniewski for the pull request.
    • [#1380][#1505] API, bugfix: requiredOptionMarker should not be displayed on ArgGroup options. Thanks to Ahmed El Khalifa for the pull request.
    • [#1563] API: Add constructor to PicocliSpringFactory to allow custom fallback IFactory. Thanks to Andrew Holland for raising this.
    • [#1767][#1802] API: avoid NPE on OptionSpec.getValue() and add IScoped internal API. Thanks to Ruud Senden for the discussion and the pull request.
    • [#1574] API: Add annotation API to control whether synopsis should be sorted alphabetically or by explicit order.
    • [#1708][#1712][#1723] API: The setUsageHelpLongOptionsMaxWidth method no longer throws an exception when an invalid value is specified; instead, the value is ignored and an INFO-level trace message is logged. Thanks to Fabio for the pull request.
    • [#648][#1846] Enhancement: Treat char[] as single-value types (Potentially breaking change). Thanks to Lukáš Petrovický for the pull request with the test to verify the solution.
    • [#1571] Enhancement: Variables in values from the default value provider should be interpolated. Thanks to Bas Passon for raising this.
    • [#1773] Enhancement: Applications can improve startup time by setting system property picocli.disable.closures to true to disable support for closures in annotations. Thanks to patric-r for raising this.
    • [#1408] Enhancement: Synopsis should respect order if specified. Thanks to Simon for raising this.
    • [#964][#1080] Enhancement: ArgGroup synopsis should respect order (if specified). Thanks to Enderaoe for the pull request with unit tests.
    • [#1706][#1710] Enhancement: Subcommands should get missing messages from parent command resource bundle. Thanks to Ruud Senden and Mike Snowden for the pull request.
    • [#899][#1578][#1579] Enhancement: improve built-in Help command description. Thanks to Michael L Heuer for the pull request. Thanks to Garret Wilson for raising this.
    • [#1713][#1714] Enhancement: Support optional booleans in annotation processor. Thanks to Jan Waś for the pull request.
    • [#1387][#1711] Enhancement: Annotation processor should validate final primitive and String fields with Option and Parameters annotations. Thanks to xehpuk for raising this, and thanks to Adam McElwee for the pull request.
    • [#1572] Enhancement: Remove redundant braces in ArgGroup synopsis.
    • [#1602] Enhancement: Fix incorrect debug output for add/removeAlias.
    • [#1603] Enhancement: Improve debug tracing information for help requests and command execution.
    • [#1629] Enhancement: Omit empty braces in standard prompt for interactive options without description. Thanks to Andreas Deininger for raising this.
    • [#1778] Enhancement: Add support for new Spring Boot auto configuration introduced in Spring Boot 2.7. Thanks to Andreas Asplund for the pull request.
    • [#1836][#1841] Enhancement: Command aliases on Mixin were not being applied. Thanks to Mike Snowden for the pull request and to Ruud Senden for raising this.
    • [#1754][#1759] Enhancement: Autocompletion now correctly handles completion candidates with spaces. Thanks to Juan Martín Sotuyo Dodero for the pull request.
    • [#1834][#1838] Bugfix: Incorrect synopsis for char[] options. Thanks to Ruud Senden and Mike Snowden for the pull request.
    • [#1680] Bugfix: ArgGroups with multiplicity="0" are now disallowed at construction time and no longer throw a StackOverflowError while parsing. Thanks to ARNOLD Somogyi for raising this.
    • [#1615][#1616] Bugfix: getCJKAdjustedLength() no longer miscalculates for supplementary code points. Thanks to gwalbran for the pull request.
    • [#1575] Bugfix: Synopsis should not cluster boolean options if posixClusteredShortOptionsAllowed is set to false.
    • [#1642] Bugfix: Negatable options should negate explicit values. Thanks to Nat Burns for raising this.
    • [#1696][#1697] Bugfix: ManPageGenerator asciidoc output now correctly shows options in nested ArgGroups. Thanks to Ruud Senden for the pull request.
    • [#1741] Bugfix: @Command-annotated method parameters are assigned incorrect indices when contained in a @Command class that is added as a subcommand to another @Command class which has scope = CommandLine.ScopeType.INHERIT. Thanks to Onedy for raising this.
    • [#1779] Bugfix: Custom factory should be used when creating CommandSpec. Thanks to Philippe Charles for raising this.
    • [#1644][#1863] Bugfix: autocompletion of directory names stopped working from picocli 4.6.3. Thanks to NewbieOrange for the pull request, and thanks to philgdn for raising this and verifying the solution.
    • [#1807] BUILD: Optimize incremental builds and local build cache usage. Thanks to Jean André Gauthier for the pull request and Nelson Osacky for the review.
    • [#1298] DOC: Publish all-in-one javadoc for all picocli modules.
    • [#812] DOC: Document how to test a picocli spring-boot application.
    • [#1596] DOC: fix javadoc typos and incorrect links.
    • [#1597] DOC: Add examples to Execution Configuration section in user manual.
    • [#1140] DOC: Add subsection Forcing Interactive Input to user manual Interactive Options section. Thanks to smalirizvi for raising this.
    • [#967] DOC: User manual now shows how to configure null as defaultValue and fallbackValue.
    • [#1625] DOC: Fix broken links after renaming default branch to main from master. Thanks to Andreas Deininger for the pull request.
    • [#1628][#1630] DOC: Fix broken link in picocli-codegen README. Thanks to Andreas Deininger for the pull request.
    • [#1627] DOC: User guide, chapter 3.2.3. Forcing Interactive Input: code sample: add Kotlin version. Thanks to Andreas Deininger for the pull request.
    • [#1650] DOC: User guide, Spring Boot section: add warning about dynamic proxies. Thanks to Ernst Plüss for raising this.
    • [#1677] DOC: Many improvements and corrections to the user manual. Thanks to Björn Kautler for the pull request.
    • [#1678] DOC: Change links from http to https, fix broken links. Thanks to Andreas Deininger for the pull request.
    • [#1750] DOC: Clarify that GPL licensing NOTICE is for docs only.
    • [#1788] DOC: add link to picocli-examples in the user manual. Thanks to Markus Elfring for raising this.
    • [#1796] DOC: Fixing broken links and typos. Thanks to Andreas Deininger for the pull request.
    • [#1798] DOC: update examples for jakarta.validation-api. Thanks to Roy for raising this.
    • [#1803] DOC: show @Command-annotated method with int return value in user manual. Thanks to SinaMobasheri for raising this.
    • [#1581] BUILD: Fix dependabot config.
    • [#1613] DEP: The picocli-groovy module now declares groovy-all as dependency.
    • [#1604] DEP: Remove dependency on slf4j from picocli-spring-boot-starter.
    • [#1783] DEP: Update actions/checkout requirement to 2541b1294d2704b0964813337f33b291d3f8596b
    • [#1837] DEP: Bump actions/checkout from 3.0.2 to 3.1.0
    • [#1607] DEP: Bump actions/setup-java from 2.5.0 to 3
    • [#1646] DEP: Bump actions/setup-java from 3.0.0 to 3.1.0
    • [#1655] DEP: Bump actions/setup-java from 3.1.0 to 3.1.1
    • [#1667] DEP: Bump actions/setup-java from 3.1.1 to 3.2.0
    • [#1674] DEP: Bump actions/setup-java from 3.2.0 to 3.3.0
    • [#1717] DEP: Bump actions/setup-java from 3.3.0 to 3.4.0
    • [#1736] DEP: Bump actions/setup-java from 3.4.0 to 3.4.1
    • [#1806] DEP: Bump actions/setup-java from 3.4.1 to 3.5.0
    • [#1826] DEP: Bump actions/setup-java from 3.5.0 to 3.5.1
    • [#1624] DEP: Bump actions/upload-artifact from 2.3.1 to 3
    • [#1687] DEP: Bump actions/upload-artifact from 3.0.0 to 3.1.0
    • [#1859] DEP: Bump actions/upload-artifact from 3.1.0 to 3.1.1
    • [#1585] DEP: Bump github/codeql-action from 1.0.30 to 1.1.0
    • [#1593] DEP: Bump github/codeql-action from 1.1.0 to 1.1.2
    • [#1601] DEP: Bump github/codeql-action from 1.1.2 to 1.1.3
    • [#1631] DEP: Bump github/codeql-action from 1.1.3 to 1.1.4
    • [#1636] DEP: Bump github/codeql-action from 1.1.4 to 1.1.5
    • [#1643] DEP: Bump github/codeql-action from 1.1.5 to 2.1.6
    • [#1652] DEP: Bump github/codeql-action from 2.1.6 to 2.1.7
    • [#1654] DEP: Bump github/codeql-action from 2.1.7 to 2.1.8
    • [#1669] DEP: Bump github/codeql-action from 2.1.8 to 2.1.9
    • [#1676] DEP: Bump github/codeql-action from 2.1.9 to 2.1.10
    • [#1682] DEP: Bump github/codeql-action from 2.1.10 to 2.1.11
    • [#1700] DEP: Bump github/codeql-action from 2.1.11 to 2.1.12
    • [#1720] DEP: Bump github/codeql-action from 2.1.12 to 2.1.14
    • [#1728] DEP: Bump github/codeql-action from 2.1.14 to 2.1.15
    • [#1739] DEP: Bump github/codeql-action from 2.1.15 to 2.1.16
    • [#1781] DEP: Bump github/codeql-action from 2.1.18 to 2.1.1
    • [#1786] DEP: Bump github/codeql-action from 2.1.18 to 2.1.20
    • [#1792] DEP: Bump github/codeql-action from 2.1.20 to 2.1.21
    • [#1797] DEP: Bump github/codeql-action from 2.1.21 to 2.1.22
    • [#1817] DEP: Bump github/codeql-action from 2.1.22 to 2.1.23
    • [#1820] DEP: Bump github/codeql-action from 2.1.22 to 2.1.24
    • [#1823] DEP: Bump github/codeql-action from 2.1.24 to 2.1.25
    • [#1831] DEP: Bump github/codeql-action from 2.1.25 to 2.1.26
    • [#1842] DEP: Bump github/codeql-action from 2.1.26 to 2.1.27
    • [#1862] DEP: Bump github/codeql-action from 2.1.28 to 2.1.29
    • [#1782] DEP: Bump gradle/gradle-build-action from c6619898ec857b418d6436d3efe8a0becf74eb9e to 2.2.4
    • [#1787] DEP: Bump gradle/gradle-build-action from c6619898ec857b418d6436d3efe8a0becf74eb9e to 2.2.5
    • [#1825] DEP: Bump gradle/gradle-build-action from 2.3.0 to 2.3.1
    • [#1832] DEP: Bump gradle/gradle-build-action from 2.3.1 to 2.3.2
    • [#1860] DEP: Bump gradle/gradle-build-action from 2.3.2 to 2.3.3
    • [#1861] DEP: Bump gradle/wrapper-validation-action from 1.0.4 to 1.0.5
    • [#1586] DEP: Bump ossf/scorecard-action from 1.0.2 to 1.0.3
    • [#1594] DEP: Bump ossf/scorecard-action from 1.0.3 to 1.0.4
    • [#1691] DEP: Bump ossf/scorecard-action from 1.0.4 to 1.1.0
    • [#1699] DEP: Bump ossf/scorecard-action from 1.1.0 to 1.1.1
    • [#1805] DEP: Bump ossf/scorecard-action from 1.1.2 to 2.0.0
    • [#1813] DEP: Bump ossf/scorecard-action from 2.0.0 to 2.0.2
    • [#1816] DEP: Bump ossf/scorecard-action from 2.0.0 to 2.0.3
    • [#1828] DEP: Bump ossf/scorecard-action from 2.0.3 to 2.0.4
    • [#1583] DEP: Bump step-security/harden-runner from 1.3.0 to 1.4.0
    • [#1639] DEP: Bump step-security/harden-runner from 1.4.0 to 1.4.1
    • [#1666] DEP: Bump step-security/harden-runner from 1.4.1 to 1.4.2
    • [#1730] DEP: Bump step-security/harden-runner from 1.4.3 to 1.4.4
    • [#1833] DEP: Bump step-security/harden-runner from 1.4.5 to 1.5.0
    • [#1580] DEP: Bump asciidoctor to 2.5.3 from 2.5.2. Thanks to Andreas Deininger for the pull request.
    • [#1688] DEP: Bump asciidoctorj-pdf from 1.6.2 to 2.0.0
    • [#1690] DEP: Bump asciidoctorj-pdf from 2.0.0 to 2.0.2
    • [#1692] DEP: Bump asciidoctorj-pdf from 2.0.2 to 2.0.3
    • [#1694] DEP: Bump asciidoctorj-pdf from 2.0.3 to 2.0.4
    • [#1695] DEP: Bump asciidoctorj-pdf from 2.0.4 to 2.0.6
    • [#1715] DEP: Bump asciidoctorj-pdf from 2.0.6 to 2.0.8
    • [#1722] DEP: Bump asciidoctorj-pdf from 2.0.8 to 2.1.2
    • [#1785] DEP: Bump asciidoctorj-pdf from 2.1.6 to 2.3.0
    • [#1854] DEP: Bump asciidoctorj-pdf from 2.3.0 to 2.3.3
    • [#1618] DEP: Bump biz.aQute.bnd.gradle from 6.1.0 to 6.2.0
    • [#1698] DEP: Bump biz.aQute.bnd.gradle from 6.2.0 to 6.3.0
    • [#1703] DEP: Bump biz.aQute.bnd.gradle from 6.3.0 to 6.3.1
    • [#1582] DEP: Bump groovy-all from 2.4.10 to 2.5.15 // latest version of Groovy that supports Java 5
    • [#1589] DEP: Bump hamcrest-core from 1.3 to 2.2
    • [#1621] DEP: Bump hibernate-validator from 7.0.2.Final to 7.0.3.Final
    • [#1633][#1635] DEP: Bump hibernate-validator from 7.0.3.Final to 7.0.4.Final
    • [#1821] DEP: Bump hibernate-validator from 7.0.5.Final to 8.0.0.Final
    • [#1812] DEP: Bump hibernate-validator from 7.0.5.Final to 8.0.0.Final
    • [#1622] DEP: Bump hibernate-validator-annotation-processor from 7.0.2.Final to 7.0.3.Final
    • [#1634] DEP: Bump hibernate-validator-annotation-processor from 7.0.3.Final to 7.0.4.Final
    • [#1587] DEP: Bump ivy from 2.4.0 to 2.5.0
    • [#1584] DEP: Bump jansi from 2.1.0 to 2.4.0
    • [#1573] DEP: Bump JLine3 version to 3.21.0 from 3.19.0.
    • [#1590] DEP: Bump junit-dep from 4.11 to 4.11.20120805.1225
    • [#1591] DEP: Bump junit from 4.12 to 4.13.2
    • [#1649] DEP: Bump kotlin-gradle-plugin from 1.6.10 to 1.6.20
    • [#1829] DEP: Bump kotlin-gradle-plugin from 1.7.10 to 1.7.20
    • [#1648] DEP: Bump kotlin-script-runtime from 1.6.10 to 1.6.20
    • [#1830] DEP: Bump kotlin-script-runtime from 1.7.10 to 1.7.20
    • [#1617] DEP: Bump log4j2Version from 2.17.1 to 2.17.2
    • [#1729] DEP: Bump log4j2Version from 2.17.2 to 2.18.0
    • [#1819] DEP: Bump log4j2Version from 2.18.0 to 2.19.0
    • [#1822] DEP: Bump scala-library from 2.13.8 to 2.13.9
    • [#1843] DEP: Bump scala-library from 2.13.9 to 2.13.10
    • [#1576] DEP: Bump Spring Boot version from 2.5.6 to 2.6.3
    • [#1606] DEP: Bump Spring Boot version from 2.6.3 to 2.6.4
    • [#1641] DEP: Bump Spring Boot version from 2.6.4 to 2.6.5
    • [#1645] DEP: Bump Spring Boot version from 2.6.5 to 2.6.6
    • [#1684] DEP: Bump Spring Boot version from 2.6.7 to 2.6.8
    • [#1686] DEP: Bump Spring Boot version from 2.6.8 to 2.7.0
    • [#1719] DEP: Bump Spring Boot version from 2.7.0 to 2.7.1
    • [#1747] DEP: Bump Spring Boot version from 2.7.1 to 2.7.2
    • [#1780] DEP: Bump spring Boot Version from 2.7.2 to 2.7.3
    • [#1824] DEP: Bump springBootVersion from 2.7.3 to 2.7.4
    • [#1853] DEP: Bump springBootVersion from 2.7.4 to 2.7.5
    • [#1588] DEP: Bump system-rules from 1.17.1 to 1.19.0

    Deprecations

    No features were deprecated in this release.

    Potential breaking changes

    • The JPMS module name of picocli-spring-boot-starter has been changed to info.picocli.spring.boot from info.picocli.spring.
    • The picocli-groovy module now declares groovy-all as dependency.
    • The parser now treats char[] as a single-value type.
    • Redundant braces are now omitted in ArgGroup synopsis in usage help messages.
    Source code(tar.gz)
    Source code(zip)
    picocli-4.7.0-javadoc.jar(809.78 KB)
    picocli-4.7.0.jar(403.08 KB)
    picocli-all-4.7.0.zip(3.64 MB)
    picocli-codegen-4.7.0.jar(125.94 KB)
    picocli-groovy-4.7.0.jar(11.80 KB)
    picocli-shell-jline2-4.7.0.jar(1.64 KB)
    picocli-shell-jline3-4.7.0.jar(10.11 KB)
    picocli-spring-boot-starter-4.7.0.jar(3.47 KB)
  • v4.6.3(Feb 9, 2022)

    Picocli 4.6.3

    The picocli community is pleased to announce picocli 4.6.3.

    This release includes bugfixes and enhancements, as well as documentation and security improvements.

    Several improvements to the annotation processor and the generated autocompletion scripts.

    Much gratitude to the picocli community for the many pull requests and other contributions!

    This is the seventy-eighth public release. Picocli follows semantic versioning. Artifacts in this release are signed by Remko Popma (6601 E5C0 8DCC BB96).

    Table of Contents

    New and Noteworthy

    Default branch renamed to main

    The default branch has been renamed! master is now named main.

    If you have a local clone, you can update it by running the following commands:

    git branch -m master main
    git fetch origin
    git branch -u origin/main main
    git remote set-head origin -a
    

    Autocompletion script improvements

    • Autocompletion now shows subcommand aliases in the completion candidates
    • Autocompletion now displays completion candidates on exact match
    • Autocompletion now supports file names containing spaces
    • Remove file name extension and local dir prefix from the command name in generated autocomplete scripts
    • Fix Bash error compopt: command not found on older versions of Bash
    • Autocompletion on ZSH should only call compinit once

    Fixed issues

    • [#1440] Bugfix: annotation processor incorrectly failed with DuplicateOptionAnnotationsException when multiple commands had a subcommand in common and an inherited (scope = ScopeType.INHERIT) option. Thanks to nemetsSY for raising this.
    • [#1472] Bugfix: annotation processor option -Averbose=true no longer incorrectly triggers warning: The following options were not recognized by any processor: '[verbose]'. Thanks to Lorenz Leutgeb for raising this.
    • [#1384][#1493] Bugfix: parser now correctly handles ArgGroups with optional positional parameters. Thanks to Matthew Lewis for raising this and to Kurt Kaiser for the pull request.
    • [#1474] Bugfix: Avoid UnsupportedCharsetException: cp65001 on Microsoft Windows console when code page is set to UTF-8. Thanks to epuni for raising this.
    • [#1528][#1529] Bugfix: Allow aliases of a CommandSpec that is already a subcommand to be properly & consistently modified. Thanks to Ross Goldberg for the pull request.
    • [#1466][#1467] Bugfix/Enhancement: Autocomplete now shows subcommand aliases in the completion candidates. Thanks to Ruud Senden for the pull request.
    • [#1468] Bugfix/Enhancement: Autocompletion now displays completion candidates on exact match. Thanks to Ruud Senden for raising this.
    • [#1537][#1541] Bugfix: AbbreviationMatcher now treats aliases of the same object as one match. Thanks to Staffan Arvidsson McShane for raising this and NewbieOrange for the pull request.
    • [#1531] Bugfix: Options defined as annotated methods should reset between parseArgs invocations when CommandLine instance is reused. Thanks to kaushalkumar for raising this.
    • [#1458][#1473] Enhancement: Autocompletion now supports file names containing spaces. Thanks to zpater345 for raising this and thanks to NewbieOrange for the pull request.
    • [#1477] Enhancement: Remove file name extension and local dir prefix from the command name in generated autocomplete scripts. Thanks to Andrea Peruffo for the pull request.
    • [#1464] Enhancement: Fix Bash error compopt: command not found on older versions Bash. Thanks to Andres Almiray for raising this.
    • [#1476] Enhancement: improve error message in AbstractCommandSpecProcessor#extractTypedMember. Thanks to Ross Goldberg for raising this.
    • [#1475] Enhancement: Fix typo in annotation target-type error message. Thanks to Ross Goldberg for the pull request.
    • [#1366][#1370] Enhancement: show in usage help that the built-in help command only works on the first argument. Thanks to Patrice Duroux for the pull request.
    • [#1492] Enhancement: Use EditorConfig to define file formats and coding style; Thanks to Goooler for the pull request.
    • [#1530] Enhancement: Simplified CommandSpec#validateSubcommandName implementation. Thanks to Ross Goldberg for the pull request.
    • [#1484] Enhancement: Fixed org.junit.Assert.assertThat deprecation warning; Thanks to Ross Goldberg for the pull request.
    • [#1485] Enhancement: Fix build warnings; build doc enhancements; Thanks to Ross Goldberg for the pull request.
    • [#1483] Enhancement: Improved AbstractCommandSpecProcessor#isSubcommand; Thanks to Ross Goldberg for the pull request.
    • [#1499] Enhancement: Improved DefaultFactory#create(Class<T>). Thanks to Ross Goldberg for the pull request.
    • [#1518] Enhancement: Simplified detection of getter & setter in TypedMember constructor. Thanks to Ross Goldberg for the pull request.
    • [#1568] Enhancement: CommandLine cleanup. Thanks to Ross Goldberg for the pull request.
    • [#1526][#1548] Enhancement: Autocompletion on ZSH should only call compinit once. Thanks to Ben Herweyer for the pull request.
    • [#1539] DOC: Various documentation improvements. Thanks to Hamid Nazari for the pull request.
    • [#1481] DOC: Removed repeated "whether" typo in JavaDoc; Thanks to Ross Goldberg for the pull request.
    • [#1125][#1538] DOC: Update "Option Names or Subcommands as Option Values" section in user manual; Thanks to Scott Turner for raising this.
    • [#1409][#1463] DOC: add documentation section on using default values in argument groups. Thanks to Ben Kedo for the pull request.
    • [#1383][#1502] DOC: add tests demonstrating usage of multiple arguments. Thanks to Ben Kedo and lind6 for the pull request.
    • [#1462] DOC, BUILD, DEP: Extend documentation on argument files, fix broken/outdated links, update dependencies. Thanks to Andreas Deininger for the pull request.
    • [#1457] DOC: add caution about arguments in @files with quoted option parameters. Thanks to Andreas Deininger for the pull request.
    • [#1544][#1545] DOC: Add NOTICE file with GPL v2 + CPE license. Thanks to Keith M Swartz for the pull request.
    • [#1553] SECURITY: Fix code scanning alert - Token-Permissions
    • [#1554] SECURITY: Fix code scanning alert - Pinned-Dependencies
    • [#1555] SECURITY: Fix code scanning alert - Create SECURITY.md
    • [#1556][#1557] SECURITY: Fix code scanning alert - SAST
    • [#1558] SECURITY: Fix code scanning alert - Pinned-Dependencies in codeql-analysis.yml
    • [#1559] SECURITY: Fix code scanning alert - Token-Permissions in codeql-analysis.yml
    • [#1560] SECURITY: Fix code scanning alert - Binary-Artifacts - Validate Gradle Wrapper
    • [#1561] SECURITY: Fix code scanning alert - Doc/example code uses a broken or risky cryptographic algorithm
    • [#1562] BUILD: Rename 'master' branch to 'main'
    • [#1491] BUILD: Add build job in CI; Thanks to Goooler for the pull request.
    • [#1482] BUILD: Optimize gradle; Thanks to Goooler for the pull request.
    • [#1461] BUILD: Allow publishing without signing for non-release versions. Thanks to Andreas Deininger for raising this.
    • [#1459] BUILD: The nexus-staging Gradle plugin must be applied to the root project, not to subprojects. Thanks to Andreas Deininger for raising this.
    • [#1503] BUILD: Fix failing System.exit tests on Java 18.
    • [#1504] BUILD: Run tests on Java 6-7 in CI environment, semi-automate testing on Java 5.
    • [#1516] DEP: Remove redundant dependency on jline-console in picocli-shell-jline3. Thanks to kaushalkumar for raising this.
    • [#1495] DEP: Bump validation-api from 2.0.0.Final to 2.0.1.Final
    • [#1496] DEP: Bump biz.aQute.bnd.gradle from 5.1.2 to 6.1.0
    • [#1494] DEP: Bump kotlin-gradle-plugin from 1.5.31 to 1.6.0
    • [#1497] DEP: Bump badass-jar from 1.1.3 to 1.2.0
    • [#1498] DEP: Bump hibernate-validator from 6.1.2.Final to 7.0.1.Final
    • [#1490] DEP: Bump hibernate-validator-annotation-processor from 6.1.2.Final to 7.0.1.Final
    • [#1489] DEP: Bump log4j-core from 2.13.0 to 2.14.1
    • [#1488] DEP: Bump log4j-api from 2.13.0 to 2.14.1
    • [#1487] DEP: Bump kotlin-script-runtime from 1.5.31 to 1.6.0
    • [#1486] DEP: Bump gradle-nexus-staging-plugin from 0.21.0 to 0.30.0
    • [#1500][#1517] DEP: Bump gradle from 7.3 to 7.3.3. Thanks to Ross Goldberg for the pull request.
    • [#1569] DEP: Bump gradle from 7.3.3 to 7.4. Thanks to Ross Goldberg for the pull request.
    • [#1515] DEP: Bump kotlin-gradle-plugin from 1.6.0 to 1.6.10
    • [#1512] DEP: Bump kotlin-script-runtime from 1.6.0 to 1.6.10
    • [#1514] DEP: Bump log4j-api from 2.14.1 to 2.17.1
    • [#1513] DEP: Bump log4j-core from 2.14.1 to 2.17.1
    • [#1543] DEP: Bump asciidoctorj-pdf from 1.6.0 to 1.6.2
    • [#1547] DEP: Bump scala-library from 2.13.7 to 2.13.8
    • [#1550] DEP: Bump hibernate-validator from 7.0.1.Final to 7.0.2.Final
    • [#1551] DEP: Bump hibernate-validator-annotation-processor from 7.0.1.Final to 7.0.2.Final

    Deprecations

    No features were deprecated in this release.

    Potential breaking changes

    This release has no breaking changes.

    Source code(tar.gz)
    Source code(zip)
    picocli-4.6.3.jar(396.43 KB)
    picocli-4.6.3.jar.asc(664 bytes)
    picocli-all-4.6.3.zip(3.29 MB)
    picocli-codegen-4.6.3.jar(124.82 KB)
    picocli-codegen-4.6.3.jar.asc(664 bytes)
    picocli-groovy-4.6.3.jar(11.83 KB)
    picocli-groovy-4.6.3.jar.asc(664 bytes)
    picocli-shell-jline2-4.6.3.jar(1.67 KB)
    picocli-shell-jline2-4.6.3.jar.asc(664 bytes)
    picocli-shell-jline3-4.6.3.jar(10.14 KB)
    picocli-shell-jline3-4.6.3.jar.asc(664 bytes)
    picocli-spring-boot-starter-4.6.3.jar(2.82 KB)
    picocli-spring-boot-starter-4.6.3.jar.asc(664 bytes)
  • v4.6.2(Nov 5, 2021)

    Picocli 4.6.2

    The picocli community is pleased to announce picocli 4.6.2.

    This release includes bugfixes and enhancements. Many improvements in the documentation.

    Thanks to the many people in the picocli community for raising issues and contributing pull requests to fix issues!

    From this release, picocli uses system properties sun.stdout.encoding and sun.stderr.encoding when creating the PrintWriters returned by CommandLine::getOut and CommandLine::getErr. When these system properties do not exist, picocli falls back to the default charset (determined by file.encoding). This addresses an issue on Windows, where the default charset is not the same as the encoding for its console (often the older cp437 codepage on English-language versions of Windows).

    Note that these system properties seem to have been introduced in Java 8 (although I cannot find it in the JDK 8 release notes) and may not exist on earlier JVMs or on JVMs other than the Oracle and OpenJDK implementations.

    This is the seventy-seventh public release. Picocli follows semantic versioning. Artifacts in this release are signed by Remko Popma (6601 E5C0 8DCC BB96).

    Table of Contents

    New and Noteworthy

    Fixed issues

    • [#1422] API: Un-deprecate the @Option help attribute; it is useful for custom help options. Thanks to kaushalkumar for raising this.
    • [#1337][#1338] Enhancement: prevent spurious WARNING: tag not found in include file messages when generating man pages. Thanks to Philip Crotwell for the pull request.
    • [#1340] Enhancement: add xref to generated man page document to link to subcommands from the parent command page. Thanks to Philip Crotwell for the pull request.
    • [#1351][#1362] Enhancement: avoid calling option completionCandidates when displaying usage help if ${COMPLETION-CANDIDATES} is not specified in description. Thanks to Wenhao ZHANG, sustc11810424 and Yining Tang for the pull request.
    • [#1303] Bugfix: Prevent IllegalArgumentException: argument type mismatch error in method subcommands with inherited mixed-in standard help options. Thanks to Andreas Deininger for raising this.
    • [#1300] Bugfix: Avoid spurious warning "Could not set initial value for field boolean" when reusing CommandLine with ArgGroup. Thanks to Yashodhan Ghadge for raising this.
    • [#1316] Bugfix: Avoid DuplicateOptionAnnotationsException thrown on mixinStandardHelpOptions for subcommands when parent has scope = INHERIT by picocli-codegen annotation processor. Thanks to Philippe Charles for raising this.
    • [#1319] Bugfix: Avoid DuplicateOptionAnnotationsException when parent has inherited mixed-in help options and the built-in HelpCommand subcommand. Thanks to Andreas Deininger for raising this.
    • [#1331] Bugfix: Avoid IllegalArgumentException when parent has no standard help options and scope = INHERIT, while subcommand does have mixed-in standard help options. Thanks to Andreas Deininger for raising this.
    • [#1381][#1382] Bugfix: Default value of option in repeated subcommand was not applied correctly. Thanks to sfeuerhahn for the pull request.
    • [#1434][#1435] CommandSpec.remove(arg) should also remove the arg from the args collection in the CommandSpec. Thanks to kaushalkumar for the pull request.
    • [#1404] Bugfix/Enhancement: Print paramLabel only when it could exist. Thanks to João Guerra for the pull reqeust.
    • [#1320][#1321] Bugfix/Enhancement: Use system properties sun.stdout.encoding and sun.stderr.encoding when creating the PrintWriters returned by CommandLine::getOut and CommandLine::getErr. Thanks to Philippe Charles for the investigation and the pull request.
    • [#1431] Bugfix/enhancement: .gitattributes should include HTML files to convert CRLF to LF. Thanks to wenhoujx for pointing this out.
    • [#1388][#1430] Bugfix: Fix subcommand aliases autocomplete regression. Thanks to NewbieOrange for the pull request.
    • [#1415] Bugfix/DOC: fix NullPointerException in README Example. Thanks to shannonbay for raising this.
    • [#1421] Bugfix/DOC: execute method in RunAll, RunFirst and RunLast should not be deprecated. Thanks to Gamal DeWeever for raising this.
    • [#1326][#1339] DOC: Added documentation and examples for controlling the locale. Thanks to Andreas Deininger for the pull request.
    • [#1296] DOC: add Kotlin code samples to user manual; other user manual improvements. Thanks to Andreas Deininger for the pull request.
    • [#1299] DOC: Link to IParameterPreprocessor from IParameterConsumer javadoc. Thanks to Andreas Deininger for the pull request.
    • [#1304] DOC: Manual, chapter '17.9 Inherited Command Attributes': added Kotlin version of code sample. Thanks to Andreas Deininger for the pull request.
    • [#1305] DOC: Document use of IParameterConsumer as n-ary type converter. Thanks to Martin for raising this.
    • [#1307] DOC: Added CAUTION admonitions, Kotlin code sample. Thanks to Andreas Deininger for the pull request.
    • [#1308] DOC: Add example for Option converter, improve text for default values. Thanks to Abhijit Sarkar for raising this.
    • [#1314] DOC: Fix use of deprecated Maven properties in README. Thanks to Philippe Charles for the pull request.
    • [#1323] DOC: Update Testing section of the user manual for Stefan Birkner's library System-Lambda.
    • [#1325] DOC: Add section on Short and Long Option Columns to user manual. Thanks to Andrei Ciobanu for raising this.
    • [#1336] DOC: Kotlin sample code, documentation improvements. Thanks to Andreas Deininger for the pull request.
    • [#1342] DOC: Improve user manual chapter 28.3 'Testing the Exit Code'. Thanks to Andreas Deininger for the pull request.
    • [#1344] DOC: Documentation, chapter 'Testing environment variables:': add Kotlin test sample. Thanks to Andreas Deininger for the pull request.
    • [#1443] DOC: Fix incorrect method name setLongOptionsMaxWidth to setUsageHelpLongOptionsMaxWidth in user manual section 'Long Option Column Width'. Thanks to kunlk for raising this.
    • [#1360][#1359] DOC: add JReleaser as packaging option. Thanks to Andres Almiray for the pull request.
    • [#1363][#1364] DOC: Add caution on Variable interpolation in Kotlin. Thanks to MagnusMG for the pull request.
    • [#1397][#1399] DOC: Update Jline2 README.md to add some recommended workaround about ANSI incompatible terminals. Thanks to Simon for the pull request.
    • [#1398][#1400] DOC: Arity of boolean options is now documented correctly. Thanks to João Guerra for the pull request.
    • [#1428][#1433] DOC: Add section about subcommands with the same name as option default value. Thanks to cbcmg for the pull request.
    • [#1390][#1432] DOC: Update examples to not throw Exception from main method. Thanks to wenhoujx for the pull request.
    • [#1423] DOC: Fixed broken link in README.md to annotation processor documentation. Thanks to Sevy007 for raising this.
    • [#1449] DOC: Fix typo in picocli-shell-jline2/README.md. Thanks to Ahmed Ashour for the pull request.
    • [#1426] Fix README adoption logos. Thanks to NewbieOrange for the pull request.
    • [#1313] DEP: Bump jline3Version in order to avoid stackoverflow error. Thanks to Rupert Madden-Abbott for the pull request.
    • [#1455] DEP: Bump spring-boot version to 2.5.6.
    • [#1369][#1371] Upgrade jline3 to version 3.19.0 to avoid "ReadConsoleInputW failed: Incorrect function" error. Thanks to auricgoldfinger for the pull request.
    • [#1336] BUILD: Bump Spring Boot, Gradle and Kotlin to latest version. Thanks to Andreas Deininger for the pull request.
    • [#1327] BUILD: fix incorrect version in MANIFEST.MF. Thanks to Fiouz for the pull request.
    • [#1328] BUILD: Upgrade Gradle to 6.8.2 and enable official Gradle Wrapper Validation GitHub Action. Thanks to Fiouz for the pull request.
    • [#1329] BUILD: OSGi manifest entry in picocli-4.6.0.jar should not require groovy. Thanks to Fiouz for raising this.
    • [#1330] BUILD: use type-safe DSL instead of direct XML manipulation to generate pom.xml. Thanks to Fiouz for the pull request.
    • [#1332] BUILD: Bumping asciidoctor + asciidoctor gradle plugin to latest versions. Thanks to Andreas Deininger for the pull request.
    • [#1413] BUILD: Improve Travis CI build Performance. Thanks to YunLemon for the pull request.
    • [#1322] BUILD: switch from Bintray jcenter to Maven Central.

    Deprecations

    No features were deprecated in this release.

    The @Option help attribute is no longer deprecated from this release; it is useful for custom help options.

    Potential breaking changes

    This release has no breaking changes.

    Source code(tar.gz)
    Source code(zip)
    picocli-4.6.2.jar(393.46 KB)
    picocli-4.6.2.jar.asc(664 bytes)
    picocli-all-4.6.2.zip(3.24 MB)
    picocli-codegen-4.6.2.jar(124.78 KB)
    picocli-codegen-4.6.2.jar.asc(664 bytes)
    picocli-groovy-4.6.2.jar(11.83 KB)
    picocli-groovy-4.6.2.jar.asc(664 bytes)
    picocli-shell-jline2-4.6.2.jar(1.67 KB)
    picocli-shell-jline2-4.6.2.jar.asc(664 bytes)
    picocli-shell-jline3-4.6.2.jar(10.14 KB)
    picocli-shell-jline3-4.6.2.jar.asc(664 bytes)
    picocli-spring-boot-starter-4.6.2.jar(2.82 KB)
    picocli-spring-boot-starter-4.6.2.jar.asc(664 bytes)
  • v4.6.1(Jan 3, 2021)

    Picocli 4.6.1

    The picocli community is pleased to announce picocli 4.6.1.

    This release fixes a problem (introduced in the 4.6.0 release) with dependency scope in the following sub-modules:

    • picocli-codegen
    • picocli-groovy
    • picocli-shell-jline2
    • picocli-shell-jline3
    • picocli-spring-boot-starter

    The problem was that these modules contained dependencies that were declared to have implementation scope instead of api scope. However, these were transitive dependencies, and necessary to compile any project that uses the above picocli modules.

    In this release, transitive dependencies are declared with api scope in the above modules.

    Special thanks to Sualeh Fatehi, Dejan Stojadinović and Semyon Levin for the quick community feedback, pull request and reviews!

    This is the seventy-sixth public release. Picocli follows semantic versioning.

    Table of Contents

    New and Noteworthy

    Fixed issues

    • [#1291] Fix dependency scope for picocli-shell-jline3. Thanks to Sualeh Fatehi for raising this.
    • [#1292] PR to fix dependency scope for picocli-shell-jline3. Thanks to Dejan Stojadinović for the pull request, and Semyon Levin for the review.
    • [#1294] Fix dependency scope for picocli-spring-boot-starter. Thanks to Semyon Levin for raising this.

    Deprecations

    No features were deprecated in this release.

    Potential breaking changes

    This release has no breaking changes.

    Source code(tar.gz)
    Source code(zip)
    picocli-4.6.1.jar(392.63 KB)
    picocli-4.6.1.jar.asc(821 bytes)
    picocli-4.6.1.zip(4.32 MB)
    picocli-codegen-4.6.1.jar(124.66 KB)
    picocli-codegen-4.6.1.jar.asc(821 bytes)
    picocli-groovy-4.6.1.jar(11.83 KB)
    picocli-groovy-4.6.1.jar.asc(821 bytes)
    picocli-shell-jline2-4.6.1.jar(1.67 KB)
    picocli-shell-jline2-4.6.1.jar.asc(821 bytes)
    picocli-shell-jline3-4.6.1.jar(10.14 KB)
    picocli-shell-jline3-4.6.1.jar.asc(821 bytes)
    picocli-spring-boot-starter-4.6.1.jar(2.82 KB)
    picocli-spring-boot-starter-4.6.1.jar.asc(821 bytes)
  • v4.6.0(Jan 1, 2021)

    Picocli 4.6.0

    The picocli community is pleased to announce picocli 4.6.0.

    This release contains new features, bug fixes and other enhancements.

    Community Contributions

    This release contains many, many community contributions, for which I am extremely grateful. Let's give the contributors some credit!

    • Andreas Deininger has been contributing to the documentation and other areas for a long time, but recently went into overdrive :-) and contributed many, many new pull requests to improve the documentation. The user manual and Quick Guide now have a "foldable" table of contents, and examples in tabs, with many additional examples in Kotlin, Scala and Groovy. A lot of work went into this! Many thanks, Andreas!
    • Marko Mackic contributed a pull request to add IModelTransformer API for user-defined model transformations after initialization and before parsing.
    • Sualeh Fatehi contributed a pull request to the picocli-shell-jline3 module that adds a built-in clear command and improves the help command.
    • H.Sakata contributed a pull request that adds support for echo and prompt for interactive options and positional parameters.
    • Daniel Gray contributed a bug fix to prevent incorrectly defaulting inherited positional params after a subcommand.
    • nveeser-google contributed a fix for compiler warnings about Annotation::getClass and assignment in if condition.
    • Petr Hála contributed a pull request to add a section on Mocking to user manual.
    • Max Rydahl Andersen contributed a pull request to include jbang in the Build Tools section of the user manual.
    • David Phillips contributed a section to the user manual on Really Executable JARs.
    • Laurent Almeras contributed a pull request to fix the user manual: @ParentObject should be @ParentCommand.
    • Mattias Andersson raised the idea of supporting subcommand methods in Groovy scripts.
    • Adrian A. raised the idea of using closures in the picocli annotations in Groovy programs instead of specifying a class.
    • Nick Cross raised the idea of inheriting @Command attributes with scope=INHERIT.
    • Marko Mackic raised the idea of adding a CommandSpec::removeSubcommand method.
    • Max Rydahl Andersen raised the idea of supporting Optional<T> type for options and positional parameters.
    • Max Rydahl Andersen and David Walluck raised the idea of supporting key-only Map options (to support -Dkey as well as -Dkey=value).
    • David Walluck raised the idea of a "preprocessor" parser plugin.
    • Jannick Hemelhof raised the idea of supporting @Spec-annotated members in ArgGroup classes.
    • Vitaly Shukela raised a bug report: the error message for unmatched positional argument reports an incorrect index when value equals a previously matched argument.
    • drkilikil raised a bug report: MissingParameterException should not be thrown when subcommand has required options and help option is specified on parent command.
    • Sebastian Thomschke raised a bug report: ReflectionConfigGenerator should not generate method section in subclass config for private superclass methods in reflect-config.json.
    • Lukas Heumos added the picocli-based cli-java template to CookieTemple.
    • Sualeh Fatehi raised the idea of adding add CommandLine::getFactory accessor method.
    • David Walluck contributed a test improvement that allows the tests to run reliably in more environments.
    • Sabrina (link witheld) pointed out various typos in the documentation.

    What is in this release

    Improved Groovy support: this release introduces a new @PicocliScript2 annotation that adds support for exit codes and @Command-annotated methods to define subcommands. Also, from this release, Groovy programs can use closures in the picocli annotations instead of specifying a class.

    From this release, Map options accept key-only parameters, so end users can specify -Dkey as well as -Dkey=value. There is a new mapFallbackValue attribute that enables this, which can be used to control the value that is put into the map when only a key was specified on the command line.

    Also, this release adds support for java.util.Optional<T>: single-value types can be wrapped in an Optional container object when running on Java 8 or higher. If the option or positional parameter was not specified on the command line, picocli assigns the value Optional.empty() instead of null.

    This release also adds support for commands with scope = ScopeType.INHERIT. Commands with this scope have their attributes copied to all subcommands (and sub-subcommands).

    New parser plugin: IParameterPreprocessor and new configuration plugin: IModelTransformer.

    From this release, @Spec-annotated elements can be used in ArgGroup classes, which can be convenient for validation.

    Interactive options and positional parameters can now set echo = true (for non-security sensitive data) so that user input is echoed to the console, and control the prompt text that is shown before asking the user for input.

    Help API: this release adds public methods Help.Layout::colorScheme, Help.Layout::textTable, Help.Layout::optionRenderer, Help.Layout::parameterRenderer, and Help::calcLongOptionColumnWidth, making it easier to customize the table format used to lay out options and positional parameters in the usage help message.

    CommandSpec API: added method CommandSpec::removeSubcommand.

    This is the seventy-fifth public release. Picocli follows semantic versioning.

    Table of Contents

    New and Noteworthy

    New @PicocliScript2 annotation

    The older @picocli.groovy.PicocliScript annotation is deprecated from picocli 4.6. New scripts should use the @picocli.groovy.PicocliScript2 annotation (and associated picocli.groovy.PicocliBaseScript2 base class) instead. The table below lists the differences between the PicocliBaseScript2 and PicocliBaseScript script base classes.

    | PicocliBaseScript2 | PicocliBaseScript |---- | ---- | Subcommands can be defined as @Command-annotated methods in the script. | No support for @Command-annotated methods. | Support for help subcommands (both the built-in one and custom ones). | No support for help subcommands. | Exit code support: scripts can override afterExecution(CommandLine, int, Exception) to call System.exit.| No support for exit code. | Invokes CommandLine::execute. Scripts can override beforeParseArgs(CommandLine) to install a custom IExecutionStrategy.| Execution after parsing is defined in PicocliBaseScript::run and is not easy to customize. Any subcommand and the main script are both executed. | Scripts can override beforeParseArgs(CommandLine) to install a custom IParameterExceptionHandler. | Invalid input handling can be customized by overriding PicocliBaseScript::handleParameterException. | Scripts can override beforeParseArgs(CommandLine) to install a custom IExecutionExceptionHandler. | Runtime exception handling can be customized by overriding PicocliBaseScript::handleExecutionException. | Implements Callable<Object>, script body is transformed to the call method. | Script body is transformed to the runScriptBody method.

    Groovy Closures in Annotations

    From picocli 4.6, Groovy programs can use closures in the picocli annotations instead of specifying a class. This can be especially useful in Groovy scripts, where one cannot define a static inner class.

    Example:

    @Command(name = "ClosureDemo",
            versionProvider = {
                { -> ["line1" , "line2"] as String[] } as IVersionProvider // <1>
            },
            defaultValueProvider = {
                { argSpec -> "some default" } as IDefaultValueProvider // <2>
            })
    class ClosureDemo {
        @Option(names = '-x', completionCandidates = {["A", "B", "C"]}) // <3>
        String x
    
        @Option(names = '-y',
                parameterConsumer = {
                    { args, argSpec, commandSpec ->  // <4>
                        argSpec.setValue(args.toString() + commandSpec.name())
                        args.clear()
                    } as IParameterConsumer
                })
        String y
    
        @Option(names = '-z', converter = [ // requires Groovy 3.0.7
                { { str -> MessageDigest.getInstance(str) } as ITypeConverter } // <5>
        ])
        MessageDigest z
    }
    

    When a class is specified, picocli creates an instance of the class. By contrast, when a closure is specified, picocli calls the closure to get an instance. (To be precise, both of these are delegated to the configured factory, and the default factory implementation supports closures from picocli 4.6.)

    As you can see in the above example, each closure in the annotation should contain another closure that has the required type (IVersionProvider, IDefaultValueProvider, etc.)

    • <1> Command versionProvider: note the empty parameter list before the -> arrow. This is needed to help the Groovy compiler. The closure must be cast to IVersionProvider.
    • <2> Command defaultProvider: return a default value for the specified ArgSpec parameter. The closure must be cast to IDefaultValueProvider.
    • <3> Option or Parameters completionCandidates: return a list of Strings. No parameter list or casting is required.
    • <4> Option or Parameters parameterConsumer: given a Stack, ArgSpec and CommandSpec, process the remaining arguments. The closure must be cast to IParameterConsumer.
    • <5> Option or Parameters type converter takes an array of closures. Groovy 3.0.7 or greater is required: older versions of Groovy ignore closures in class array annotations. Each closure must have a parameter and be cast to ITypeConverter.

    Key-only map parameters

    By default, picocli expects Map options and positional parameters to look like key=value, that is, the option parameter or positional parameter is expected to have a key part and a value part, separated by a = character. If this is not the case, picocli shows a user-facing error message: Value for ... should be in KEY=VALUE format but was ....

    From picocli 4.6, applications can specify a mapFallbackValue to allow end users to specify only the key part. The specified mapFallbackValue is put into the map when end users to specify only a key. The value type can be wrapped in a java.util.Optional. For example:

    @Option(names = {"-P", "--properties"}, mapFallbackValue = Option.NULL_VALUE)
    Map<String, Optional<Integer>> properties;
    
    @Parameters(mapFallbackValue = "INFO", description = "... ${MAP-FALLBACK-VALUE} ...")
    Map<Class<?>, LogLevel> logLevels;
    

    This allows input like the following:

    <cmd> --properties=key1 -Pkey2 -Pkey3=3 org.myorg.MyClass org.myorg.OtherClass=DEBUG
    

    The above input would give the following results:

    properties = [key1: Optional.empty, key2: Optional.empty, key3: Optional[3]]
    logLevels  = [org.myorg.MyClass: INFO, org.myorg.OtherClass: DEBUG]
    

    Note that the option description may contain the ${MAP-FALLBACK-VALUE} variable which will be replaced with the actual map fallback value when the usage help is shown.

    System Properties

    A common requirement for command line applications is to support the -Dkey=value syntax to allow end users to set system properties.

    The example below uses the Map type to define an @Option-annotated method that delegates all key-value pairs to System::setProperty. Note the use of mapFallbackValue = "" to allow key-only option parameters.

    class SystemPropertiesDemo {
        @Option(names = "-D", mapFallbackValue = "") // allow -Dkey
        void setProperty(Map<String, String> props) {
            props.forEach((k, v) -> System.setProperty(k, v));
        }
    }
    

    java.util.Optional<T>

    From version 4.6, picocli supports single-value types wrapped in a java.util.Optional container when running on Java 8 or higher. If the option or positional parameter was not specified on the command line, picocli assigns the value Optional.empty() instead of null. For example:

    @Option(names = "-x")
    Optional<Integer> x;
    
    @Option(names = "-D", mapFallbackValue = Option.NULL_VALUE)
    Map<String, Optional<Integer>> map;
    

    WARNING: Picocli has only limited support for java.util.Optional types: only single-value types, and the values in a Map (but not the keys!) can be wrapped in an Optional container. java.util.Optional cannot be combined with arrays or other Collection classes.

    Inherited Command Attributes

    Picocli 4.6 adds support for inheriting @Command attributes with the scope = ScopeType.INHERIT annotation. Commands with this scope have their @Command attributes copied to all subcommands (and sub-subcommands, to any level of depth).

    When a subcommand specifies an explicit value in its @Command annotation, this value is used instead of the inherited value. For example:

    @Command(name = "app", scope = ScopeType.INHERIT,
            mixinStandardHelpOptions = true, version = "app version 1.0",
            header = "App header",
            description = "App description",
            footerHeading = "Copyright%n", footer = "(c) Copyright by the authors",
            showAtFileInUsageHelp = true)
    class App implements Runnable {
        @Option(names = "-x") int x;
    
        public void run() { System.out.printf("Hello from app %d%n!", x); }
    
        @Command(header = "Subcommand header", description = "Subcommand description")
        void sub(@Option(names = "-y") int y) {
            System.out.printf("Hello app sub %d%n!", y);
        }
    }
    

    The app command in the above example has scope = ScopeType.INHERIT, so its @Command properties are inherited by the sub subcommand.

    The sub subcommand defines its own header and description, so these are not inherited from the parent command. The help message for the subcommand looks like this:

    Subcommand header
    Usage: app sub [-hV] [-y=<arg0>] [@<filename>...]
    Subcommand description
          [@<filename>...]   One or more argument files containing options.
      -h, --help             Show this help message and exit.
      -V, --version          Print version information and exit.
      -y=<arg0>
    Copyright
    (c) Copyright by the authors
    

    Note that the subcommand has inherited the mixed-in standard help options (--help and --version), the @file usage help, and the footer and footer heading. It also inherited the version string, shown when the user invokes app sub --version.

    When a command has scope = INHERIT, the following attributes are copied to its subcommands:

    • all usage help attributes: description, descriptionHeading, header, headerHeading, footer, footerHeading, customSynopsis, synopsisHeading, synopsisSubcommandLabel, abbreviateSynopsis, optionListHeading, parameterListHeading, commandListHeading, exitCodeList, exitCodeListHeading, requiredOptionMarker, showDefaultValues, sortOptions, autoWidth, width, showAtFileInUsageHelp, showEndOfOptionsDelimiterInUsageHelp, and hidden
    • exit codes: exitCodeOnSuccess, exitCodeOnUsageHelp, exitCodeOnVersionHelp, exitCodeOnInvalidInput, exitCodeOnExecutionException
    • the help and version options mixed in by mixinStandardHelpOptions
    • separator between option and option parameter
    • version
    • versionProvider
    • defaultValueProvider
    • subcommandsRepeatable
    • whether this command is a helpCommand

    Attributes that are not copied include:

    • command name
    • command aliases
    • options and parameters (other than the help and version options mixed in by mixinStandardHelpOptions)
    • other mixins than mixinStandardHelpOptions
    • subcommands
    • argument groups

    Preprocessor Parser Plugin

    Introduced in picocli 4.6, the IParameterPreprocessor is also a parser plugin, similar to IParameterConsumer, but more flexible.

    Options, positional parameters and commands can be assigned a IParameterPreprocessor that implements custom logic to preprocess the parameters for this option, position or command. When an option, positional parameter or command with a custom IParameterPreprocessor is matched on the command line, picocli's internal parser is temporarily suspended, and this custom logic is invoked.

    This custom logic may completely replace picocli's internal parsing for this option, positional parameter or command, or augment it by doing some preprocessing before picocli's internal parsing is resumed for this option, positional parameter or command.

    The "preprocessing" actions can include modifying the stack of command line parameters, or modifying the model.

    Example use case

    This may be useful when disambiguating input for commands that have both a positional parameter and an option with an optional parameter. For example, suppose we have a command with the following synopsis:

    edit [--open[=<editor>]] <file>
    

    One of the limitations of options with an optional parameter is that they are difficult to combine with positional parameters.

    With a custom parser plugin, we can customize the parser, such that VALUE in --option=VALUE is interpreted as the option parameter, and in --option VALUE (without the = separator), VALUE is interpreted as the positional parameter. The code below demonstrates:

    @Command(name = "edit")
    class Edit {
    
        @Parameters(index = "0", description = "The file to edit.")
        File file;
    
        enum Editor { defaultEditor, eclipse, idea, netbeans }
    
        @Option(names = "--open", arity = "0..1", preprocessor = Edit.MyPreprocessor.class,
            description = {
                "Optionally specify the editor to use; if omitted the default editor is used. ",
                "Example: edit --open=idea FILE opens IntelliJ IDEA (notice the '=' separator)",
                "         edit --open FILE opens the specified file in the default editor"
            })
        Editor editor = Editor.defaultEditor;
        
        static class MyPreprocessor implements IParameterPreprocessor {
            public boolean preprocess(Stack<String> args,
                                      CommandSpec commandSpec,
                                      ArgSpec argSpec,
                                      Map<String, Object> info) {
                // we need to decide whether the next arg is the file to edit
                // or the name of the editor to use...
                if (" ".equals(info.get("separator"))) { // parameter was not attached to option
    
                    // act as if the user specified --open=defaultEditor
                    args.push(Editor.defaultEditor.name());
                }
                return false; // picocli's internal parsing is resumed for this option
            }
        }
    }
    

    With this preprocessor, the following user input gives the following command state:

    # User input # Command State
    # --------------------------
    --open A B   # editor: defaultEditor, file: A,    unmatched: [B]
    --open A     # editor: defaultEditor, file: A,    unmatched: []
    --open=A B   # editor: A,             file: B,    unmatched: []
    --open=A     # editor: A,             file: null, unmatched: []
    

    Model Transformations

    From picocli 4.6, it is possible to use the annotations API to modify the model (commands, options, subcommands, etc.) dynamically at runtime. The @Command annotation now has a modelTransformer attribute where applications can specify a class that implements the IModelTransformer interface:

    This allows applications to dynamically add or remove options, positional parameters or subcommands, or modify the command in any other way, based on some runtime condition.

    @Command(modelTransformer = Dynamic.SubCmdFilter.class)
    class Dynamic {
    
        private static class SubCmdFilter implements IModelTransformer {
            public CommandSpec transform(CommandSpec commandSpec) {
                if (Boolean.getBoolean("disable_sub")) {
                    commandSpec.removeSubcommand("sub");
                }
                return commandSpec;
            }
        }
    
        @Command
        private void sub() {
            // subcommand business logic
        }
    }
    

    Fixed issues

    • [#1164] API: Add support for @Command(scope=INHERIT). Thanks to Nick Cross for raising this.
    • [#1191] API: Add @PicocliScript2 annotation to support subcommand methods in Groovy scripts. Thanks to Mattias Andersson for raising this.
    • [#1241] API: Add mapFallbackValue attribute to @Options and @Parameters annotations, and corresponding ArgSpec.mapFallbackValue().
    • [#1217] API: Add IParameterPreprocessor parser plugin to invoke custom logic when a command, option or positional parameter is matched. Thanks to David Walluck for raising this.
    • [#1259][#1266] API: Add IModelTransformer to support user-defined model transformations after initialization and before parsing. Thanks to Marko Mackic for the pull request.
    • [#802][#1284] API: Add support for echo and prompt in for interactive options and positional parameters. Thanks to H.Sakata for the pull request.
    • [#1184] API: Added public methods Help.Layout::colorScheme, Help.Layout::textTable, Help.Layout::optionRenderer, Help.Layout::parameterRenderer, and Help::calcLongOptionColumnWidth.
    • [#1254] API: Added ArgSpec::root: this method returns the original ArgSpec for inherited ArgSpec objects, and null for other ArgSpec objects. Thanks to Daniel Gray for the pull request.
    • [#1256] API: Added CommandSpec::removeSubcommand method. Thanks to Marko Mackic for raising this.
    • [#1258] API: Groovy programs can now use closures in the picocli annotations instead of specifying a class. Thanks to Adrian A. for raising this.
    • [#1267] API: Add CommandLine::getFactory accessor for the factory. Thanks to Sualeh Fatehi for the suggestion.
    • [#1108] Enhancement: Support Optional<T> type for options and positional parameters. Thanks to Max Rydahl Andersen for raising this.
    • [#1214] Enhancement: Support Map options with key-only (support -Dkey as well as -Dkey=value). Thanks to Max Rydahl Andersen and David Walluck for raising this and subsequent discussion.
    • [#1260] Enhancement: Support @Spec-annotated members in ArgGroup classes. Thanks to Jannick Hemelhof for raising this.
    • [#1265] Enhancement in picocli-shell-jline3: add built-in clear command and improve help command. Thanks to Sualeh Fatehi for the pull request.
    • [#1236] Enhancement/bugfix: Fix compiler warnings about Annotation::getClass and assignment in if condition. Thanks to nveeser-google for the pull request.
    • [#1229] Bugfix: Fix compilation error introduced with fc5ef6de6 (#1184). Thanks to Andreas Deininger for the pull request.
    • [#1225] Bugfix: Error message for unmatched positional argument reports an incorrect index when value equals a previously matched argument. Thanks to Vitaly Shukela for raising this.
    • [#1250] Bugfix: Inherited positional parameter should not be overridden by default value if placed after subcommand. Thanks to Daniel Gray for the pull request.
    • [#1183] Bugfix: Prevent MissingParameterException thrown when subcommand has required options and help option is specified on parent command. Thanks to drkilikil for raising this.
    • [#1273] Bugfix: The Help.calcLongOptionColumnWidth now calls Help.createDefaultOptionRenderer, so overriding createDefaultOptionRenderer uses the correct column width in the options and parameters list.
    • [#1274] Bugfix: ReflectionConfigGenerator should not generate method section in subclass config for private superclass methods in reflect-config.json. Thanks to Sebastian Thomschke for raising this.
    • [#1215] DOC: User manual improvements, including more tabs with Kotlin source code. Thanks to Andreas Deininger for the pull request.
    • [#1219] DOC: User manual improvements: added more tabs with Kotlin code. Thanks to Andreas Deininger for the pull request.
    • [#1220] DOC: User manual improvements: corrections, more Kotlin tabs. Thanks to Andreas Deininger for the pull request.
    • [#1221] DOC: User manual improvements: add tabs with Kotlin code for samples (chapter 14: Usage help). Thanks to Andreas Deininger for the pull request.
    • [#1222] DOC: User manual improvements: add tabs with Kotlin code for samples (chapter 7 + 12). Thanks to Andreas Deininger for the pull request.
    • [#1223] DOC: User manual improvements: add tabs with Kotlin code for samples (chapter 10: Validation). Thanks to Andreas Deininger for the pull request.
    • [#1224] DOC: User manual improvements: add tabs with Kotlin code for samples (chapter 5: Default Values). Thanks to Andreas Deininger for the pull request.
    • [#1226] DOC: User manual improvements: add tabs with Kotlin code for samples (chapter 9.6 - 9.8: Executing commands). Thanks to Andreas Deininger for the pull request.
    • [#1228] DOC: User manual improvements: add tabs with Kotlin code for samples (chapters 8, 16, 20). Thanks to Andreas Deininger for the pull request.
    • [#1230] DOC: User manual improvements: add tabs with Kotlin code for samples (Chapters 6, 11, 15, 19). Thanks to Andreas Deininger for the pull request.
    • [#1232] DOC: User manual improvements for Micronaut example: add Kotlin version, extended description of Micronaut usage. Thanks to Andreas Deininger for the pull request.
    • [#1233] DOC: User manual improvements: add tabs with Kotlin code for samples (Chapter 21: Tips & Tricks). Thanks to Andreas Deininger for the pull request.
    • [#1234] DOC: add system properties example to user manual.
    • [#1235][#1238] DOC: User manual: update DI section on Quarkus. Thanks to Andreas Deininger for the pull request.
    • [#1246] DOC: User manual improvements: Guice and Spring Boot examples: add Kotlin versions. Thanks to Andreas Deininger for the pull request.
    • [#1242] DOC: "Foldable" table of contents for User Manual and Quick Guide. Thanks to Andreas Deininger for the pull request.
    • [#1247] DOC: User manual: extended Spring Boot example. Thanks to Andreas Deininger for the pull request.
    • [#1249] DOC: Added section on Mocking to user manual. Thanks to Petr Hála for the pull request.
    • [#1244] DEP: Bump Spring-Boot-Starter version to 2.3.5.RELEASE. Thanks to Andreas Deininger for the pull request.
    • [#1289] DEP: Bump Spring boot dependency to 2.4.1. Thanks to Andreas Deininger for the pull request.
    • [#1248] BUILD: Fix gradle warnings. Thanks to Andreas Deininger for the pull request.
    • [#1280] BUILD: Remove trailing comment from gradle.properties to prevent build error. Thanks to David Walluck for raising this.
    • [#1253] DOC: Fix line endings to LF in documentation files. Thanks to Daniel Gray for the pull request.
    • [#1255] DOC: User manual and Quick Guide: add Groovy, Kotlin and Scala examples. Thanks to Andreas Deininger for the pull request.
    • [#1261] DOC: User manual improvements: add Scala code samples. Thanks to Andreas Deininger for the pull request.
    • [#1262] DOC: User manual: include jbang in the Build Tools section. Thanks to Max Rydahl Andersen for the pull request.
    • [#1263] DOC: User manual: show build scripts in tabs. Thanks to Andreas Deininger for the pull request.
    • [#1264] DOC: Fix broken links to GraalVm native image build configuration. Thanks to Andreas Deininger for the pull request.
    • [#1005] DOC: Add link to the CookieTemple cli-java template README. Thanks to Lukas Heumos for getting this added to CookieTemple.
    • [#1276] DOC: User manual: add section for "really executable JARs". Thanks to David Phillips for the pull request.
    • [#1286] DOC: Fix: @ParentObject should be @ParentCommand. Thanks to Laurent Almeras for the pull request.
    • [#1290] DOC: JLine: change keystroke syntax 'Ctl-D' to more common used syntax 'Ctrl-D'. Thanks to Andreas Deininger for the pull request.
    • [#1270] TEST: Fix issue #1103 in Issue1225UnmatchedArgBadIndex. Thanks to David Walluck for the pull request.

    Deprecations

    From this release, the @picocli.groovy.PicocliScript annotation in the picocli-groovy module is deprecated in favor of @picocli.groovy.PicocliScript2, and the picocli.groovy.PicocliBaseScript class is deprecated in favor of picocli.groovy.PicocliBaseScript2.

    Potential breaking changes

    Added method isOptional() to the picocli.CommandLine.Model.ITypeInfo interface.

    Source code(tar.gz)
    Source code(zip)
    picocli-4.6.0.jar(392.63 KB)
    picocli-4.6.0.jar.asc(821 bytes)
    picocli-all-4.6.0.zip(4.32 MB)
    picocli-codegen-4.6.0.jar(124.65 KB)
    picocli-codegen-4.6.0.jar.asc(821 bytes)
    picocli-groovy-4.6.0.jar(11.83 KB)
    picocli-groovy-4.6.0.jar.asc(821 bytes)
    picocli-shell-jline2-4.6.0.jar(1.67 KB)
    picocli-shell-jline2-4.6.0.jar.asc(821 bytes)
    picocli-shell-jline3-4.6.0.jar(10.14 KB)
    picocli-shell-jline3-4.6.0.jar.asc(821 bytes)
    picocli-spring-boot-starter-4.6.0.jar(2.82 KB)
    picocli-spring-boot-starter-4.6.0.jar.asc(821 bytes)
  • v4.5.2(Oct 14, 2020)

    Picocli 4.5.2

    The picocli community is pleased to announce picocli 4.5.2.

    This release contains bug fixes and enhancements:

    • Auto-enable ANSI colors on MSYS2 terminals.
    • Abbreviated options are now matched correctly even when value attached with '=' separator.
    • The built-in HelpCommand now respects subcommands case-sensitivity and abbreviations.
    • Required parameters no longer consume negated options.
    • Positional parameters in Argument Groups no longer result in ArithmeticException: / by zero exceptions.
    • The user manual now has tabs showing examples in languages other than Java. This is a work in progress: many examples still only have a Java version. Contributions welcome!
    • Many, many documentation enhancements, most of which contributed by the community.

    Many thanks to the picocli community who contributed 28 pull requests in this release! Please see the Fixed Issues section below for the individual contributors. Great work!

    This is the seventy-fourth public release. Picocli follows semantic versioning.

    Table of Contents

    New and Noteworthy

    The user manual now has tabs showing examples in languages other than Java. This is a work in progress: many examples still only have a Java version. Contributions welcome!

    Fixed issues

    • [#1186] Enhancement: Auto-enable ANSI colors on MSYS2 (Git for Windows, MSYS2-based Windows Terminal shells, etc.). Thanks to Sysmat for raising this.
    • [#1162] Bugfix: Abbreviated options are not matched if value attached with '=' separator (like -x=3). Thanks to Chris Laprun for raising this.
    • [#1156][#1172] Bugfix: the built-in HelpCommand now respects subcommands case-sensitivity and abbreviations. Thanks to NewbieOrange for the pull request.
    • [#1197] Bugfix: required parameters should not consume negated options. Thanks to Kevin Turner for raising this.
    • [#1213] Bugfix: @Parameters in @ArgGroup should not result in ArithmeticException: / by zero. Thanks to Loren Keagle for raising this.
    • [#1158] DOC: Fix broken links to GraalVM repo. Thanks to Andreas Deininger for the pull request.
    • [#1155] DOC: Fix sample code in chapter "Validation". Thanks to Andreas Deininger for the pull request.
    • [#1157] DOC: Fix typo "a argument group" in user manual. Thanks to sabrina for raising this.
    • [#1160] DOC: Added section Was a Value Defaulted? to the user manual.
    • [#1161] DOC: Fix typo "4,2" (should be 4.2) in user manual. Thanks to sabrina for raising this.
    • [#1165] DOC: Fix jline3 example: add AnsiConsole::systemUninstall in finally clause. Thanks to David Walluck for raising this.
    • [#1168][#1169] DOC: Ensure org.jline.terminal.Terminal is closed when done. Thanks to David Walluck for the pull request.
    • [#1167] DOC: Fix broken links in Quick Guide. Thanks to Andreas Deininger for the pull request.
    • [#1171] DOC: Various documentation improvements. Thanks to Andreas Deininger for the pull request.
    • [#1173] DOC: Improve example applications for the user manual and Quick Guide. Thanks to Andreas Deininger for the pull request.
    • [#1175] DOC: section on compatible versions to picocli-shell-jline3/README.md. Thanks to Nick Cross for raising this.
    • [#1176] DOC: Update JLine picocli-shell-jline3 example to 3.16.0. Thanks to Nick Cross for the pull request.
    • [#890][#1187] DOC: Extend and improve subcommands documentation. Thanks to Andreas Deininger for the pull request.
    • [#1190] DOC: Improve InetSocketAddressConverter demo. Thanks to Andreas Deininger for the pull request.
    • [#1192] DOC: Fix broken links in documentation. Thanks to Andreas Deininger for the pull request.
    • [#1196] DOC: Quick Guide examples can now be executed on the documentation page via JDoodle.com. Thanks to Andreas Deininger for the pull request.
    • [#1200] DOC: User manual checksum example can now be executed on the documentation page via JDoodle.com. Thanks to Andreas Deininger for the pull request.
    • [#1199] DOC: Fix paramLabel in examples. Thanks to Andreas Deininger for the pull request.
    • [#1198] DOC: Add copy button to code blocks. Thanks to Andreas Deininger for the pull request.
    • [#1201] DOC: User manual checksum example: add Kotlin source code on second tab. Thanks to Andreas Deininger for the pull request.
    • [#1202] DOC: Update to latest Asciidoctor gradle plugin. Thanks to Andreas Deininger for the pull request.
    • [#1203] DOC: Replace 'coderay' source code highlighter with 'rouge' to support Kotlin, Scala and Groovy. Thanks to Andreas Deininger for the pull request.
    • [#1205] DOC: User manual checksum example: add more tabs for Groovy, Groovy script and Scala. Thanks to Andreas Deininger for the pull request.
    • [#1208] DOC: Fix: Show copy buttons in code blocks with latest Asciidoctor gradle plugin. Thanks to Andreas Deininger for the pull request.
    • [#1209] DOC: Show Maven coordinates in JLine2/3 README. Thanks to Jiří Holuša for the pull request.
    • [#1210] DOC: User manual subcommands example: add tab with Kotlin source code. Thanks to Andreas Deininger for the pull request.
    • [#1211] DOC: User manual subcommands section: add several tabs with Kotlin source code. Thanks to Andreas Deininger for the pull request.
    • [#1170] TEST: Ensure ANSI is disabled in ManPageGeneratorTest regardless of environment. Thanks to David Walluck for the pull request.
    • [#1166][#1103] TEST: Ensure ANSI is disabled in TracerTest regardless of environment. Thanks to David Walluck for the pull request.
    • [#1179] TEST: Use .invalid domain name for InetAddress test. Thanks to David Phillips for the pull request.
    • [#1178] BUILD: Run Travis build on macOS. Thanks to David Phillips for the pull request.
    • [#1192] Dependency Upgrade: Bump AsciiDoctor to 2.1.0 from 1.6.2. Thanks to Andreas Deininger for the pull request.

    Deprecations

    No features were deprecated in this release.

    Potential breaking changes

    This release has no breaking changes.

    Source code(tar.gz)
    Source code(zip)
    picocli-4.5.2.jar(381.10 KB)
    picocli-4.5.2.jar.asc(821 bytes)
    picocli-all-4.5.2.zip(4.10 MB)
    picocli-codegen-4.5.2.jar(124.72 KB)
    picocli-codegen-4.5.2.jar.asc(821 bytes)
    picocli-groovy-4.5.2.jar(7.16 KB)
    picocli-groovy-4.5.2.jar.asc(821 bytes)
    picocli-shell-jline2-4.5.2.jar(1.67 KB)
    picocli-shell-jline2-4.5.2.jar.asc(821 bytes)
    picocli-shell-jline3-4.5.2.jar(8.42 KB)
    picocli-shell-jline3-4.5.2.jar.asc(821 bytes)
    picocli-spring-boot-starter-4.5.2.jar(2.82 KB)
    picocli-spring-boot-starter-4.5.2.jar.asc(821 bytes)
  • v4.5.1(Aug 26, 2020)

    Picocli 4.5.1

    The picocli community is pleased to announce picocli 4.5.1.

    This release contains bug fixes and enhancements.

    Fixed bug in the picocli-codegen annotation processor that resulted in errors in native images that used ManPageGenerator as subcommand.

    Suppress generation of Gradle Module Metadata, to fix Gradle build failures for projects using picocli 4.4.0 or 4.5.0.

    Fixed terminal width detection on macOS.

    The user manual now has a new section on Validation. Various other documentation improvements.

    This is the seventy-third public release. Picocli follows semantic versioning.

    Table of Contents

    New and Noteworthy

    Fixed issues

    • [#1151] Bugfix: ManPageGenerator as subcommand with native-image throws exception. Thanks to Sebastian Hoß for raising this.
    • [#1152] Bugfix: Gradle build fail when using picocli 4.4.0 or 4.5.0: Gradle Module Metadata for picocli 4.4.0+ missing from Maven Central. Thanks to Frank Pavageau for reporting this.
    • [#1150] Bugfix: Fix terminal width detection on macOS. Thanks to David Phillips for the pull request.
    • [#1142] DOC: Update Kotlin GraalVM native image example - Update native image gradle plugin. Now supports jdk 11. Thanks to OndrejMalek for the pull request.
    • [#1153] DOC: Fix documentation leading code quote. Thanks to sabrina for raising this.
    • [#1147] DOC: Add documentation on how to do custom parameter validation. Thanks to Loren Keagle for raising this.

    Deprecations

    No features were deprecated in this release.

    Potential breaking changes

    This release has no breaking changes.

    Source code(tar.gz)
    Source code(zip)
    picocli-4.5.1.jar(380.60 KB)
    picocli-4.5.1.jar.asc(821 bytes)
    picocli-all-4.5.1.zip(4.10 MB)
    picocli-codegen-4.5.1.jar(124.75 KB)
    picocli-codegen-4.5.1.jar.asc(821 bytes)
    picocli-groovy-4.5.1.jar(7.16 KB)
    picocli-groovy-4.5.1.jar.asc(821 bytes)
    picocli-shell-jline2-4.5.1.jar(1.67 KB)
    picocli-shell-jline2-4.5.1.jar.asc(821 bytes)
    picocli-shell-jline3-4.5.1.jar(8.25 KB)
    picocli-shell-jline3-4.5.1.jar.asc(821 bytes)
    picocli-spring-boot-starter-4.5.1.jar(2.82 KB)
    picocli-spring-boot-starter-4.5.1.jar.asc(821 bytes)
  • v4.5.0(Aug 1, 2020)

    Picocli 4.5.0

    The picocli community is pleased to announce picocli 4.5.0.

    This release contains bug fixes and enhancements.

    The ColorScheme class now has new methods stackTraceText and richStackTraceString, which can be convenient when creating custom error handlers with colors.

    Various bugfixes in the picocli-codegen annotation processor.

    The user manual now has anchor links before all section titles.

    This is the seventy-second public release. Picocli follows semantic versioning.

    Table of Contents

    New and Noteworthy

    Fixed issues

    • [#1129] API: Add methods ColorScheme::stackTraceText(Throwable) and ColorScheme::richStackTraceString(Throwable).
    • [#1124] Enhancement: automatically generate a better summary in the AutoComplete.GenerateCompletion generated man page.
    • [#1126] Enhancement: Make picocli trace levels case-insensitive.
    • [#1128] Enhancement: ParameterException caused by TypeConversionException now have their cause exception set.
    • [#1137] Bugfix: The picocli-codegen annotation processor causes the build to fail with a ClassCastException when an option has completionCandidates defined.
    • [#1134] Bugfix: The picocli-codegen annotation processor should allow @Spec-annotated field in classes implementing IVersionProvider.
    • [#1138] Bugfix: The picocli-codegen annotation processor no longer gives FATAL ERROR: picocli.CommandLine$InitializationException: ArgGroup has no options or positional parameters, and no subgroups during incremental compilation in Intelli/J IDEA.
    • [#1127] DOC: Custom ShortErrorMessageHandler manual example should use bold red for error message.
    • [#1130] DOC: Clarify how to run picocli-based applications.
    • [#1131] DOC: Add anchor links before section titles in user manual.

    Deprecations

    No features were deprecated in this release.

    Potential breaking changes

    This release has no breaking changes.

    Source code(tar.gz)
    Source code(zip)
    picocli-4.5.0.jar(380.54 KB)
    picocli-4.5.0.jar.asc(821 bytes)
    picocli-all-4.5.0.zip(4.09 MB)
    picocli-codegen-4.5.0.jar(124.52 KB)
    picocli-codegen-4.5.0.jar.asc(821 bytes)
    picocli-groovy-4.5.0.jar(7.16 KB)
    picocli-groovy-4.5.0.jar.asc(821 bytes)
    picocli-shell-jline2-4.5.0.jar(1.67 KB)
    picocli-shell-jline2-4.5.0.jar.asc(821 bytes)
    picocli-shell-jline3-4.5.0.jar(8.25 KB)
    picocli-shell-jline3-4.5.0.jar.asc(821 bytes)
    picocli-spring-boot-starter-4.5.0.jar(2.82 KB)
    picocli-spring-boot-starter-4.5.0.jar.asc(821 bytes)
  • v4.4.0(Jul 5, 2020)

    Picocli 4.4.0

    The picocli community is pleased to announce picocli 4.4.0.

    This release contains over 45 bugfixes, enhancements, and new features.

    A major new feature in this release is support for abbreviated options and subcommands. When abbreviations are enabled, users can specify the initial letter(s) of the first "component" and optionally of one or more subsequent components of an option or subcommand name. "Components" are parts of a name, separated by - dash characters or by upper/lower case. So for example, both --CamelCase and --kebab-case have two components. For details see the New and Noteworthy section below.

    Another important change are parser fixes and improvements: the parser will no longer assign values that match an option name to options that take a parameter, unless the value is in quotes. Also, values that resemble, but not exactly match, option names are now treated more consistently and parser behaviour for such values is configurable.

    Also worth hightlighting: from this release, the ManPageGenerator tool can be used as a subcommand in your application.

    There are many more improvements in this release: it is now easier to customize the usage help message, there are JANSI fixes, and other bugfixes and enhancements. See the Fixed Issues list for details.

    This is the seventy-first public release. Picocli follows semantic versioning.

    Table of Contents

    New and Noteworthy

    Abbreviated Options and Subcommands

    Since picocli 4.4, the parser can recognize abbreviated options and subcommands. This needs to be enabled explicitly with CommandLine::setAbbreviatedOptionsAllowed and CommandLine::setAbbreviatedSubcommandsAllowed.

    Recognized Abbreviations

    When abbreviations are enabled, users can specify the initial letter(s) of the first component and optionally of one or more subsequent components of an option or subcommand name.

    "Components" are separated by - dash characters or by case, so for example, both --CamelCase and --kebab-case have two components.

    NOTE: When case sensitivity is disabled, only the - dash character can be used to separate components.

    Examples of valid abbreviations:

    Option or Subcommand | Recognized Abbreviations
    -------------------- | ------------------------
    --veryLongCamelCase  | --very, --vLCC  --vCase
    --super-long-option  | --sup, --sLO, --s-l-o, --s-lon, --s-opt, --sOpt
    some-long-command    | so, sLC, s-l-c, soLoCo, someCom
    

    Ambiguous Abbreviations

    When the user specifies input that can match multiple options or subcommands, the parser throws a ParameterException. When applications use the execute method, a short error message and the usage help is displayed to the user.

    For example, given a command with subcommands help and hello, then ambiguous user input like hel will show this error message:

    Error: 'hel' is not unique: it matches 'hello', 'help'
    

    Abbreviated Long Options and POSIX Clustered Short Options

    When an argument can match both a long option and a set of clustered short options, picocli matches the long option.

    For example:

    class AbbreviationsAndPosix {
        @Option(names = "-A") boolean a;
        @Option(names = "-B") boolean b;
        @Option(names = "-AaaBbb") boolean aaaBbb;
    }
    AbbreviationsAndPosix app = new AbbreviationsAndPosix();
    new CommandLine(app).setAbbreviatedOptionsAllowed(true).parseArgs("-AB");
    assertTrue(app.aaaBbb);
    assertFalse(app.a);
    assertFalse(app.b);
    

    When abbreviated options are enabled, user input -AB will match the long -AaaBbb option, but not the -A and -B options.

    Parser Fixes and Improvements

    Option Names as Option Values

    Options that take a parameter previously were able to take option names as the parameter value. From this release, this is no longer possible. The parser will no longer assign values that match an option name to an option, unless the value is in quotes. For example:

    class App {
        @Option(names = "-x") String x;
        @Option(names = "-y") String y;
    
        public static void main(String... args) {
            App app = new App();
            new CommandLine(app).setTrimQuotes(true).parseArgs(args);
            System.out.printf("x='%s', y='%s'%n", app.x, app.y);
        }
    }
    

    In previous versions of picocli, the above command would accept input -x -y, and the value -y would be assigned to the x String field. From this release, the above input will be rejected with an error message indicating that the -x option requires a parameter.

    If it is necessary to accept values that match option names, these values need to be quoted. For example:

    java App -x="-y"
    

    This will print the following output:

    x='-y', y='null'
    

    Vararg Positional Parameters No Longer Consume Unmatched Options

    Vararg positional arguments no longer consume unmatched options unless configured to do so. For example:

    class App {
        @Parameters(arity = "*") String[] positionals;
    }
    

    In previous versions of picocli, the parser behaviour was not consistent:

    • input -z 123 would be rejected with error "Unmatched argument: '-z'
    • input 123 -z would be accepted and the positionals String array would contain two values, 123 and -z

    (Note that this problem only occurred with multi-value positional parameters defined with variable arity: arity = "*".)

    From this release, both of the above input sequences will be rejected with an error message indicating that -z is an unknown option. As before, to accept such values as positional parameters, call CommandLine::setUnmatchedOptionsArePositionalParams with true.

    Configure Whether Options Should Consume Unknown Options

    By default, options accept parameter values that "resemble" (but don't exactly match) an option.

    This release introduces a CommandLine::setUnmatchedOptionsAllowedAsOptionParameters method that makes it possible to configure the parser to reject values that resemble options as option parameters. Setting it to false will result in values resembling option names being rejected as option values.

    For example:

    class App {
        @Option(names = "-x") String x;
    }
    

    By default, a value like -z, which resembles an option, is accepted as the parameter for -x:

    App app = new App();
    new CommandLine(app).parseArgs("-x", "-z");
    assertEquals("-z", app.x);
    

    After setting the unmatchedOptionsAllowedAsOptionParameters parser option to false, values resembling an option are rejected as parameter for -x:

    new CommandLine(new App())
            .setUnmatchedOptionsAllowedAsOptionParameters(false)
            .parseArgs("-x", "-z");
    

    This will throw an UnmatchedArgumentException with message:

    "Unknown option '-z'; Expected parameter for option '-x' but found '-z'"
    

    NOTE: Negative numbers are not considered to be unknown options, so even when unmatchedOptionsAllowedAsOptionParameters is set to false, option parameters like -123, -NaN, -Infinity, -#ABC and -0xCAFEBABE will not be rejected for resembling but not matching an option name.

    ManPageGenerator as Subcommand in Your App

    From picocli 4.4, the ManPageGenerator tool can be used as a subcommand in your application, with the usual syntax:

    import picocli.codegen.docgen.manpage.ManPageGenerator;
    
    @Command(subcommands = ManPageGenerator.class)
    ...
    

    To use the ManPageGenerator tool as a subcommand, you will need the picocli-codegen jar in your classpath.

    Fixed issues

    • [#10][#732][#1047] API: Support abbreviated options and commands. Thanks to NewbieOrange for the pull request.
    • [#639] API: Add method CommandLine::is/setUnmatchedOptionsAllowedAsOptionParameters to disallow option parameter values resembling option names. Thanks to Peter Murray-Rust for raising this.
    • [#1074][#1075] API: Added method ParseResult::expandedArgs to return the list of arguments after @-file expansion. Thanks to Kevin Bedi for the pull request.
    • [#1052] API: Show/Hide commands in usage help on specific conditions. Thanks to Philippe Charles for raising this.
    • [#1088] API: Add method Help::allSubcommands to return all subcommands, including hidden ones. Clarify the semantics of Help::subcommands.
    • [#1090] API: Add methods Help::optionListExcludingGroups to return a String with the rendered section of the usage help containing only the specified options, including hidden ones.
    • [#1092] API: Add method Help::parameterList(List<PositionalParamSpec>) to return a String with the rendered section of the usage help containing only the specified positional parameters, including hidden ones.
    • [#1093] API: Add method Help::commandList(Map<String, Help>) to return a String with the rendered section of the usage help containing only the specified subcommands, including hidden ones.
    • [#1091] API: Add method Help::optionListGroupSections to return a String with the rendered section of the usage help containing only the option groups.
    • [#1089] API: Add method Help::createDefaultOptionSort to create a Comparator that follows the command and options' configuration.
    • [#1084][#1094] API: Add method Help::createDefaultLayout(List<OptionSpec>, List<PositionalParamSpec>, ColorScheme) to create a layout for the specified options and positionals.
    • [#1087] API: Add methods ArgumentGroupSpec::allOptionsNested and ArgumentGroupSpec::allPositionalParametersNested.
    • [#1086] API: add methods Help.Layout::addAllOptions and Help.Layout::addAllPositionals, to show all specified options, including hidden ones.
    • [#1085] API: Add method Help::optionSectionGroups to get argument groups with a header.
    • [#1101] API: Add method Help::createDetailedSynopsisOptionsText to specify which options to show in the synopsis.
    • [#1061] API: Add method Help::makeSynopsisFromParts for building complex synopsis strings; synopsis now shows non-group options before argument groups, for a more natural synopsis when groups contain only positional parameters.
    • [#983] Allow making inherited options hidden on subcommands. This can now be accomplished with the new Help methods by providing a custom option list and customizing the synopsis.
    • [#1051][#1056] Enhancement: GenerateCompletion command no longer needs to be a direct subcommand of the root command. Thanks to Philippe Charles for the pull request.
    • [#1083] Enhancement: @Command-annotated methods no longer need the enclosing class to have a @Command annotation.
    • [#1068] Enhancement: Make ParserSpec::toString output settings in alphabetic order.
    • [#1069] Enhancement: Debug output should show optionsCaseInsensitive and subcommandsCaseInsensitive settings.
    • [#1070] Enhancement: Code cleanup: removed redundant modifiers and initializations, unused variables, incorrect javadoc references, and more. Thanks to NewbieOrange for the pull request.
    • [#1096] Enhancement: Override Help.Column equals, hashCode and toString methods to facilitate testing.
    • [#1106] Enhancement: First check if JANSI is explicitly disabled without loading any JANSI classes, to avoid JANSI extracting a DLL to the temporary folder when one of its classes is loaded. This avoids problems where AppLocker can forbid loading of non-signed libraries from the Windows temporary folder. Thanks to Philippe Charles for raising this.
    • [#1110] Enhancement: Fix broken javadoc links, fix Kotlin compiler warnings, bump to latest Kotlin and Scala versions. Thanks to Andreas Deininger for the pull request.
    • [#1109][#1112] Enhancement: Fix ManPageGenerator to ensure generated AsciiDoc man pages use UTF-8 encoding. Thanks to Andreas Deininger for the pull request.
    • [#1063][#1064] ManPageGenerator now correctly excludes hidden options, parameters, and subcommands from man page generation. Thanks to Brian Demers for the pull request.
    • [#1103] Enhancement: Tests no longer fail under Cygwin/ConEmu due to ANSI in output. Thanks to David Walluck for raising this.
    • [#1055] Bugfix: The parser will no longer assign values that match an option name to options that take a parameter, unless the value is in quotes. Thanks to waacc-gh for raising this.
    • [#1015] Bugfix: Parser improvement: varargs positional arguments no longer consume unmatched options unless unmatchedOptionsArePositionalParams is configured. Thanks to Chris Smowton for raising this.
    • [#1071] Bugfix: Usage help no longer renders options header when it is specified via optionListHeading when all options are hidden.
    • [#1076] Bugfix: Don't generate Autocomplete for hidden commands. Thanks to power721 for raising this.
    • [#1081] Bugfix: CommandLine.Help constructor no longer calls overridable methods addAllSubcommands and createDefaultParamLabelRenderer.
    • [#1065] Bugfix: With a List<> option in @ArgGroup, group incorrectly appears twice in the synopsis. Thanks to kap4lin for raising this.
    • [#1067] Bugfix: ParserSpec::initFrom was not copying useSimplifiedAtFiles.
    • [#1054] Bugfix: Fixed issue in argument group parsing where incorrect input with missing mandatory elements was accepted when an option was specified multiple times. Thanks to waacc-gh for raising this.
    • [#1072] Bugfix: Mixin UsageMessageSpec::width and UsageMessageSpec::longOptionsMaxWidth is no longer ignored.
    • [#1100] Bugfix: The factory of the original CommandSpec is now correctly used in the CommandSpec copy for repeatable subcommands. Thanks to Michael Kunz for the pull request.
    • [#1058][#1059] DOC: Man page generator: fix incorrect asciidoctor call in synopsis. Thanks to Andreas Deininger for the pull request.
    • [#1058][#1060] DOC: Man page generator: add documentation about creating language variants. Thanks to Andreas Deininger for the pull request.
    • [#1120] Clean up compiler warnings.
    • [#1073] DOC: Improve user manual: fix typos, update content. Thanks to Andreas Deininger for the pull request.
    • [#1102] DOC: Show descriptionKeys for @file and EndOfOptions (--) delimiter in resource bundles.
    • [#1116] DOC: Improved Guice example in user manual. Thanks to H.Sakata for the pull request.
    • [#1098][#1117] DOC: Simplify JLine 3 documentation by moving examples for older JLine 3 and picocli to the picocli wiki. Thanks to Kevin Arthur for the pull request.
    • [#1121] DOC: Link to alternative in @deprecated Javadoc tag for Help::addSubcommand.
    • [#1099] Dependency Upgrade: Bump JLine to 3.15.0. Thanks to mattirn for the pull request.

    Deprecations

    No features were deprecated in this release.

    Potential breaking changes

    Parser Changes

    The parser behaviour has changed: picocli will no longer assign values that match an option name to options that take a parameter, unless the value is in quotes. Applications that rely on this behaviour need to use quoted values.

    Error Message for Unknown Options

    Unmatched arguments that look like options now result in an error message Unknown option: '-unknown'.

    Previously, the error message was: Unmatched argument: '-unknown'.

    Usage Help: Synopsis for Arg Groups

    This release changes the synopsis for commands with argument groups: the synopsis now shows the non-group options before argument groups, where previously argument groups were shown first.

    This gives a more natural synopsis when groups contain only positional parameters.

    Source code(tar.gz)
    Source code(zip)
    picocli-4.4.0.jar(380.20 KB)
    picocli-all-4.4.0.zip(4.07 MB)
    picocli-codegen-4.4.0.jar(123.79 KB)
    picocli-groovy-4.4.0.jar(7.16 KB)
    picocli-shell-jline2-4.4.0.jar(1.67 KB)
    picocli-shell-jline3-4.4.0.jar(8.25 KB)
    picocli-spring-boot-starter-4.4.0.jar(2.82 KB)
  • v4.3.2(May 16, 2020)

    Picocli 4.3.2

    The picocli community is pleased to announce picocli 4.3.2.

    This release fixes a bug where the stack trace of an exception in the business logic would omit nested cause exceptions.

    This is the seventieth public release. Picocli follows semantic versioning.

    Table of Contents

    New and Noteworthy

    Fixed issues

    [#1048][#1049] Bugfix: Cause exception not printed by default execution exception handler. Thanks to Neko Null for the pull request.

    Deprecations

    No features were deprecated in this release.

    Potential breaking changes

    This release has no breaking changes.

    Source code(tar.gz)
    Source code(zip)
    picocli-4.3.2.jar(373.27 KB)
    picocli-all-4.3.2.zip(4.15 MB)
    picocli-codegen-4.3.2.jar(121.87 KB)
    picocli-groovy-4.3.2.jar(7.16 KB)
    picocli-shell-jline2-4.3.2.jar(1.67 KB)
    picocli-shell-jline3-4.3.2.jar(8.02 KB)
    picocli-spring-boot-starter-4.3.2.jar(2.82 KB)
  • v4.3.1(May 14, 2020)

    Picocli 4.3.1

    The picocli community is slightly embarrassed to announce picocli 4.3.1. :-)

    This release fixes some critical bugs:

    • an IllegalArgumentException: wrong number of arguments was thrown when the @Option(scope = INHERIT) feature is used in a command that has subcommands defined in @Command-annotated methods
    • a NullPointerException was thrown in DefaultParamLabelRenderer.renderParameterLabel for programmatically built models that have a non-null split regex and do not have a splitSynopsisLabel
    • removed a call to the String.isEmpty method, which prevented picocli from running on Java 5: this method was introduced in Java 6

    See Fixed issues for the full list of changes.

    This is the sixty-nineth public release. Picocli follows semantic versioning.

    Table of Contents

    New and Noteworthy

    Fixed issues

    [#1042] Bugfix: "wrong number of arguments" exception when using inherited options with @Command-annotated methods. Thanks to Garret Wilson for raising this. [#1043] Bugfix: NullPointerException thrown in DefaultParamLabelRenderer.renderParameterLabel for programmatically built models that have a non-null split regex and do not have a splitSynopsisLabel. [#1044] Bugfix: only display splitSynopsisLabel in usage help message if the option has a split regex. Thanks to Andreas Deininger for raising this. [#1045] Bugfix: replace use of Java 6 API String.isEmpty with picocli-internal Java 5 equivalent. [#1046] DOC: mention picocli's programmatic API and link to the programmatic API documentation from the user manual.

    Deprecations

    No features were deprecated in this release.

    Potential breaking changes

    This release has no breaking changes.

    Source code(tar.gz)
    Source code(zip)
    picocli-4.3.1.jar(372.40 KB)
    picocli-all-4.3.1.zip(4.14 MB)
    picocli-codegen-4.3.1.jar(121.87 KB)
    picocli-groovy-4.3.1.jar(7.16 KB)
    picocli-shell-jline2-4.3.1.jar(1.67 KB)
    picocli-shell-jline3-4.3.1.jar(8.02 KB)
    picocli-spring-boot-starter-4.3.1.jar(2.82 KB)
  • v4.3.0(May 12, 2020)

    Picocli 4.3.0

    The picocli community is pleased to announce picocli 4.3.0.

    This is a fairly big release with 70 tickets closed, and over 50 bugfixes and enhancements. Many thanks to the picocli community who contributed 21 pull requests!

    A major theme of this release is sharing options between commands:

    • New feature: "inherited" options. Options defined with scope = ScopeType.INHERIT are shared with all subcommands (and sub-subcommands, to any level of depth). Applications can define an inherited option on the top-level command, in one place, to allow end users to specify this option anywhere: not only on the top-level command, but also on any of the subcommands and nested sub-subcommands.
    • More powerful mixins. Mixin classes can declare a @Spec(MIXEE)-annotated field, and picocli will inject the CommandSpec of the command receiving this mixin (the "mixee") into this field. This is useful for mixins containing shared logic, in addition to shared options and parameters.

    Another major theme is improved support for positional parameters:

    • Automatic indexes for positional parameters. Single-value positional parameters without an explicit index = "..." attribute are now automatically assigned an index based on the other positional parameters in the command. One use case is mixins with positional parameters.
    • Repeatable ArgGroups can now define positional parameters.

    Other improvements:

    • The parser now supports case-insensitive mode for options and subcommands.
    • Error handlers now use ANSI colors and styles. The default styles are bold red for the error message, and italic for stack traces. Applications can customize with the new Help.ColorScheme methods errors and stackTraces.
    • The usage help message can now show an entry for -- in the options list with the @Command(showEndOfOptionsDelimiterInUsageHelp = true) annotation.
    • Easily make subcommands mandatory by making the top-level command a class that does not implement Runnable or Callable.

    This is the sixty-eighth public release. Picocli follows semantic versioning.

    Table of Contents

    New and Noteworthy

    Inherited Options

    This release adds support for "inherited" options. Options defined with scope = ScopeType.INHERIT are shared with all subcommands (and sub-subcommands, to any level of depth). Applications can define an inherited option on the top-level command, in one place, to allow end users to specify this option anywhere: not only on the top-level command, but also on any of the subcommands and nested sub-subcommands.

    Below is an example where an inherited option is used to configure logging.

    @Command(name = "app", subcommands = Sub.class)
    class App implements Runnable {
        private static Logger logger = LogManager.getLogger(App.class);
    
        @Option(names = "-x", scope = ScopeType.LOCAL) // option is not shared: this is the default
        int x;
        
        @Option(names = "-v", scope = ScopeType.INHERIT) // option is shared with subcommands, sub-subcommands, etc
        public void setVerbose(boolean verbose) {
            // Configure log4j.
            // This is a simplistic example: you probably only want to modify the ConsoleAppender level.
            Configurator.setRootLevel(verbose ? Level.DEBUG : Level.INFO);
        }
        
        public void run() {
            logger.debug("-x={}", x);
        }
    }
    
    @Command(name = "sub")
    class Sub implements Runnable {
        private static Logger logger = LogManager.getLogger(Sub.class);
    
        @Option(names = "-y")
        int y;
        
        public void run() {
            logger.debug("-y={}", y);
        }
    }
    

    Users can specify the -v option on either the top-level command or on the subcommand, and it will have the same effect.

    # the -v option can be specified on the top-level command
    java App -x=3 -v sub -y=4
    

    Specifying the -v option on the subcommand will have the same effect. For example:

    # specifying the -v option on the subcommand also changes the log level
    java App -x=3 sub -y=4 -v
    

    NOTE: Subcommands don't need to do anything to receive inherited options, but a potential drawback is that subcommands do not get a reference to inherited options.

    Subcommands that need to inspect the value of an inherited option can use the @ParentCommand annotation to get a reference to their parent command, and access the inherited option via the parent reference. Alternatively, for such subcommands, sharing options via mixins may be a more suitable mechanism.

    Case-insensitive mode

    By default, all options and subcommands are case sensitive. Case sensitivity can be switched off globally, as well as on a per-command basis.

    To toggle case sensitivity for all commands, use the CommandLine::setSubcommandsCaseInsensitive and CommandLine::setOptionsCaseInsensitive methods. Use the CommandSpec::subcommandsCaseInsensitive and CommandSpec::optionsCaseInsensitive methods to give some commands a different case sensitivity than others.

    Automatic Indexes for Positional Parameters

    From this release, when the index = "..." attribute is omitted, the default index is index = "0+", which tells picocli to assign an index automatically, starting from zero, based on the other positional parameters defined in the same command.

    A simple example can look like this:

    class AutomaticIndex {
        @Parameters(hidden = true)  // "hidden": don't show this parameter in usage help message
        List<String> allParameters; // no "index" attribute: captures _all_ arguments
    
        @Parameters String group;    // assigned index = "0"
        @Parameters String artifact; // assigned index = "1"
        @Parameters String version;  // assigned index = "2"
    }
    

    Picocli initializes fields with the values at the specified index in the arguments array.

    String[] args = { "info.picocli", "picocli", "4.3.0" };
    AutomaticIndex auto = CommandLine.populateCommand(new AutomaticIndex(), args);
    
    assert auto.group.equals("info.picocli");
    assert auto.artifact.equals("picocli");
    assert auto.version.equals("4.3.0");
    assert auto.allParameters.equals(Arrays.asList(args));
    

    The default automatic index (index = "0+") for single-value positional parameters is "anchored at zero": it starts at zero, and is increased with each additional positional parameter.

    Sometimes you want to have indexes assigned automatically from a different starting point than zero. This can be useful when defining Mixins with positional parameters.

    To accomplish this, specify an index with the anchor point and a + character to indicate that picocli should start to automatically assign indexes from that anchor point. For example:

    class Anchored {
        @Parameters(index = "1+") String p1; // assigned index = "1" or higher
        @Parameters(index = "1+") String p2; // assigned index = "2" or higher
    }
    

    Finally, sometimes you want to have indexes assigned automatically to come at the end. Again, this can be useful when defining Mixins with positional parameters.

    To accomplish this, specify an index with a + character to indicate that picocli should automatically assign indexes that come at the end. For example:

    class Unanchored {
        @Parameters(index = "+") String penultimate; // assigned the penultimate index in the command
        @Parameters(index = "+") String last;        // assigned the last index in the command
    }
    

    Repeatable ArgGroups with Positional Parameters

    From this release, positional parameters can be used in repeating Argument Groups.

    When a @Parameters positional parameter is part of a group, its index is the index within the group, not within the command.

    Below is an example of an application that uses a repeating group of positional parameters:

    @Command(name = "grades", mixinStandardHelpOptions = true, version = "grades 1.0")
    public class Grades implements Runnable {
    
        static class StudentGrade {
            @Parameters(index = "0") String name;
            @Parameters(index = "1") BigDecimal grade;
        }
    
        @ArgGroup(exclusive = false, multiplicity = "1..*")
        List<StudentGrade> gradeList;
    
        @Override
        public void run() {
            gradeList.forEach(e -> System.out.println(e.name + ": " + e.grade));
        }
    
        public static void main(String[] args) {
            System.exit(new CommandLine(new Grades()).execute(args));
        }
    }
    

    Running the above program with this input:

    Alice 3.1 Betty 4.0 "X Æ A-12" 3.5 Zaphod 3.4
    

    Produces the following output:

    Alice: 3.1
    Betty: 4.0
    X Æ A-12: 3.5
    Zaphod: 3.4
    

    @Spec(MIXEE) Annotation

    From this release, mixins are more powerful. Mixin classes can declare a @Spec(MIXEE)-annotated field, and picocli will inject the CommandSpec of the command receiving this mixin (the "mixee") into this field. This is useful for mixins containing shared logic, in addition to shared options and parameters.

    Since picocli 4.3, the @Spec annotation has a value element. The value is Spec.Target.SELF by default, meaning that the CommandSpec of the enclosing class is injected into the @Spec-annotated field.

    For classes that are used as a mixins, there is another value that may be useful. When @Spec(Spec.Target.MIXEE) is specified in a mixin class, the CommandSpec of the command receiving this mixin (the "mixee") is injected into the @Spec-annotated field. This can be useful when a mixin contains logic that is common to many commands. For example:

    import picocli.CommandLine.Option;
    import picocli.CommandLine.Spec;
    
    class AdvancedMixin {
        @Spec(Spec.Target.MIXEE) CommandSpec mixee;
    
        /**
         * When the -x option is specified on any subcommand,
         * multiply its value with another integer supplied by this subcommand
         * and set the result on the top-level command.
         * @param x the value of the -x option
         */
        @Option(names = "-x")
        void setValue(int x) {
            // Get another value from the command we are mixed into.
            // This mixin requires the command(s) it is mixed into to implement `IntSupplier`.
            int y = ((java.util.function.IntSupplier) mixee.userObject()).getAsInt();
    
            int product = x * y;
    
            // Set the result on the top-level (root) command.
            // This mixin requires the root command to implement `IntConsumer`.
            ((java.util.function.IntConsumer) mixee.root().userObject()).accept(product);
        }
    }
    

    Showing -- End of Options in usage help

    From picocli 4.3, an entry for the -- End of Options delimiter can be shown in the options list of the usage help message of a command with the @Command(showEndOfOptionsDelimiterInUsageHelp = true) annotation.

    Example command:

    @Command(name = "myapp", showEndOfOptionsDelimiterInUsageHelp = true,
            mixinStandardHelpOptions = true, description = "Example command.")
    class MyApp {
        @Parameters(description = "A file.") File file;
    }
    

    The usage help message for this command looks like this:

    Usage: myapp [-hV] [--] <file>
    Example command.
          <file>      A file.
      -h, --help      Show this help message and exit.
      -V, --version   Print version information and exit.
      --              This option can be used to separate command-line options from
                        the list of positional parameters.
    

    Fixed issues

    • [#649][#948] Provide convenience API for inherited/global options (was: Feature request: inheriting mixins in subcommands). Thanks to Garret Wilson for the request and subsequent discussion (and patience!).
    • [#1001] Support required inherited options.
    • [#996] Default values should not be applied to inherited options.
    • [#985] API: Show end-of-options -- in usage help options list.
    • [#958] API: Add @Spec(Spec.Target.MIXEE) annotation element to allow mixins to get a reference to the command they are mixed into.
    • [#960] API: Add method CommandSpec::root to return the CommandSpec of the top-level command.
    • [#484][#845][#1008] API: Error handlers now use ANSI colors and styles. Added methods errors and stackTraces to Help.ColorScheme. Thanks to Neko Null for the pull request.
    • [#765][#1017] API: Added splitSynopsisLabel attribute on @Option and @Parameters for controlling how split regular expressions are displayed in the synopsis. Thanks to Murphy Han for the pull request and thanks to deining for raising this.
    • [#9][#1021][#1020][#1023][#154] API: Added support for case-insensitive subcommands and options. Thanks to NewbieOrange for the pull request, thanks to ifsheldon for exploring alternative solutions and helping clarify the requirements, and thanks to Neko Null for the pull request with documentation and executable examples.
    • [#564] Add support for relative indices for positional parameters. Useful in mixins and inherited positional parameters. Thanks to krisleonard-mcafee for raising this topic.
    • [#956] Enhancement: Default ParameterExceptionHandler should show stack trace when tracing is set to DEBUG level.
    • [#952] Enhancement: Make annotation processor quiet by default; add -Averbose annotation processor option to enable printing NOTE-level diagnostic messages to the console.
    • [#959] Enhancement: Print "Missing required subcommand" instead of throwing exception if command with subcommands does not implement Runnable or Callable. Thanks to Max Rydahl Andersen for the suggestion.
    • [#693][#1009][#1011] Enhancement: Add autocompletion for the built-in HelpCommand. Thanks to NewbieOrange for the pull request.
    • [#1022][#1029] Enhancement/Bugfix: Duplicate negated options were incorrectly accepted. Thanks to NewbieOrange for the pull request.
    • [#1030][#1029] Enhancement/Bugfix: setOptionsCaseInsensitive should make negatable options case insensitive. Thanks to NewbieOrange for the pull request.
    • [#1027][#1036] Enhancement: Support repeatable ArgGroups with positional parameters. Thanks to NewbieOrange for the pull request.
    • [#974] Enhancement/Bugfix: Add support for @ArgGroup argument groups in @Command-annotated methods. Thanks to Usman Saleem for raising this.
    • [#962][#961] Enhancement/Bugfix: Default value should only be applied if value is missing. Thanks to 粟嘉逸 and chirlo for raising this.
    • [#995][#1024][#1035] Enhancement/Bugfix: Reset multi-value options/positional params to initial value when reusing CommandLine instances. Thanks to Linyer-qwq, WU Jiangning, and Wycers for the pull request.
    • [#991][#993] Enhancement/Bugfix: Detecting terminal width fails on non-English Windows versions. Thanks to Stefan Gärtner for the pull request.
    • [#1040] Enhancement: internal code cleanup and minor fixes. Thanks to NewbieOrange for the pull request.
    • [#987] Bugfix: Bump JLine to 3.14.1 and fix [#969] autocompletion in Picocli Shell JLine3. Thanks to mattirn for the pull request.
    • [#969] Bugfix: Fixed broken autocompletion for nested subcommands in Picocli Shell JLine3. Thanks to niklas97 for raising this.
    • [#968] Bugfix: Avoid creating user object in Help constructor. Thanks to Immueggpain for raising this.
    • [#990] Bugfix: Options in subcommands were not reset to their initial value between invocations when the CommandLine object is reused. Thanks to marinier for pointing this out.
    • [#984][#997] Bugfix: Parameters heading is now shown in the usage help message when @filename is the only parameter. Thanks to Wycer for the pull request.
    • [#1004] Bugfix: Prevent NullPointerException in IParameterConsumer with @Option in @ArgGroup. Thanks to masupilami for raising this.
    • [#988][#1002] Bugfix: Option group sections in the usage help message now include subgroup options. Thanks to Wycer for the pull request.
    • [#957] Bugfix: Debug tracing now shows variable value instead of variable name.
    • [#955] Bugfix: TargetInvocationMessage handling in MethodBinding.set methods should use getTargetException not getCause; better error reporting.
    • [#1007] Bugfix: Custom Type Converters are missing for repeated subcommands. Thanks to Bastian Diehl for raising this.
    • [#1026] Bugfix: Hidden options should not impact usage help.
    • [#1034] Bugfix: Writer should flush() in UnmatchedArgumentException.printSuggestions. Thanks to darkmoonka for raising this.
    • [#963] DOC: Fixed broken link in README. Thanks to vladimirf7 for the pull request.
    • [#895] DOC: Added Initialization Before Execution section on initialization with subcommands to the user manual. Thanks to Walter Scott Johnson for raising this.
    • [#951] DOC: Fixed typo in picocli-codegen annotation processor documentation: disable.resource.config is correct (the option name was incorrectly spelled as disable.resources.config). Thanks to Max Rydahl Andersen for raising this.
    • [#966] DOC: Add section about Testing to the user manual.
    • [#973] DOC: Update documentation for using the picocli-codegen annotation processor during the build with Kotlin.
    • [#972] DOC: Add section "Handling Invalid Input" for custom type converters to user manual, demonstrating TypeConversionException. Add example InetSocketAddressConverter to picocli-examples. Thanks to Simon for raising this.
    • [#975] DOC: Update user manual Annotation Processor section to use ${project.groupId} instead of deprecated ${groupId}. Thanks to Dmitry Timofeev for the pull request.
    • [#976] DOC: Update user manual Testing section; add subsection on Testing Environment Variables. Thanks to David M. Carr for raising this and providing a sample project.
    • [#979][#981] DOC: Update user manual: add section Options with an Optional Parameter. Thanks to razvanh, Jake and mohdpasha for raising this.
    • [#989] DOC: Update examples for picocli-shell-jline3 prior to and after the [#987][#969] bugfix. Thanks to Ralf D. Müller for raising this.
    • [#998] DOC: Update manual: quote option parameter containing pipe characters in split regex for FIX message example. Thanks to Galder Zamarreño and Max Rydahl Andersen for raising this and subsequent discussion.
    • [#1012] DOC: Update user manual: add to ArgGroup limitations. Thanks to masupilami and patric-r for raising this and subsequent discussion.
    • [#1015] DOC: Update user manual: added section Variable Arity Options and Unknown Options. Thanks to Chris Smowton for raising this.
    • [#1019] DOC: Fix PrintExceptionMessageHandler example. Thanks to Adam Hosman for the pull request.
    • [#1006] DOC: Add Mixin example: MyLogger to the user manual.
    • [#1028][#1031] DOC: Update user manual: added Java 15 text blocks example. Thanks to Enderaoe for the pull request.
    • [#1037] DOC: Update user manual for programmatic API: fix typo. Thanks to Yoshida for the pull request.
    • [#1041] DOC: Fix broken links in javaDoc. Thanks to Andreas Deininger for the pull request.
    • [#1033] TEST: Added tests for [#984][#997]. Thanks to WU Jiangning for the pull request.
    • [#965] Dependency Upgrade: in picocli-examples, bump hibernate-validator from 6.0.2 to 6.1.2 to deal with CVE-2019-10219. Thanks to https://github.com/Security3rd for raising this.

    Deprecations

    No features were deprecated in this release.

    Potential breaking changes

    Behaviour has changed for some cases involving positional parameters. One example is applications that define multiple positional parameters without an explicit index (see next section). I hope these are edge cases. Other than that, some error messages and details of the usage help message have changed. See details below.

    Default index for single-value positional parameters

    Prior to picocli 4.3.0, if your application defines any single-value positional parameters without explicit index, these parameters would all point to index zero. From picocli 4.3.0, picocli automatically assigns an index, so the first such parameter gets index 0 (zero), the next parameter gets index 1 (one), the next parameter gets index 2 (two), etc.

    This may break applications that have multiple single-value positional parameters without explicit index, that expect to capture the first argument in all of these parameters.

    Different error when user specifies too many parameters

    The error message has changed when a user specifies more positional parameters than the program can accept. For example:

    class SingleValue {
        @Parameters String str;
    }
    

    This program only accepts one parameter. What happens when this program is invoked incorrectly with two parameters, like this:

    java SingleValue val1 val2
    

    Before this release, picocli would throw an OverwrittenOptionException with message "positional parameter at index 0..* (<str>) should be specified only once".

    From picocli 4.3, picocli throws an UnmatchedArgumentException with message "Unmatched argument at index 1: 'val2'".

    This may break applications that have error handling that depends on an OverwrittenOptionException being thrown.

    Different mechanism for dealing with too many parameters

    Continuing with the previous example, before this release, applications could deal with this by allowing single-value options to be overwritten:

    // before
    CommandLine cmd = new CommandLine(new SingleValue());
    cmd.setOverwrittenOptionsAllowed(true);
    // ...
    

    From picocli 4.3, applications need to allow unmatched arguments instead:

    // after
    CommandLine cmd = new CommandLine(new SingleValue());
    cmd.setUnmatchedArgumentsAllowed(true);
    // ...
    // get the invalid values
    cmd.getUnmatchedArguments();
    

    Usage help message for single-value positional parameters

    Before picocli 4.3.0, single-value positional parameters would incorrectly show an ellipsis (...) after their parameter label. This ellipsis is incorrect because it indicates that multiple values can be specified. The ellipsis is no longer shown for single-value positional parameters from picocli 4.3.0.

    Before:

    Usage: <main class> PARAM...
          PARAM...   Param description.
    

    After:

    Usage: <main class> PARAM
          PARAM   Param description.
    

    This may break application tests that expect a specific usage help message format.

    Different error for missing required options or parameters

    Missing options list now starts with colon, no more square brackets

    Before:

    Missing required option '--required=<required>'
    Missing required options [-a=<first>, -b=<second>, -c=<third>]
    

    After:

    Missing required option: '--required=<required>'
    Missing required options: '-a=<first>', '-b=<second>', '-c=<third>'
    

    Better message when both options and positional parameters are missing

    Before:

    Missing required options [-x=<x>, params[0]=<p0>, params[1]=<p1>]
    

    After:

    Missing required options and parameters: '-x=<x>', '<p0>', '<p1>'
    

    Missing positional parameters are now quoted

    Before:

    Missing required parameter: <mandatory>
    Missing required parameters: <mandatory>, <anotherMandatory>
    

    After:

    Missing required parameter: '<mandatory>'
    Missing required parameters: '<mandatory>', '<anotherMandatory>'
    
    Source code(tar.gz)
    Source code(zip)
    picocli-4.3.0.jar(372.50 KB)
    picocli-all-4.3.0.zip(4.14 MB)
    picocli-codegen-4.3.0.jar(121.87 KB)
    picocli-groovy-4.3.0.jar(7.16 KB)
    picocli-shell-jline2-4.3.0.jar(1.67 KB)
    picocli-shell-jline3-4.3.0.jar(8.02 KB)
    picocli-spring-boot-starter-4.3.0.jar(2.82 KB)
  • v4.2.0(Feb 11, 2020)

    Picocli 4.2.0

    The picocli community is pleased to announce picocli 4.2.0.

    This release adds support for Repeatable Subcommands: when a command is marked as @Command(subcommandsRepeatable = true) it becomes possible to specify that command's subcommands multiple times on the command line.

    The picocli-codegen module can now generate AsciiDoc documentation for picocli-based applications. AsciiDoc is a lightweight markup language that can easily can be converted to unix man pages, HTML and PDF with the wonderful asciidoctor tool.

    From this release, subcommands are not instantiated until they are matched on the command line. This should improve the startup time for applications with subcommands that do a lot of initialization when they are instantiated.

    Autocompletion improvements: from this release the generated bash completions scripts support completing positional parameters, and are implemented without the use of associative arrays (so they should work on MacOS or other systems that use older versions of bash). Additionally there are now automated tests using Expect to verify that the generated completion scripts work as expected.

    GraalVM configuration generation improvement: added --factory option to ReflectionConfigGenerator, ResourceConfigGenerator and DynamicProxyConfigGenerator. This makes it possible to generate configurations for command classes without a default no-arg constructor.

    From this release it is possible to inject the CommandSpec into a IVersionProvider, making it easier to write version provider implementations that are reusable across multiple commands or even applications.

    Similarly, from this release it is possible to inject the parent command object into mixins via a @ParentCommand-annotated field.

    This release adds programmatic API to allow the long options column to grow larger than 20 characters in the usage help message via the CommandLine::setLongOptionsMaxWidth and UsageMessageSpec::longOptionsMaxWidth methods.

    Finally, it is now possible let the usage help show that @-files are supported by listing a @<filename> entry above the list of positional parameters in the usage help.

    This is the sixty-seventh public release. Picocli follows semantic versioning.

    Table of Contents

    New and Noteworthy

    Generate AsciiDoc Documentation for Your Application (convertable to unix man pages, HTML and PDF)

    This release adds a new class picocli.codegen.docgen.manpage.ManPageGenerator to the picocli-codegen module that generates AsciiDoc documentation for picocli-based applications using the manpage doctype and manpage document structure.

    The generated AsciiDoc files can be converted to HTML, PDF and unix man pages with the asciidoctor tool.

    The picocli-codegen README has more details.

    Repeatable Subcommands

    From picocli 4.2, it is possible to specify that a command's subcommands can be specified multiple times by marking it with @Command(subcommandsRepeatable = true).

    Example

    Below is an example where the top-level command myapp is marked as subcommandsRepeatable = true. This command has three subcommands, add, list and send-report:

    @Command(name = "myapp", subcommandsRepeatable = true)
    class MyApp implements Runnable {
    
        @Command
        void add(@Option(names = "-x") String x, @Option(names = "-w") double w) { ... }
    
        @Command
        void list(@Option(names = "--where") String where) { ... }
    
        @Command(name = "send-report")
        void sendReport(@Option(names = "--to", split = ",") String[] recipients) { ... }
    
        // ...
    }
    

    The above example command allows users to specify one or more of its subcommands multiple time. For example, this would be a valid invocation:

    myapp add -x=item1 -w=0.2 \
          add -x=item2 -w=0.5 \
          add -x=item3 -w=0.7 \
          list --where "w>0.2" \
          send-report [email protected]
    

    In the above command line invocation, the myapp top-level command is followed by its subcommand add. Next, this is followed by another two occurences of add, followed by list and send-report. These are all "sibling" commands, that share the same parent command myapp. This invocation is valid because myapp is marked with subcommandsRepeatable = true.

    Repeatable Subcommands Specification

    Normally, subcommandsRepeatable is false, so for each command, only one of its subcommands can be specified, potentially followed by only one sub-subcommand of that subcommand, etc.

    In mathematical terms, a valid sequence of commands and subcommands can be represented by a directed rooted tree that starts at the top-level command. This is illustrated by the diagram below.

    subcommands not repeatable

    When subcommandsRepeatable is set to true on a command, the subcommands of this command may appear multiple times. Also, a subcommand can be followed by a "sibling" command (another command with the same parent command).

    In mathematical terms, when a parent command has this property, the additional valid sequences of its subcommands form a fully connected subgraph (a complete digraph).

    The blue and green dotted arrows in the diagram below illustrate the additional sequences that are allowed when a command has repeatable subcommands.

    subcommands-repeatable

    Note that it is not valid to specify a subcommand followed by its parent command:

    # invalid: cannot move _up_ the hierarchy
    myapp add -x=item1 -w=0.2 myapp
    

    Subcommands are now lazily instantiated

    From this release, subcommands are not instantiated until they are matched on the command line, unless the user object has a @Spec or @ParentObject-annotated field; these are instantiated during initialization.

    Injecting CommandSpec Into a IVersionProvider

    From this release, IVersionProvider implementations can have @Spec-annotated fields. If such a field exists, picocli will inject the CommandSpec of the command that uses this version provider. This gives the version provider access to the full command hierarchy, and may make it easier to implement version providers that can be reused among multiple commands.

    For example:

    class MyVersionProvider implements IVersionProvider {
        @Spec CommandSpec spec;
    
        public String[] getVersion() {
            return new String[] { "Version info for " + spec.qualifiedName() };
        }
    }
    

    Showing @filename in usage help

    From picocli 4.2, an entry for @<filename> can be shown in the options and parameters list of the usage help message of a command with the @Command(showAtFileInUsageHelp = true) annotation.

    Example:

    @Command(name = "myapp", showAtFileInUsageHelp = true,
            mixinStandardHelpOptions = true, description = "Example command.")
    class MyApp {
        @Parameters(description = "A file.") File file;
    }
    

    The usage help message for this command looks like this:

    Usage: myapp [-hV] [@<filename>...] <file>
    Example command.
          [@<filename>...]   One or more argument files containing options.
          <file>             A file.
      -h, --help             Show this help message and exit.
      -V, --version          Print version information and exit.
    

    By default, the @<filename> entry is shown before the positional parameters in the synopsis as well as in the parameters list. This can be changed with the Help API for reordering sections.

    Both the label and the description of the @<filename> entry have been defined with custom variables, to allow applications to change the text. The variables are:

    • picocli.atfile.label
    • picocli.atfile.description

    By setting the above variables in either system properties, environment variables or the resource bundle for a command, the text can be customized.

    See the user manual for examples.

    Mixins with @ParentCommand-annotated fields

    A common use case is sharing options between different levels of the command hierarchy, so that "global" options from the top-level command are also available on subcommands.

    Since picocli 4.2, @ParentCommand-annotated fields can be used in mixins, which makes this easier. See the Use Case: Sharing Options section of the user manual for a full example.

    For mixins that need to be reusable across more than two levels in the command hierarchy, injecting a @Spec-annotated field gives the mixin access to the full command hierarchy.

    Configurable long options column width

    The default layout shows short options and long options in separate columns, followed by the description column. The width of the long options column shrinks automatically if all long options are very short, but by default this column does not grow larger than 20 characters.

    If the long option with its option parameter is longer than 20 characters (for example: --output=<outputFolder>), the long option overflows into the description column, and the option description is shown on the next line.

    This (the default) looks like this:

    Usage: myapp [-hV] [-o=<outputFolder>]
      -h, --help      Show this help message and exit.
      -o, --output=<outputFolder>
                      Output location full path.
      -V, --version   Print version information and exit.
    

    From picocli 4.2, there is programmatic API to change this via the CommandLine::setLongOptionsMaxWidth and UsageMessageSpec::longOptionsMaxWidth methods.

    In the above example, if we call commandLine.setLongOptionsMaxWidth(23) before printing the usage help, we get this result:

    Usage: myapp [-hV] [-o=<outputFolder>]
      -h, --help                    Show this help message and exit.
      -o, --output=<outputFolder>   Output location full path.
      -V, --version                 Print version information and exit.
    

    Fixed issues

    • [#454] API: Added support for repeatable subcommands. Thanks to Idan Arye, Miroslav Kravec, Philipp Hanslovsky and Jay for raising this and the subsequent discussion.
    • [#629] API: Support injecting @Spec CommandSpec spec into IVersionProvider implementations. Thanks to Garret Wilson for raising this.
    • [#795] API: Added @Command(showAtFileInUsageHelp=true) attribute to show @filename in usage help.
    • [#925] API: Support @ParentCommand-annotated fields in mixin classes.
    • [#936] API: Change visibility of Help.subcommands() method from protected to public.
    • [#459] API: Generate manpage documentation. Thanks to Miroslav Kravec for raising this. The picocli-codegen module can now generate AsciiDoc documentation that uses the manpage doctype and adheres to the manpage document structure so it can be converted to unix man pages in troff format with the asciidoctor tool.
    • [#299] API: Generate AsciiDoc documentation. Thanks to Philippe Charles for raising this. Added a new class picocli.codegen.docgen.manpage.ManPageGenerator to the picocli-codegen module that generates AsciiDoc documentation using the manpage doctype and manpage document structure. Custom markup like @|bold mytext|@, @|italic mytext|@ etc., originally intended to be converted to ANSI escape codes, can from this release also be converted to custom markup like <b>mytext</b> and <i>mytext</i> in HTML, or *mytext* and _mytext_ in lightweight markup languages like AsciiDoc. Applications can control this by setting a ColorScheme with a custom markup map. This ticket resulted in the following additional methods: ColorScheme::text, ColorScheme::string, ColorScheme::customMarkupMap, ColorScheme::parse, ColorScheme::resetStyle, ColorScheme::apply, ColorScheme.Builder::customMarkupMap (getter and setter) and a new picocli.CommandLine.Help.Ansi.Text(String, ColorScheme) constructor. The picocli.CommandLine.Help.Ansi::apply method is now deprecated in favor of ColorScheme::apply.
    • [#906] Auto-completion: Added automated tests for picocli-generated bash/zsh completion scripts.
    • [#468][#505][#852] Auto-completion: added support for positional parameter completion. Thanks to Serhii Avsheniuk for the pull request.
    • [#644][#671] Auto-completion: fix shellcheck warnings in generated autocompletion scripts. Thanks to Dylan Cali for raising this, and thanks to AlcaYezz for the pull request.
    • [#396] Auto-completion: completion scripts no longer use associative arrays, and should now work on OSX.
    • [#934] Enhancement: Make long options column width configurable. Thanks to tomerz90 for raising this.
    • [#930] Enhancement: Add --factory option to ReflectionConfigGenerator, ResourceConfigGenerator and DynamicProxyConfigGenerator. Thanks to Santiago Acosta for raising this.
    • [#690] Enhancement: Postpone instantiating subcommands until they are matched on the command line. Thanks to Daniel Breitlauch for raising this.
    • [#942] Enhancement: Show at files in usage help for picocli built-in commands.
    • [#941] Enhancement: Allow default values for predefined variables.
    • [#926] Enhancement: Clarify debug trace output when adding aliases.
    • [#928] Enhancement: Improve debug tracing: show command user object identity hashcode and prefix "Processing argument..." with argument index.
    • [#920] Enhancement: Reduce DEBUG tracing noise if no resource bundle is set.
    • [#946] Enhancement: Add --exit option to picocli codegen utilities.
    • [#940] Bugfix: ArgGroups with a negatable option no longer cause a NullPointerException during initialization.
    • [#938] Bugfix: ArgGroups validation now correctly reports an error when a required option is missing, while an optional subgroup is present. Thanks to Trent Mohay for raising this.
    • [#933] Bugfix: Incorrect error message when multiple exclusive groups are used. Thanks to Mikaël Barbero for raising this.
    • [#905] Bugfix: non-public @Command-annotated methods without arguments caused a IllegalAccessException. From this release such methods no longer need to be public. Thanks to David Connelly for raising this.
    • [#924] Bugfix: CommandSpec.mixinAnnotatedElements map should be initialized when discovering @Mixin-annotated fields and methods via reflection.
    • [#937] Bugfix: Text.getStyledChars no longer incorrectly inserts ANSI escape chars into the next line prefix when lines are broken.
    • [#945] Bugfix: Text.substring now leaves out StyledSection instances that do not apply.
    • [#944] DOC: Fix typo in picocli user manual - remove unnecessary semicolon. Thanks to ztbx for raising this.
    • [#943] DOC: Create man pages for built-in picocli commands.
    • [#929] DOC: Add jbang under packaging in the user manual.
    • [#927] DOC: Show current picocli version in the Spring Boot section of the user manual. Thanks to Christian Grobmeier for the pull request.
    • [#919] DOC: Added example Gradle project with Kotlin and Graal Native Image. Thanks to OndrejMalek for the pull request.
    • [#918] DOC: Added more Scala examples. Thanks to Andreas Deininger for the pull request.
    • [#916] DOC: Added Scala examples. Thanks to Andreas Deininger for the pull request.
    • [#914] DOC: Added Java and Kotlin examples for using ResourceBundle to internationalize and localize your CLI app. Thanks to Andreas Deininger for the pull request.
    • [#915] DOC: Ensure Kotlin examples compile correctly. Thanks to Andreas Deininger for the suggestion.
    • [#913] DOC: Added more Java and Kotlin examples. Thanks to Andreas Deininger for the pull request.
    • [#912] DOC: Fixed broken links in javadoc. Thanks to Andreas Deininger for the pull request.
    • [#911] DOC: Fixed syntax error in javadoc. Thanks to Andreas Deininger for the pull request.
    • [#909] DOC: User manual: minor fixes. Thanks to Andreas Deininger for the pull request.
    • [#908] DOC: Fix typo in user manual: Add missing closing curly bracket. Thanks to Piotrek Żygieło for the pull request.
    • [#907] DOC: Updated and added Kotlin examples. Thanks to Andreas Deininger for the pull request.
    • [#910] Dependency Upgrade: Bump Spring Boot dependency to 2.2.2 to allow it to work under Java 13. Thanks to Stéphane Vanacker for raising this.

    Deprecations

    • The picocli.CommandLine.Help.Ansi#apply method has been deprecated in favor of the picocli.CommandLine.Help.ColorScheme#apply method.
    • The picocli.CommandLine.Help.TextTable forDefaultColumns(Ansi, int, int) method has been deprecated in favor of the new TextTable.forDefaultColumns(ColorScheme, int, int) method.
    • The picocli.CommandLine.Help.TextTable forColumnWidths(Ansi, int...) method has been deprecated in favor of the new TextTable.forColumnWidths(ColorScheme, int...) method.
    • The picocli.CommandLine.Help.TextTable forColumns(Ansi, Column...) method has been deprecated in favor of the new TextTable.forColumns(ColorScheme, Column...) method.
    • The picocli.CommandLine.Help.TextTable constructor (Ansi, Column[]) has been deprecated in favor of the new TextTable(ColorScheme, Column...) constructor.

    Potential breaking changes

    Annotated command objects are now not instantiated until the command is matched on the command line. Previously all subcommands were instantiated when the top-level command's CommandLine was constructed.

    Source code(tar.gz)
    Source code(zip)
    picocli-4.2.0.jar(355.48 KB)
    picocli-all-4.2.0.zip(3.89 MB)
    picocli-codegen-4.2.0.jar(121.71 KB)
    picocli-groovy-4.2.0.jar(7.16 KB)
    picocli-shell-jline2-4.2.0.jar(1.67 KB)
    picocli-shell-jline3-4.2.0.jar(5.64 KB)
    picocli-spring-boot-starter-4.2.0.jar(2.82 KB)
  • v4.1.4(Dec 21, 2019)

    Picocli 4.1.4

    The picocli community is pleased to announce picocli 4.1.4.

    This release contains a bugfix for GraalVM users, and minor documentation enhancements.

    This release fixes a bug in the picocli-codegen annotation processor that generates an incorrect reflect-config.json file with invalid entries for inner classes of commands in the unnamed package, that are unnecessarily prefixed with a dot. This makes the GraalVM native-image generator fail with an error like "Class .Outer$Inner not found".

    This is the sixty-sixth public release. Picocli follows semantic versioning.

    Table of Contents

    New and Noteworthy

    Fixed issues

    • [#903] Bugfix: picocli-codegen generates invalid reflect-config.json for classes in unnamed package.
    • [#902] DOC: replace deprecated CommandLine.invoke() function. Thanks to Andreas Deininger for the pull request.

    Deprecations

    No features were deprecated in this release.

    Potential breaking changes

    This release has no breaking changes.

    Source code(tar.gz)
    Source code(zip)
    picocli-4.1.4.jar(343.31 KB)
    picocli-all-4.1.4.zip(3.67 MB)
    picocli-codegen-4.1.4.jar(100.26 KB)
    picocli-groovy-4.1.4.jar(7.16 KB)
    picocli-shell-jline2-4.1.4.jar(1.67 KB)
    picocli-shell-jline3-4.1.4.jar(5.64 KB)
    picocli-spring-boot-starter-4.1.4.jar(2.82 KB)
  • v4.1.3(Dec 21, 2019)

    Picocli 4.1.3

    The picocli community is pleased to announce picocli 4.1.3.

    This release contains a bugfix for GraalVM users.

    This release fixes a bug in the picocli-codegen annotation processor that generates an incorrect reflect-config.json file with duplicate entries for inner classes of a command, one with the standard class name and one with the canonical class name. This makes the GraalVM native-image generator fail with an error like "Class Outer.Inner not found".

    This is the sixty-fifth public release. Picocli follows semantic versioning.

    Table of Contents

    New and Noteworthy

    Fixed issues

    • [#901] Bugfix: picocli-codegen generated invalid reflect-config.json for inner classes.

    Deprecations

    No features were deprecated in this release.

    Potential breaking changes

    This release has no breaking changes.

    Source code(tar.gz)
    Source code(zip)
    picocli-4.1.3.jar(343.31 KB)
    picocli-all-4.1.3.zip(3.67 MB)
    picocli-codegen-4.1.3.jar(100.24 KB)
    picocli-groovy-4.1.3.jar(7.16 KB)
    picocli-shell-jline2-4.1.3.jar(1.67 KB)
    picocli-shell-jline3-4.1.3.jar(5.64 KB)
    picocli-spring-boot-starter-4.1.3.jar(2.82 KB)
  • v4.1.2(Dec 8, 2019)

    Picocli 4.1.2

    The picocli community is pleased to announce picocli 4.1.2.

    This release contains bugfixes, improvements, and documentation enhancements.

    This version of picocli requires JLine 3.13.2 or higher and adds a PicocliCommands class that provides command descriptions that can be displayed in the terminal status bar via the new JLine TailTipWidgets functionality.

    The built-in picocli.AutoComplete.GenerateCompletion (generate-completion) subcommand now omits validation of mandatory options in the parent command.

    "Hidden" subcommands and options are no longer shown as suggestions in unmatched argument usage help or autocompletion scripts.

    From picocli 4.1.2, all options in an exclusive group are automatically considered required, even if they are not marked as required = true in the annotations. Applications using older versions of picocli should mark all options in exclusive groups as required.

    This is the sixty-fourth public release. Picocli follows semantic versioning.

    Thanks to the Community

    Special thanks to mattirn and to Andreas Deininger for the pull requests and feedback!

    Table of Contents

    New and Noteworthy

    JLine3

    JLine has had some interesting improvements in its 3.12 release.

    This version of picocli requires JLine 3.13.2 or higher and adds a PicocliCommands class that provides command descriptions that can be displayed in the terminal status bar via the new JLine TailTipWidgets functionality.

    See the picocli-shell-jline3 README for details.

    Completion

    The built-in picocli.AutoComplete.GenerateCompletion (generate-completion) subcommand now omits validation of mandatory options in the parent command.

    Also, "hidden" subcommands and options are no longer shown as suggestions in unmatched argument usage help or autocompletion scripts.

    Fixed issues

    • [#888] (API) Added new PicocliCommands class to picocli-shell-jline3 module; bumped JLine to 3.13.2. Thanks to mattirn for the pull request.
    • [#884] (Bugfix) Built-in picocli.AutoComplete.GenerateCompletion (generate-completion) subcommand now omits validation of mandatory options in the parent command. Thanks to Andreas Deininger for raising this.
    • [#887] (Bugfix) "Hidden" subcommands and options are no longer shown as suggestions in unmatched argument usage help or autocompletion scripts. Thanks to Andreas Deininger for raising this.
    • [#871] (Bugfix) All options in an exclusive group are now automatically considered required, to prevent unexpected results when mixing required and non-required options in exclusive ArgGroups. Thanks to W Scott Johnson for raising this.
    • [#883] (DOC) Update of Quick Guide. Thanks to Andreas Deininger for the pull request.
    • [#889][#885] (DOC) Update of Picocli Programmatic API documentation. Thanks to Andreas Deininger for the pull request.
    • [#891] (DOC) Fixed broken links in README. Thanks to Andreas Deininger for the pull request.
    • [#892] (DOC) Minor improvements to example app in picocli-shell-jline3.

    Deprecations

    No features were deprecated in this release.

    Potential breaking changes

    This release has no breaking changes.

    Source code(tar.gz)
    Source code(zip)
    picocli-4.1.2.jar(343.31 KB)
    picocli-all-4.1.2.zip(3.64 MB)
    picocli-codegen-4.1.2.jar(98.76 KB)
    picocli-groovy-4.1.2.jar(7.16 KB)
    picocli-shell-jline2-4.1.2.jar(1.67 KB)
    picocli-shell-jline3-4.1.2.jar(5.64 KB)
    picocli-spring-boot-starter-4.1.2.jar(2.82 KB)
  • v4.1.1(Nov 26, 2019)

    Picocli 4.1.1

    The picocli community is pleased to announce picocli 4.1.1.

    This release contains bugfixes, and documentation enhancements.

    The new picocli.AutoComplete.GenerateCompletion reusable subcommand did not flush the generated script to the System.out stream, making it unusable. This has been fixed.

    This is the sixty-third public release. Picocli follows semantic versioning.

    Thanks to the Community

    Special thanks to Andreas Deininger for the many pull requests and feedback!

    Table of Contents

    New and Noteworthy

    Fixed issues

    • [#880] (Bugfix) Built-in picocli.AutoComplete.GenerateCompletion (generate-completion) subcommand does not flush, resulting in no output. Thanks to Andreas Deininger for raising this.
    • [#875] (DOC) Fix broken internal links in RELEASE-NOTES for 4.1. Thanks to Andreas Deininger for raising this.
    • [#881] (DOC) Update of Quick Guide to the latest execute API. Thanks to Andreas Deininger for the pull request.
    • [#874] (DOC) Fix Javadoc issues. Thanks to Andreas Deininger for the pull request.

    Deprecations

    No features were deprecated in this release.

    Potential breaking changes

    This release has no breaking changes.

    Source code(tar.gz)
    Source code(zip)
    picocli-4.1.1.jar(342.61 KB)
    picocli-all-4.1.1.zip(3.63 MB)
    picocli-codegen-4.1.1.jar(98.76 KB)
    picocli-groovy-4.1.1.jar(7.16 KB)
    picocli-shell-jline2-4.1.1.jar(1.67 KB)
    picocli-shell-jline3-4.1.1.jar(1.85 KB)
    picocli-spring-boot-starter-4.1.1.jar(2.82 KB)
  • v4.1.0(Nov 22, 2019)

    Picocli 4.1.0

    The picocli community is pleased to announce picocli 4.1.0.

    This release contains bugfixes, and enhancements.

    The library now provides functionality that previously required custom code:

    PropertiesDefaultProvider - this release includes a built-in default provider allows end users to maintain their own default values for options and positional parameters, which may override the defaults that are hard-coded in the application.

    AutoComplete.GenerateCompletion - this release includes a built-in generate-completion subcommand that end users can use to easily install Bash/ZSH completion for your application.

    Help API improvements make it even easier to add custom sections to the usage help message.

    This release also includes various bug fixes for ArgGroups, which were first introduced in picocli 4.0, and are still maturing.

    This is the sixty-second public release. Picocli follows semantic versioning.

    Table of Contents

    New and Noteworthy

    PropertiesDefaultProvider

    From picocli 4.1, applications can use the built-in PropertiesDefaultProvider implementation that loads default values from a properties file.

    By default, this implementation tries to find a properties file named .${COMMAND-NAME}.properties in the user home directory, where ${COMMAND-NAME} is the name of the command. If a command has aliases in addition to its name, these aliases are also used to try to find the properties file. For example:

    import picocli.CommandLine.PropertiesDefaultProvider;
    // ...
    @Command(name = "git", defaultValueProvider = PropertiesDefaultProvider.class)
    class Git { }
    

    The above will try to load default values from new File(System.getProperty("user.home"), ".git.properties"). The location of the properties file can also be controlled with system property "picocli.defaults.${COMMAND-NAME}.path" ("picocli.defaults.git.path" in this example), in which case the value of the property must be the path to the file containing the default values.

    The location of the properties file may also be specified programmatically. For example:

    CommandLine cmd = new CommandLine(new MyCommand());
    File defaultsFile = new File("path/to/config/mycommand.properties");
    cmd.setDefaultValueProvider(new PropertiesDefaultProvider(defaultsFile));
    cmd.execute(args);
    

    PropertiesDefaultProvider Format

    The PropertiesDefaultProvider expects the properties file to be in the standard java .properties https://en.wikipedia.org/wiki/.properties[format].

    For options, the key is either the descriptionKey, or the option's longest name, without the prefix. So, for an option --verbose, the key would be verbose, and for an option /F, the key would be F.

    For positional parameters, the key is either the descriptionKey, or the positional parameter's param label.

    End users may not know what the descriptionKey of your options and positional parameters are, so be sure to document that with your application.

    Subcommands Default Values

    The default values for options and positional parameters of subcommands can be included in the properties file for the top-level command, so that end users need to maintain only a single file. This can be achieved by prefixing the keys for the options and positional parameters with their command's qualified name. For example, to give the git commit command's --cleanup option a default value of strip, define a key of git.commit.cleanup and assign it a default value:

    # /home/remko/.git.properties
    git.commit.cleanup = strip
    

    AutoComplete.GenerateCompletion

    This release adds a built-in generate-completion subcommand that generates a completion script for its parent command.

    Example usage:

    @Command(name = "myapp",
            subcommands = picocli.AutoComplete.GenerateCompletion.class)
    static class MyApp { //...
    }
    

    This allows users to install completion for the myapp command by running the following command:

    source <(myapp generate-completion)
    

    Autocompletion script improvements

    The generated completion script itself now enables bash completion in zsh.

    That means it is no longer necessary to run the below commands in ZSH before sourcing the completion script:

    autoload -U +X compinit && compinit
    autoload -U +X bashcompinit && bashcompinit
    

    Help API improvements

    The new Help.createHeading(String, Object...) and Help.createTextTable(Map<?, ?>) methods facilitate creating tabular custom Help sections.

    The below example shows how to add a custom Environment Variables section to the usage help message.

    // help section keys
    static final String SECTION_KEY_ENV_HEADING = "environmentVariablesHeading";
    static final String SECTION_KEY_ENV_DETAILS = "environmentVariables";
    // ...
    
    // the data to display
    Map<String, String> env = new LinkedHashMap<>();
    env.put("FOO", "explanation of foo");
    env.put("BAR", "explanation of bar");
    env.put("XYZ", "xxxx yyyy zzz");
    
    // register the custom section renderers
    CommandLine cmd = new CommandLine(new MyApp());
    cmd.getHelpSectionMap().put(SECTION_KEY_ENV_HEADING,
                                help -> help.createHeading("Environment Variables:%n"));
    cmd.getHelpSectionMap().put(SECTION_KEY_ENV_DETAILS,
                                help -> help.createTextTable(env).toString());
    
    // specify the location of the new sections
    List<String> keys = new ArrayList<>(cmd.getHelpSectionKeys());
    int index = keys.indexOf(CommandLine.Model.UsageMessageSpec.SECTION_KEY_FOOTER_HEADING);
    keys.add(index, SECTION_KEY_ENV_HEADING);
    keys.add(index + 1, SECTION_KEY_ENV_DETAILS);
    cmd.setHelpSectionKeys(keys);
    

    There are also new convenience methods Help.fullSynopsis() and CommandLine.getHelp().

    ArgGroup improvements

    • ArgGroups with @Option-annotated methods no longer fail with NullPointerException
    • ArgGroups now match multiple occurrences of a multi-value @Option in the same group instance, and don't create a new group for each occurrence
    • ArgGroups now don't validate when marked as validate = false
    • ArgGroups now correctly validate that required options are present
    • Non-validating ArgGroups are now automatically set to be non-exclusive

    Fixed issues

    • [#841] (API) Add JniConfigGenerator to picocli-codegen module.
    • [#865] (API) Add Help.createHeading(String, Object...) and Help.createTextTable(Map<?, ?>) to facilitate creating tabular custom Help sections.
    • [#829] (Bugfix) @ArgGroup with @Option-annotated methods fail with NullPointerException. Thanks to A2 Geek for raising this.
    • [#828] (Bugfix/enhancement) Subcommands should not be parsed as option values for options with optional parameters. Thanks to Martin Paljak for raising this.
    • [#811] (Bugfix) CommandLine.setResourceBundle did not propagate resource bundle to subcommands recursively. Thanks to thope for the pull request with the bug fix.
    • [#850] (Bugfix) @Mixin-annotated fields were not included in reflect-config.json by picocli-codegen annotation processor. Thanks to Nikolaos Georgiou for raising this.
    • [#826] (Enhancement) Suppress compiler warning "Supported source version 'RELEASE_6' from annotation processor... less than -source..." in picocli-codegen.
    • [#815] (Enhancement) @ArgGroup should match multiple occurrences of a multi-value @Option in the same group instance, not create new group for each occurrence. Thanks to kacchi for raising this.
    • [#810] (Bugfix) @ArgGroup should not validate when marked as validate = false. Thanks to Andreas Deininger for raising this.
    • [#870] (Bugfix) Required options were not validated when mixing required and non-required options in an ArgGroup. Thanks to W Scott Johnson for raising this.
    • [#868] (Enhancement) Add built-in default value provider implementation PropertiesDefaultProvider that loads default values from properties file in home directory or specified location.
    • [#809] (Enhancement) Add built-in generate-completion subcommand that generates a completion script for its parent command. Thanks to George Gastaldi for the suggestion.
    • [#836] (Enhancement) Add convenience methods Help.fullSynopsis() and CommandLine.getHelp().
    • [#833] (Enhancement) Non-validating ArgGroups are now automatically set to be non-exclusive. Thanks to Andreas Deininger for raising this.
    • [#830] (Enhancement) Enum constants can now be matched by their toString() as well as their name(). Improved error reporting. Thanks to Henning Makholm for the pull request.
    • [#846] (Enhancement) Allow value tty for system property picocli.ansi: force picocli to emit ANSI escape characters if the process is using an interactive console.
    • [#772] (Enhancement) Generated completion script should enable bash completion in zsh. Thanks to Bob Tiernay for raising this.
    • [#480] (DOC) Added a Handling Errors subsection to the Executing Commands section of the user manual to show how to customize how your application deals with invalid input or business logic exceptions.
    • [#813] (DOC) Clarify usage of negatable boolean @Option with default value "true". Thanks to Yann ROBERT for raising this.
    • [#814] (DOC) Document how a CLI application can be packaged for distribution.
    • [#820] (DOC) Update user manual section on ANSI supported platforms: mention Windows Subsystem for Linux under Windows 10.
    • [#819] (DOC) Update user manual section on Variable Interpolation: improve example, link to this section from other parts of the manual.
    • [#818] (DOC) Update user manual section on Usage Help API to point to picocli-examples.
    • [#816] (DOC) Update user manual for IHelpCommandInitializable2.
    • [#817] (DOC) Update user manual section on Subcommands for the execute API.
    • [#809] (DOC) Output completion script as a subcommand of the command itself. Thanks to George Gastaldi for the suggestion.
    • [#456] (DOC) Integrate completion generation into command itself. Thanks to jvassev for the suggestion.
    • [#835] (DOC) Document how to create ANSI colored output in an application.
    • [#847] (DOC) Improve documentation for ANSI colors in Windows.
    • [#844] (DOC) Clarify when @ArgGroup-annotated fields are initialized in user manual.
    • [#860] (DOC) Fix broken link to GraalVM Native Image section. Thanks to Andreas Deininger for the pull request.
    • [#861] (DOC) Fix broken link to ShowCommandHierarchy example. Thanks to Andreas Deininger for the pull request.
    • [#864] (DOC) Fix code examples in documentation. Thanks to Andreas Deininger for the pull request.
    • [#867] (DOC) Update user manual to clarify that the toggling behaviour is no longer the default from picocli 4.0. Thanks to Linus Fernandes for raising this.

    Deprecations

    No features were deprecated in this release.

    Potential breaking changes

    • From picocli 4.1, subcommands will not be parsed as option values for options with optional parameters.
    • Enum constants can now be matched by their toString() as well as their name().
    Source code(tar.gz)
    Source code(zip)
    picocli-4.1.0.jar(342.59 KB)
    picocli-4.1.0.zip(3.63 MB)
    picocli-codegen-4.1.0.jar(98.76 KB)
    picocli-groovy-4.1.0.jar(7.16 KB)
    picocli-shell-jline2-4.1.0.jar(1.67 KB)
    picocli-shell-jline3-4.1.0.jar(1.85 KB)
    picocli-spring-boot-starter-4.1.0.jar(2.82 KB)
  • v4.0.4(Sep 8, 2019)

    Picocli 4.0.4

    The picocli community is pleased to announce picocli 4.0.4.

    This release contains a bugfixes and enhancements.

    GraalVM native image-configuration generation for options or positional parameters with custom type converters or custom parameter consumers now work correctly.

    Also fixed a bug where validation was performed on ArgGroups even when they were marked as validate = false.

    This is the sixty-first public release. Picocli follows semantic versioning.

    Table of Contents

    New and Noteworthy

    Fixed issues

    • [#803] (Bugfix) Custom IParameterConsumer caused native-image to fail. Thanks to Patrick Plenefisch for raising this.
    • [#804][#806] (Bugfix) Visit Parameter Consumers when doing GraalVM reflection generation; added test. Thanks to Patrick Plenefisch for the pull requests.
    • [#808] (Bugfix) Option-specific ITypeConverter class is now correctly included in generated reflect-config.json.
    • [#807] (Bugfix) ArgGroup should not validate when marked as validate = false. Thanks to cranphin for the bug report.
    • [#799] (DOC) Update adoption section in README.
    • [#805] (DOC) Add example for alphabetically sorting subcommands by subclassing Help. Thanks to frontfact for raising this issue.

    Deprecations

    No features were deprecated in this release.

    Potential breaking changes

    This release has no breaking changes.

    Source code(tar.gz)
    Source code(zip)
    picocli-4.0.4.jar(337.51 KB)
    picocli-all-4.0.4.zip(3.53 MB)
    picocli-codegen-4.0.4.jar(92.95 KB)
    picocli-groovy-4.0.4.jar(7.16 KB)
    picocli-shell-jline2-4.0.4.jar(1.67 KB)
    picocli-shell-jline3-4.0.4.jar(1.85 KB)
    picocli-spring-boot-starter-4.0.4.jar(2.82 KB)
  • v4.0.3(Aug 26, 2019)

    Picocli 4.0.3

    The picocli community is pleased to announce picocli 4.0.3.

    This release contains a bugfixes and enhancements.

    GraalVM native image-configuration generation for picocli commands with argument groups now work correctly.

    This is the sixtieth public release. Picocli follows semantic versioning.

    Table of Contents

    New and Noteworthy

    Fixed issues

    • [#794] (Bugfix) Perform topological sort on ArgGroups in annotation processor before wiring up the model to prevent FATAL ERROR in annotation processor: picocli.CommandLine$InitializationException: ArgGroup has no options or positional parameters, and no subgroups.
    • [#793] (Bugfix) Argument groups disappear in GraalVM native-image (the generated reflect-config.json was missing the @ArgGroup-annotated fields). Thanks to Mike Hearn for the bug report.
    • [#787] (Enhancement) Throw InitializationException instead of StackOverflowError when subcommand is subclass of itself. Thanks to Peter Murray-Rust for raising this.
    • [#784] (DOC) Update documentation to show custom IFactory implementations should fall back to the default factory to enable the creation of collections for @Option-annotated methods and fields.
    • [#788] (DOC) Add link to GitHub examples in user manual Mixins section. Thanks to Peter Murray-Rust for the suggestion.
    • [#789] (DOC) Add example usage help to the user manual Negatable Options section.

    Deprecations

    No features were deprecated in this release.

    Potential breaking changes

    This release has no breaking changes.

    Source code(tar.gz)
    Source code(zip)
    picocli-4.0.3.jar(337.49 KB)
    picocli-all-4.0.3.zip(3.51 MB)
    picocli-codegen-4.0.3.jar(90.73 KB)
    picocli-groovy-4.0.3.jar(7.16 KB)
    picocli-shell-jline2-4.0.3.jar(1.67 KB)
    picocli-shell-jline3-4.0.3.jar(1.85 KB)
    picocli-spring-boot-starter-4.0.3.jar(2.82 KB)
  • v4.0.2(Aug 12, 2019)

    Picocli 4.0.2

    The picocli community is pleased to announce picocli 4.0.2.

    This release contains a bugfixes and enhancements.

    This is the fifty-nineth public release. Picocli follows semantic versioning.

    Table of Contents

    New and Noteworthy

    Fixed issues

    • [#781] Bugfix: Standard help mixin options not added in source order when running on Java 12+.
    • [#773] Bugfix: Add public NativeImageConfigGeneratorProcessor constructor to fix build error in IntelliJ IDEA 2019.2. Thanks to Lukáš Petrovický for raising this issue.
    • [#779] Bugfix: DuplicateOptionAnnotationsException when a nested group is defined inside a mixin. Thanks to Matteo Melli for the bug report.
    • [#777] Bugfix: Codegen failed when command contains field with argGroup annotation. Thanks to eomeara for the bug report.
    • [#776] Bugfix: Argument groups in mixins were ignored. Thanks to Matteo Melli for the bug report.
    • [#780] (DOC) Fixed the provided flag usage in the picocli-codegen readme. Thanks to Lasantha Kularatne for the pull request.
    • [#778] (DOC) Improve documentation for argument group sections in the help. Thanks to Matteo Melli for raising this.
    • [#774] (DOC) Add example demonstrating how to left-align long options in the usage help.
    • [#766] (DOC) Update user manual: mention the dependency required for using PicocliSpringFactory. Thanks to rome-legacy for the suggestion.
    • [#775] (DOC) Document jline2 incompatibility with picocli's interactive options for passwords, and update the example to show a workaround. Thanks to querqueq for the pull request.
    • [#770][#771] (DOC) Improve example code in picocli-spring-boot-starter README. Thanks to Stéphane Nicoll for the pull requests.

    Deprecations

    No features were deprecated in this release.

    Potential breaking changes

    This release has no breaking changes.

    Source code(tar.gz)
    Source code(zip)
    picocli-4.0.2.jar(337.28 KB)
    picocli-all-4.0.2.zip(3.50 MB)
    picocli-codegen-4.0.2.jar(87.91 KB)
    picocli-groovy-4.0.2.jar(7.16 KB)
    picocli-shell-jline2-4.0.2.jar(1.67 KB)
    picocli-shell-jline3-4.0.2.jar(1.85 KB)
    picocli-spring-boot-starter-4.0.2.jar(2.82 KB)
  • v4.0.1(Jul 19, 2019)

    Picocli 4.0.1

    The picocli community is pleased to announce picocli 4.0.1.

    This release contains a fix for a bug in the annotation processor that caused a compilation error when a subcommand contains a @Mixin-annotated field or method.

    This is the fifty-eighth public release. Picocli follows semantic versioning.

    Table of Contents

    New and Noteworthy

    Fixed issues

    • [#769] Annotation processor fails on subcommands with mixins. Thanks to MortronMeymo for the bug report.

    Deprecations

    No features were deprecated in this release.

    Potential breaking changes

    This release has no breaking changes.

    Source code(tar.gz)
    Source code(zip)
    picocli-4.0.1.jar(336.95 KB)
    picocli-all-4.0.1.zip(3.47 MB)
    picocli-codegen-4.0.1.jar(87.08 KB)
    picocli-groovy-4.0.1.jar(7.16 KB)
    picocli-shell-jline2-4.0.1.jar(1.67 KB)
    picocli-shell-jline3-4.0.1.jar(1.85 KB)
    picocli-spring-boot-starter-4.0.1.jar(2.82 KB)
  • v4.0.0(Jul 17, 2019)

    Picocli 4.0.0 GA

    The picocli community is pleased to announce picocli 4.0. This is a big release.

    First, the picocli-codegen module now includes an annotation processor that instantly enables your JAR for GraalVM native images. It also gives compile-time errors for invalid annotations and attributes. We recommend that all projects using picocli enable this annotation processor.

    The execute API is an easy way to execute your command with almost no code. It allows for more flexible configuration than previous APIs, and introduces much improved exit code support. This replaces the static methods call and run, as well as the parseWithHandlers methods, which are now deprecated.

    Improved Spring support: the new picocli-spring-boot-starter module includes a PicocliSpringFactory and auto-configuration to use Spring dependency injection in your picocli command line application. This is especially useful if your application contains subcommands.

    The parser has been enhanced to handle argument groups: mutually exclusive options, mutually dependent options, and option sections in the usage help. What makes the picocli design unique and extremely powerful is that argument groups can be nested, so applications can define repeating composite groups of mutually exclusive or co-dependent options.

    Annotation attributes can now contain variables that can be resolved as system properties, environment variables and resource bundle keys.

    The picocli JAR is now an explicit JPMS module, as well as an OSGi bundle. As part of this change, the Groovy support classes and annotations have been moved to a separate picocli-groovy artifact.

    Boolean options can now easily be made negatable, which adds a "no-" version of the option. This is a common feature in command line parser libraries for Perl, PHP, Ruby, Lisp, Dart and Go, but we are not aware of any other Java libraries that support this.

    All in all, this release contains 96 bugfixes and improvements over picocli 3.9.6.

    Many thanks to the following community contributors to this release of picocli:

    AkosCz, AlcaYezz, Andreas Deininger, andrewbleonard, Arturo Alonso, Bob Tiernay, Devin Smith, feinstein, Garret Wilson, Gerard Bosch, gitfineon, jrevault, Judd Gaddie, Liam Esteban Prince, marinier, Michael D. Adams, Mikaël Barbero, Mikusch, Nicolas Mingo, Paolo Di Tommaso, Philipp Hanslovsky, Radu Cotescu, Reinhard Pointner, Sebastian Thomschke, Shane Rowatt, shanetreacy, Steffen Rehberg, Sualeh Fatehi, Takuya Ishibashi, Thibaud Lepretre and Warkdev.

    This is the fifty-seventh public release. Picocli follows semantic versioning.

    Table of Contents

    New and Noteworthy

    Annotation processor

    GraalVM

    The picocli-codegen module now includes an annotation processor that instantly enables your JAR for GraalVM native images. The annotation processor can build a model from the picocli annotations at compile time rather than at runtime.

    Use this if you’re interested in:

    • Compile time error checking. The annotation processor shows errors for invalid annotations and attributes immediately when you compile, instead of during testing at runtime, resulting in shorter feedback cycles.
    • Graal native images. The annotation processor generates and updates Graal configuration files under META-INF/native-image/picocli-generated/$project during compilation, to be included in the application jar. This includes configuration files for reflection, resources and dynamic proxies. By embedding these configuration files, your jar is instantly Graal-enabled. The $project location is configurable, see processor options below. In most cases no further configuration is needed when generating a native image.

    Processor option: project

    The picocli annotation processor supports a number of options, most important of which is the project option to control the output subdirectory: the generated files are written to META-INF/native-image/picocli-generated/${project}. A good convention is to use the Maven ${groupId}/${artifactId} as the value; a unique subdirectory ensures your jar can be shaded with other jars that may also contain generated configuration files.

    To configure this option, pass the -Aproject=<some value> to the javac compiler. The examples below show how to do this for Maven and Gradle.

    Enabling the Annotation Processor

    Since Java 6, annotation processing is part of the standard javac compiler, but many IDEs and build tools require something extra to enable annotation processing.

    IDE

    This page shows the steps to configure Eclipse and IntelliJ IDEA to enable annotation processing.

    Maven

    In Maven, use annotationProcessorPaths in the configuration of the maven-compiler-plugin. This requires maven-compiler-plugin plugin version 3.5 or higher.

    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-compiler-plugin</artifactId>
      <!-- annotationProcessorPaths requires maven-compiler-plugin version 3.5 or higher -->
      <version>${maven-compiler-plugin-version}</version>
      <configuration>
        <annotationProcessorPaths>
          <path>
            <groupId>info.picocli</groupId>
            <artifactId>picocli-codegen</artifactId>
            <version>4.0.0</version>
          </path>
        </annotationProcessorPaths>
        <compilerArgs>
          <arg>-Aproject=${groupId}/${artifactId}</arg>
        </compilerArgs>
      </configuration>
    </plugin>
    

    See the picocli-codegen README for more details.

    Gradle

    Use the annotationProcessor path in Gradle 4.6 and higher:

    dependencies {
        compile 'info.picocli:picocli:4.0.0'
        annotationProcessor 'info.picocli:picocli-codegen:4.0.0'
    }
    

    To set an annotation processor option in Gradle, add these options to the options.compilerArgs list in the compileJava block.

    compileJava {
        options.compilerArgs += ["-Aproject=${project.group}/${project.name}"]
    }
    

    See the picocli-codegen README for more details.

    Execution API

    executable commands

    Picocli 4.0 introduces new API to execute commands. Let’s take a quick look at what changed.

    Exit Code

    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 introduced in picocli 4.0 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.

    Generating an Exit Code

    @Command-annotated classes that implement Callable and @Command-annotated methods can simply return an int or Integer, and this value 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;
      }
    }
    
    assert 1 == new CommandLine(new Greet()).execute();
    assert 2 == new CommandLine(new Greet()).execute("shout");
    

    Commands with a user object that implements Runnable can implement the IExitCodeGenerator interface to generate an exit code. For example:

    @Command(name = "wave")
    class Gesture implements Runnable, IExitCodeGenerator {
      public void run() {
        System.out.println("wave");
      }
      public int getExitCode() {
        return 3;
      }
    }
    
    assert 3 == new CommandLine(new Gesture()).execute();
    

    Exception Exit Codes

    By default, the execute method returns CommandLine.ExitCode.USAGE (64) for invalid input, and CommandLine.ExitCode.SOFTWARE (70) when an exception occurred in the Runnable, Callable or command method. (For reference, these values are EX_USAGE and EX_SOFTWARE, respectively, from Unix and Linux sysexits.h). This can be customized with the @Command annotation. For example:

    @Command(exitCodeOnInvalidInput = 123,
       exitCodeOnExecutionException = 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 instanceof FileNotFoundException) {
          return 74;
        }
        return 1;
      }
    }
    

    When the end user specified invalid input, the execute method prints an error message followed by the usage help message of the command, and returns an exit code. This can be customized by configuring a IParameterExceptionHandler.

    If the business logic of the command throws an exception, the execute method prints the stack trace of the exception and returns an exit code. This can be customized by configuring a IExecutionExceptionHandler.

    Configuration

    The new CommandLine.execute method is an instance method. 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.setUnmatchedArgumentsAllowed(true);
      cmd.setStopAtPositional(true);
      cmd.setExpandAtFiles(false);
      cmd.execute(args);
    }
    

    Spring support

    spring and spring boot logos

    Thibaud Lepretre, the author of kakawait/picocli-spring-boot-starter has graciously contributed a pull request to the picocli project with a new picocli-spring-boot-starter module. This includes a PicocliSpringFactory and auto-configuration and makes it extremely easy to use Spring dependency injection in your picocli command line application.

    Spring Boot example

    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.CommandLineRunner;
    import org.springframework.boot.ExitCodeGenerator;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.boot.SpringApplication;
    import org.springframework.context.annotation.Bean;
    import picocli.CommandLine;
    import picocli.CommandLine.IFactory;
    
    @SpringBootApplication
    public class MySpringApp implements CommandLineRunner, ExitCodeGenerator {
        private int exitCode;
    
        @Autowired
        IFactory factory; // auto-configured to inject PicocliSpringFactory
    
        @Autowired
        MyCommand myCommand; // your @picocli.CommandLine.Command-annotated class
    
        @Override
        public void run(String... args) {
            // let picocli parse command line args and run the business logic
            exitCode = new CommandLine(myCommand, factory).execute(args);
        }
    
        @Override
        public int getExitCode() {
            return exitCode;
        }
    
        public static void main(String[] args) {
            // let Spring instantiate and inject dependencies
            System.exit(SpringApplication.exit(SpringApplication.run(MySpringApp.class, args)));
        }
    }
    

    When your command is annotated with @Component, Spring can autodetect it for dependency injection. The business logic of your command looks like any other picocli command with options and parameters.

    import org.springframework.stereotype.Component;
    import org.springframework.beans.factory.annotation.Autowired;
    import picocli.CommandLine.Command;
    import picocli.CommandLine.Option;
    import java.util.concurrent.Callable;
    
    @Component
    @Command(name = "myCommand")
    public class MyCommand implements Callable<Integer> {
    
        @Autowired
        private SomeService someService;
    
        // Prevent "Unknown option" error when users use
        // the Spring Boot parameter 'spring.config.location' to specify
        // an alternative location for the application.properties file.
        @Option(names = "--spring.config.location", hidden = true)
        private String springConfigLocation;
    
        @Option(names = { "-x", "--option" }, description = "example option")
        private boolean flag;
    
        public Integer call() throws Exception {
            // business logic here
            return 0;
        }
    }
    

    Argument groups

    argument groups

    This release introduces a new @ArgGroup annotation and its ArgGroupSpec programmatic equivalent.

    Argument Groups can be used to define:

    • mutually exclusive options
    • options that must co-occur (dependent options)
    • option sections in the usage help message
    • repeating composite arguments

    To create a group using the annotations API, annotate a field or method with @ArgGroup. The field's type refers to the class containing the options and positional parameters in the group. (For annotated interface methods this would be the return type, for annotated setter methods in a concrete class this would be the setter's parameter type.)

    Picocli will instantiate this class as necessary to capture command line argument values in the @Option and @Parameters-annotated fields and methods of this class.

    Mutually Exclusive Options

    Annotate a field or method with @ArgGroup(exclusive = true) to create a group of mutually exclusive options and positional parameters. For example:

    @Command(name = "exclusivedemo")
    public class MutuallyExclusiveOptionsDemo {
    
        @ArgGroup(exclusive = true, multiplicity = "1")
        Exclusive exclusive;
    
        static class Exclusive {
            @Option(names = "-a", required = true) int a;
            @Option(names = "-b", required = true) int b;
            @Option(names = "-c", required = true) int c;
        }
    }
    

    The above example defines a command with mutually exclusive options -a, -b and -c.

    The group itself has a multiplicity attribute that defines how many times the group may be specified within the command. The default is multiplicity = "0..1", meaning that by default a group may be omitted or specified once. In this example the group has multiplicity = "1", so the group must occur once: one of the exclusive options must occur on the command line.

    The synopsis of this command is exclusivedemo (-a=<a> | -b=<b> | -c=<c>).

    Note that the options are defined as required = true; this means required within the group, not required within the command.

    Picocli will validate the arguments and throw a MutuallyExclusiveArgsException if multiple mutually exclusive arguments were specified. For example:

    MutuallyExclusiveOptionsDemo example = new MutuallyExclusiveOptionsDemo();
    CommandLine cmd = new CommandLine(example);
    
    try {
        cmd.parseArgs("-a=1", "-b=2");
    } catch (MutuallyExclusiveArgsException ex) {
        assert "Error: -a=<a>, -b=<b> are mutually exclusive (specify only one)"
                .equals(ex.getMessage());
    }
    

    For the above group, only one of the options can be specified. Any other combination of options, or the absence of options, is invalid.

    Mutually Dependent Options

    Annotate a field or method with @ArgGroup(exclusive = false) to create a group of dependent options and positional parameters that must co-occur. For example:

    @Command(name = "co-occur")
    public class DependentOptionsDemo {
    
        @ArgGroup(exclusive = false)
        Dependent dependent;
    
        static class Dependent {
            @Option(names = "-a", required = true) int a;
            @Option(names = "-b", required = true) int b;
            @Option(names = "-c", required = true) int c;
        }
    }
    

    The above example defines a command with dependent options -a, -b and -c that must co-occur.

    The group itself has a multiplicity attribute that defines how many times the group may be specified within the command. In this example the group uses the default multiplicity, multiplicity = "0..1", meaning that the group may be omitted or specified once.

    The synopsis of this command is co-occur [-a=<a> -b=<b> -c=<c>].

    Note that the options are defined as required = true; this means required within the group, not required within the command.

    Picocli will validate the arguments and throw a MissingParameterException if not all dependent arguments were specified. For example:

    DependentOptionsDemo example = new DependentOptionsDemo();
    CommandLine cmd = new CommandLine(example);
    
    try {
        cmd.parseArgs("-a=1", "-b=2");
    } catch (MissingParameterException ex) {
        assert "Error: Missing required argument(s): -c=<c>".equals(ex.getMessage());
    }
    

    Option Sections in Usage Help

    The example below uses groups to define options sections in the usage help. When a group has a non-null heading (or headingKey), the options in the group are given the specified heading in the usage help message. The headingKey attribute can be used to get the heading text from the command's resource bundle.

    This works for mutually exclusive or co-occurring groups, but it is also possible to define a group that does no validation but only creates an option section in the usage help.

    Annotate a field or method with @ArgGroup(validate = false) to create a group for display purposes only. For example:

    @Command(name = "sectiondemo", description = "Section demo")
    public class OptionSectionDemo {
    
        @ArgGroup(validate = false, heading = "This is the first section%n")
        Section1 section1;
    
        static class Section1 {
            @Option(names = "-a", description = "Option A") int a;
            @Option(names = "-b", description = "Option B") int b;
            @Option(names = "-c", description = "Option C") int c;
        }
    
        @ArgGroup(validate = false, heading = "This is the second section%n")
        Section2 section2;
    
        static class Section2 {
            @Option(names = "-x", description = "Option X") int x;
            @Option(names = "-y", description = "Option Y") int y;
            @Option(names = "-z", description = "Option X") int z;
        }
    
        public static void main(String[] args) {
            new CommandLine(new OptionSectionDemo()).usage(System.out);
        }
    }
    

    This prints the following usage help message:

    Usage: sectiondemo [-a=<a>] [-b=<b>] [-c=<c>] [-x=<x>] [-y=<y>] [-z=<z>]
    Section demo
    This is the first section
      -a=<a>    Option A
      -b=<b>    Option B
      -c=<c>    Option C
    This is the second section
      -x=<x>    Option X
      -y=<y>    Option Y
      -z=<z>    Option X
    

    Note that the heading text must end with %n to insert a newline between the heading text and the first option. This is for consistency with other headings in the usage help, like @Command(headerHeading = "Usage:%n", optionListHeading = "%nOptions:%n").

    Repeating Composite Argument Groups

    The below example shows how groups can be composed of other groups, and how arrays and collections can be used to capture repeating groups (with a multiplicity greater than one):

    @Command(name = "repeating-composite-demo")
    public class CompositeGroupDemo {
    
        @ArgGroup(exclusive = false, multiplicity = "1..*")
        List<Composite> composites;
    
        static class Composite {
            @ArgGroup(exclusive = false, multiplicity = "0..1")
            Dependent dependent;
    
            @ArgGroup(exclusive = true, multiplicity = "1")
            Exclusive exclusive;
        }
    
        static class Dependent {
            @Option(names = "-a", required = true) int a;
            @Option(names = "-b", required = true) int b;
            @Option(names = "-c", required = true) int c;
        }
    
        static class Exclusive {
            @Option(names = "-x", required = true) boolean x;
            @Option(names = "-y", required = true) boolean y;
            @Option(names = "-z", required = true) boolean z;
        }
    }
    

    In the above example, the annotated composites field defines a composite group that must be specified at least once, and may be specified many times (multiplicity = "1..*"), on the command line.

    The synopsis of this command is:

    Usage: repeating-composite-demo ([-a=<a> -b=<b> -c=<c>] (-x | -y | -z))...
    

    Each time the group is matched, picocli creates an instance of the Composite class and adds it to the composites list.

    The Composite class itself contains two groups: an optional (multiplicity = "0..1") group of dependent options that must co-occur, and another group of mutually exclusive options, which is mandatory (multiplicity = "1").

    The below example illustrates:

    CompositeGroupDemo example = new CompositeGroupDemo();
    CommandLine cmd = new CommandLine(example);
    
    cmd.parseArgs("-x", "-a=1", "-b=1", "-c=1", "-a=2", "-b=2", "-c=2", "-y");
    assert example.composites.size() == 2;
    
    Composite c1 = example.composites.get(0);
    assert c1.exclusive.x;
    assert c1.dependent.a == 1;
    assert c1.dependent.b == 1;
    assert c1.dependent.c == 1;
    
    Composite c2 = example.composites.get(1);
    assert c2.exclusive.y;
    assert c2.dependent.a == 2;
    assert c2.dependent.b == 2;
    assert c2.dependent.c == 2;
    

    Positional Parameters

    When a @Parameters positional parameter is part of a group, its index is the index within the group, not within the command.

    Variable expansion

    From this release, picocli supports variable interpolation (variable expansion) in annotation attributes as well as in text attributes of the programmatic API.

    Variable Interpolation Example

    @Command(name = "status", description = "This command logs the status for ${PARENT-COMMAND-NAME}.")
    class Status {
        @Option(names = {"${dirOptionName1:--d}", "${dirOptionName2:---directories}"}, // -d or --directories
                description = {"Specify one or more directories, separated by '${sys:path.separator}'.",
                               "The default is the user home directory (${DEFAULT-VALUE})."},  
                arity = "${sys:dirOptionArity:-1..*}",
                defaultValue = "${sys:user.home}",
                split = "${sys:path.separator}")
        String[] directories;
    }
    

    Predefined Variables

    See the user manual for the list of predefined variables.

    Custom Variables

    In addition, you can define your own variables. Currently the following syntaxes are supported:

    • ${sys:key}: system property lookup, replaced by the value of System.getProperty("key")
    • ${env:key}: environment variable lookup, replaced by the value of System.getEnv("key")
    • ${bundle:key}: look up the value of key in the resource bundle of the command
    • ${key}: search all of the above, first system properties, then environment variables, and finally the resource bundle of the command

    Default Values for Custom Variables

    You can specify a default value to use when no value is found for a custom variable. The syntax for specifying a default is ${a:-b}, where a is the variable name and b is the default value to use if a is not found.

    Explicit JPMS module

    modules

    The main picocli-4.0.0.jar is a JPMS module named info.picocli.

    Starting from picocli 4.0, this jar will be an explicit module instead of an automatic module, so the jlink tool can be used to provide a trimmed binary image that has only the required modules.

    Typically, a modular jar includes the module-info.class file in its root directory. This causes problems for some older tools, which incorrectly process the module descriptor as if it were a normal Java class. To provide the best backward compatibility, the main picocli artifact is a modular multi-release jar with the module-info.class file located in META-INF/versions/9.

    Separate picocli-groovy module

    Groovy logo

    Also, from this release the main picocli-4.x artifact no longer contains the picocli.groovy classes: these have been split off into a separate picocli-groovy-4.x artifact. This was necessary to make the main picocli-4.x.jar an explicit JPMS module.

    Negatable options

    From picocli 4.0, options can be negatable.

    class App {
        @Option(names = "--verbose",           negatable = true) boolean verbose;
        @Option(names = "-XX:+PrintGCDetails", negatable = true) boolean printGCDetails;
        @Option(names = "-XX:-UseG1GC",        negatable = true) boolean useG1GC = true;
    }
    

    When an option is negatable, picocli will recognize negative aliases of the option on the command line.

    For *nix-style long options, aliases have the prefix 'no-' to the given names. For Java JVM-style options, the :+ is turned into :- and vice versa. (This can be changed by customizing the INegatableOptionTransformer.)

    If the negated form of the option is found, for example --no-verbose, the value is set to the provided default. Otherwise, with a regular call, for example --verbose, it is set to the opposite of the default.

    Fallback value for options

    This release introduces a new attribute on the Option annotation: fallbackValue for options with optional parameter: assign this value when the option was specified on the command line without parameter.

    This is different from the defaultValue, which is assigned if the option is not specified at all on the command line.

    Using a fallbackValue allows applications to distinguish between cases where

    • the option was not specified on the command line (default value assigned)
    • the option was specified without parameter on the command line (fallback value assigned)
    • the option was specified with parameter on the command line (command line argument value assigned)

    This is useful to define options that can function as a boolean "switch" and optionally allow users to provide a (strongly typed) extra parameter value.

    The option description may contain the ${FALLBACK-VALUE} variable which will be replaced with the actual fallback value when the usage help is shown.

    Custom parameter processing

    Options or positional parameters can be assigned a IParameterConsumer that implements custom logic to process the parameters for this option or this position. When an option or positional parameter with a custom IParameterConsumer is matched on the command line, picocli's internal parser is temporarily suspended, and the custom parameter consumer becomes responsible for consuming and processing as many command line arguments as needed.

    This can be useful when passing options through to another command.

    For example, the unix find command has a -exec option to execute some action for each file found. Any arguments following the -exec option until a ; or + argument are not options for the find command itself, but are interpreted as a separate command and its options.

    The example below demonstrates how to implement find -exec using this API:

    @Command(name = "find")
    class Find {
        @Option(names = "-exec", parameterConsumer = ExecParameterConsumer.class)
        List<String> list = new ArrayList<String>();
    }
    
    class ExecParameterConsumer implements IParameterConsumer {
        public void consumeParameters(Stack<String> args, ArgSpec argSpec, CommandSpec commandSpec) {
            List<String> list = argSpec.getValue();
            while (!args.isEmpty()) {
                String arg = args.pop();
                list.add(arg);
    
                // `find -exec` semantics: stop processing after a ';' or '+' argument
                if (";".equals(arg) || "+".equals(arg)) {
                    break;
                }
            }
        }
    }
    

    Improved parsing of quoted parameters

    Also, from this release, support for quoted parameter values has been improved. Quoted parameter values can now contain nested quoted substrings to give end users fine-grained control over how values are split. See the user manual for details.

    Auto-detect terminal width for usage help

    From this release, commands defined with @Command(usageHelpAutoWidth = true) will try to adjust the usage message help layout to the terminal width. There is also programmatic API to control this via the CommandLine::setUsageHelpAutoWidth and UsageMessageSpec::autoWidth methods.

    End users may enable this by setting system property picocli.usage.width to AUTO, and may disable this by setting this system property to a numeric value.

    This feature requires Java 7.

    Improved support for Chinese, Japanese and Korean usage help

    Picocli will align the usage help message to fit within some user-defined width (80 columns by default). A number of characters in Chinese, Japanese and Korean (CJK) are wider than others. If those characters are treated to have the same width as other characters, the usage help message may extend past the right margin.

    From this release, picocli will use 2 columns for these wide characters when calculating where to put line breaks, resulting in better usage help message text.

    This can be switched off with CommandLine.setAdjustLineBreaksForWideCJKCharacters(false).

    Fixed issues

    4.0.0-GA

    • [#752][#658][#496] Add picocli-spring-boot-starter module including a PicocliSpringFactory and auto-configuration. Thanks to Thibaud Lepretre for the pull request.
    • [#736] API: Allow removal of ArgSpec from CommandSpec. Thanks to AkosCz for the feature request.
    • [#756] API: Make synopsis indent for multi-line synopsis configurable (related to #739).
    • [#761] API: Add ParseResult.matchedArgs() method to return all matched arguments in order; change ParseResult.matchedOptions() and ParseResult.matchedPositionals() to return the full list of matched options and positional parameters, including duplicates if the option or positional parameter was matched multiple times. Thanks to Michael D. Adams for the feature request.
    • [#760] API: Deprecate CommandLine.setSplitQuotedStrings: the vast majority of applications want to split while respecting quotes.
    • [#754] API/Enhancement: Allow boolean options to get value from fallback instead of defaultProvider. Thanks to Michael D. Adams for the feature request.
    • [#696][#741] Enhancement: Automatically split lines in TextTable. Thanks to Sualeh Fatehi for the pull request.
    • [#744] Enhancement: Composite Argument Groups: more informative error messages. Thanks to Andreas Deininger for raising this.
    • [#745] Enhancement: Picocli should disallow split regex for single-value type options. Thanks to Andreas Deininger for raising this.
    • [#748] Enhancement: Provide API to use a custom Layout in usage help message: ensure Help.createDefaultLayout() is used internally so that subclasses overriding this method can control the Layout that is used.
    • [#595] Enhancement: Support for quoted arguments containing nested quoted substrings, allowing end-users to control how values are split in parts when a split regex is defined.
    • [#739] Bugfix: infinite loop or exception when command name plus synopsis heading length equals or exceeds usage help message width. Thanks to Arturo Alonso for raising this.
    • [#746] Bugfix: Apply default values to options and positional parameters in argument groups. Thanks to Andreas Deininger for raising this.
    • [#742] Bugfix: Default values prevent correct parsing in argument groups. Thanks to Andreas Deininger for raising this.
    • [#759] Bugfix: Correct tracing when custom end-of-option delimiter is matched on the command line.
    • [#738] Bugfix: setTrimQuotes does not trim quotes from option names. Thanks to Judd Gaddie for raising this.
    • [#758] Bugfix: Duplicate name exception in argument group: better / more concise error message. Thanks to Andreas Deininger for raising this.
    • [#751] Build: Make build more portable.
    • [#753] Doc: Improve documentation for multi-value fields: mention the split attribute. Thanks to feinstein.
    • [#740] Doc: Update user manual to replace parse examples with parseArgs.
    • [#713] Doc: Update UML class diagrams for picocli 4.0.

    4.0.0-beta-2

    • [#280] API: @Option(fallbackValue = "...") for options with optional parameter: assign this value when the option was specified on the command line without parameter. Thanks to Paolo Di Tommaso and marinier for the suggestion and in-depth discussion.
    • [#625] API: @Command(synopsisSubcommandLabel = "...") to allow customization of the subcommands part of the synopsis: by default this is [COMMAND]. Thanks to Sebastian Thomschke and AlcaYezz for the feature request and subsequent discussion.
    • [#718] API: Add IParameterConsumer and @Option(parameterConsumer = Xxx.class) for passing arguments through to another command, like find -exec. Thanks to Reinhard Pointner for the suggestion.
    • [#721] API: Add public method Text.getCJKAdjustedLength().
    • [#634] API: Dynamically detect terminal size. Requires Java 7. Thanks to my colleague Takuya Ishibashi for the suggestion.
    • [#737] Deprecate the parse method in favor of parseArgs.
    • [#717] Negatable options change: avoid unmappable character ± for synopsis: it renders as scrambled characters in encoding ASCII and in some terminals.
    • [#734][#735] Make the picocli jar OSGi friendly. Thanks to Radu Cotescu for the pull request.
    • [#733] Improve error message for unmatched arguments. Thanks to my colleague Takuya Ishibashi for raising this.
    • [#719] Bugfix: options with variable arity should stop consuming arguments on custom end-of-options delimiter.
    • [#720] Bugfix: @Unmatched list should be cleared prior to subsequent invocations.
    • [#723] Bugfix: variables in defaultValue were not expanded in usage help option description line for showDefaultValues = true. Thanks to Mikaël Barbero for raising this.
    • [#722] Bugfix: synopsis of deeply nested @ArgGroup shows @Options duplicate on outer level of command. Thanks to Shane Rowatt for raising this.
    • [#724] Bugfix: Usage message exceeds width.
    • [#731] Doc: Add Zero Bugs Commitment to README.

    4.0.0-beta-1b

    • [#500] Add a generic and extensible picocli annotation processor
    • [#699] Add annotation processor that generates reflect-config.json during build
    • [#703] Add annotation processor that generates resource-config.json during build
    • [#704] Add annotation processor that generates proxy-config.json during build
    • [#707] Add example maven/gradle projects that demonstrate using the annotation processor
    • [#711] API: Create separate picocli-groovy module, make picocli an explicit module (a modular multiversion jar)
    • [#694] API: negatable boolean options. Thanks to Michael D. Adams for the feature request.
    • [#712] Boolean options should not toggle by default, to be consistent with negatable options
    • [#709] Fix scrambled characters for the ± character when running on system with non-UTF8 encoding
    • [#717] Fix unmappable character for encoding ASCII by setting compiler encoding to UTF8 explicitly. Thanks to Liam Esteban Prince for raising this.
    • [#697] Option sort in usage help should ignore option name prefix; long options without short name should be inserted alphabetically, instead of always appear at the top.
    • [#695] Fix runtime warnings about illegal reflective access to field java.io.FilterOutputStream.out. Thanks to gitfineon for reporting this issue.
    • [#698] Reduce reflect-config.json used by GraalVM native-image generation
    • [#700] Change default exit codes to 1 for Exceptions in client code, 2 for invalid usage. Add links to ExitCode javadoc.
    • [#715] processor tests should not fail when running in different locale
    • [#710] Let annotation processor validate negatable options, usageHelp options
    • [#716] Revert @Inherited annotation for @Command. Thanks to Mikusch for raising this.

    4.0.0-alpha-3

    • [#516] API: Add support for color schemes in the convenience methods and associated classes and interfaces. Thanks to Bob Tiernay for the suggestion.
    • [#561] API: Parser configuration for convenience methods.
    • [#650] API: Global parser configuration if using Runnable. Thanks to gitfineon for raising this.
    • [#424] API: Exit on help, version or invalid arguments. Thanks to Gerard Bosch for raising this.
    • [#541] API: Improved exception handling for Runnable/Callable.
    • [#680] API: Add annotation API for exitCodeList and exitCodeListHeading.
    • [#611] API: Add CommandLine.addSubcommand overloaded method without name or alias. Thanks to andrewbleonard for the request.
    • [#684] API: Make CommandLine.defaultFactory method public.
    • [#675] API: Make Help.ColorScheme immutable. This is a breaking API change.
    • [#673] API: Deprecate CommandLine.Range public fields, add accessor methods to use instead.
    • [#663] How to remove stacktraces on error. Thanks to Nicolas Mingo and jrevault for raising this and subsequent discussion.
    • [#672] Need way to send errors back from subcommand. Thanks to Garret Wilson for raising this.
    • [#678] Exit Status section in usage help message.
    • [#683] Ensure exitCodeList implementation is consistent with other usage message attributes.
    • [#575] Codegen: Use mixinStandardHelpOptions in AutoComplete$App (add support for the --version option)
    • [#645] Codegen: Exclude Jansi Console from generated GraalVM reflection configuration. Thanks to shanetreacy for raising this.
    • [#686] Codegen: Add support for @Command interfaces (dynamic proxies) in GraalVM native image.
    • [#669] Codegen: Add support for resource bundles in GraalVM native image.
    • [#691] Codegen bugfix: ReflectionConfigGenerator should not generate config for picocli.CommandLine$Model$ObjectScope.
    • [#674] JPMS module: move module-info.class to root of jar.
    • [#676] Bugfix: non-defined variables in defaultValue now correctly resolve to null, and options and positional parameters are now correctly considered required only if their default value is null after variable interpolation. Thanks to ifedorenko for raising this.
    • [#682] Bugfix: incorrect evaluation for multiple occurrences of a variable.
    • [#689] NPE in codegen OutputFileMixin.
    • [#679] Documentation: Update examples for new execute API. Add examples for exit code control and custom exception handlers.
    • [#681] Documentation: Add exit code section to Internationalization example in user manual.

    4.0.0-alpha-2

    • [#495] Publish picocli as a JPMS module in a new artifact picocli-core-module. Thanks to Warkdev for the pull request.
    • [#21] Count double-width Asian characters as two characters for line-breaking purposes.
    • [#526] Add support for variable interpolation in message strings. Thanks to Bob Tiernay for the suggestion.
    • [#660] Added @java.lang.annotation.Inherited to the @picocli.CommandLine.Command annotation. Thanks to Devin Smith for the suggestion.
    • [#661] Bugfix for stack overflow when option in an argument group had a default value. Thanks to Andreas Deininger for reporting this.
    • [#656] Bugfix for issue where synopsis for composite argument groups did not expand for n..* (n > 1). Thanks to Arno Tuomainen for finding this issue.
    • [#654] Bugfix: argument group heading text was not retrieved from ResourceBundle. Thanks to Andreas Deininger for raising this.
    • [#635] Bugfix in argument group validation: did not show an error if some but not all parts of a co-occurring group were specified. Thanks to Philipp Hanslovsky for the pull request.
    • [#653] Bugfix: argument group validation should be skipped if help was requested. Thanks to Andreas Deininger for raising this.
    • [#655] Bugfix: argument group validation silently accepts missing subgroup with multiplicity=1.
    • [#652] Documentation: fixes in user manual. Thanks to Andreas Deininger for the pull request.
    • [#651] Documentation: fixes in user manual. Thanks to Andreas Deininger for the pull request.

    4.0.0-alpha-1

    • [#643] Change % to %% when using ${DEFAULT-VALUE} in option description. Thanks to Steffen Rehberg for the pull request.
    • [#638] Document fallback descriptionKey for options and parameters in user manual. Thanks to Mikusch for the suggestion.
    • [#199] mutually exclusive options
    • [#295] options that must co-occur (dependent options)
    • [#450] option grouping in the usage help message
    • [#358] (also [#635]) repeating composite arguments (this should also cover the use cases presented in #454 and #434 requests for repeatable subcommands)

    Deprecations

    run, call, invoke, and parseWithHandlers methods replaced by execute

    All variants of the run, call, invoke, and parseWithHandlers methods are deprecated from this release, in favor of the new execute method.

    Similarly, the following classes and interfaces are deprecated:

    • IParseResultHandler2 is deprecated in favor of the new IExecutionStrategy interface.
    • IExceptionHandler2 is deprecated in favor of the new IParameterExceptionHandler IExecutionExceptionHandler interfaces.
    • The AbstractHandler and AbstractParseResultHandler classes are deprecated with no replacement.

    CommandLine.setSplitQuotedStrings deprecated

    The CommandLine.setSplitQuotedStrings (and isSplitQuotedStrings) methods have been deprecated: Most applications should not change the default. The rare application that does need to split parameter values without respecting quotes should use ParserSpec.splitQuotedStrings(boolean).

    parse deprecated in favor of parseArgs

    From this release, the parse method is deprecated in favor of parseArgs.

    Range public fields

    The public fields of the Range class have been deprecated and public methods min(), max(), isVariable() have been added that should be used instead.

    Potential breaking changes

    picocli.groovy classes moved to separate artifact

    From this release the main picocli-4.x artifact no longer contains the picocli.groovy classes: these have been split off into a separate picocli-groovy-4.x artifact.

    Scripts upgrading to picocli 4.0 must change more than just the version number! Scripts should use @Grab('info.picocli:picocli-groovy:4.x') from version 4.0, @Grab('info.picocli:picocli:4.x') will not work.

    Split regex on single-value options is now disallowed

    Picocli now throws an InitializationException when a single-value type option or positional parameter has a split regex. Only multi-value options or positional parameters should have a split regex. The runtime check can be disabled by setting system property picocli.ignore.invalid.split to any value. (The annotation processor also checks this at compile time; this check cannot be disabled.)

    ColorScheme is now immutable

    The Help.ColorScheme class has been made immutable. Its public fields are no longer public. A new Help.ColorScheme.Builder class has been introduced to create ColorScheme instances.

    This is a breaking API change: I could not think of a way to do this without breaking backwards compatibility.

    Boolean options do not toggle by default

    From this release, when a flag option is specified on the command line picocli will set its value to the opposite of its default value.

    Prior to 4.0, the default was to "toggle" boolean flags to the opposite of their current value: if the previous value was true it is set to false, and when the value was false it is set to true.

    Applications can call CommandLine.setToggleBooleanFlags(true) to enable toggling. Note that when toggling is enabled, specifying a flag option twice on the command line will have no effect because they cancel each other out.

    ParseResult matchedOptions now returns full list

    ParseResult.matchedOptions() and ParseResult.matchedPositionals() now return the full list of matched options and positional parameters, including duplicates if the option or positional parameter was matched multiple times. Prior to this release, these methods would return a list that did not contain duplicates. Applications interested in the old behavior should use the new matchedOptionSet() and matchedPositionalSet() methods that return a Set.

    Error message for unmatched arguments changed

    The error message for unmatched arguments now shows the index in the command line arguments where the unmatched argument was found, and shows the unmatched value in single quotes. This is useful when the unmatched value is whitespace or an empty String.

    For example:

    Previously:  Unmatched arguments: B, C
    New       :  Unmatched arguments from index 1: 'B', 'C'
    

    This may break tests that rely on the exact error message.

    Option order changed

    Previously, options that only have a long name (and do not have a short name) were always shown before options with a short name. From this release, they are inserted in the option list by their first non-prefix letter. This may break tests that expect a specific help message.

    Factory

    From version 4.0, picocli delegates all object creation to the factory, including creating Collection instances to capture multi-value @Option values. Previously, Collection objects were instantiated separately without involving the factory.

    It is recommended that custom factories should fall back to the default factory. Something like this:

    @Override
    public <K> K create(Class<K> clazz) throws Exception {
        try {
            return doCreate(clazz); // custom factory lookup or instantiation
        } catch (Exception e) {
            return CommandLine.defaultFactory().create(clazz); // fallback if missing
        }
    }
    
    Source code(tar.gz)
    Source code(zip)
    picocli-4.0.0.jar(336.95 KB)
    picocli-all-4.0.0.zip(3.46 MB)
    picocli-codegen-4.0.0.jar(87.81 KB)
    picocli-groovy-4.0.0.jar(7.16 KB)
    picocli-shell-jline2-4.0.0.jar(1.67 KB)
    picocli-shell-jline3-4.0.0.jar(1.85 KB)
    picocli-spring-boot-starter-4.0.0.jar(2.82 KB)
  • v4.0.0-beta-2(Jun 19, 2019)

    Picocli 4.0.0-beta-2

    The picocli community is pleased to announce picocli 4.0.0-beta-2.

    Bugfixes and improvements.

    This release introduces two new attributes on the Option annotation:

    • fallbackValue
    • parameterConsumer

    fallbackValue is for options with optional parameter: assign this value when the option was specified on the command line without parameter. parameterConsumer and the associated IParameterConsumer interface allows for options to bypass picocli's parsing logic and replace it with custom logic. One use case is collecting arguments to pass them through to another command.

    This release introduces a new synopsisSubcommandLabel attribute on the @Command annotation to allow customization of the subcommands part of the synopsis. This is useful for applications that have required subcommands.

    Also, this release adds the ability to dynamically detect the terminal width.

    From this release, the picocli JAR is an OSGi bundle with Bundle-Name: picocli and other appropriate metadata in the manifest.

    Please try this and provide feedback. We can still make changes.

    What do you think of the @ArgGroup annotations API? What about the programmatic API? Does it work as expected? Are the input validation error messages correct and clear? Is the documentation clear and complete? Anything you want to change or improve? Any other feedback?

    Many thanks to the picocli community for the contributions!

    This is the fifty-sixth public release. Picocli follows semantic versioning.

    Table of Contents

    New and Noteworthy

    Fallback Value API

    This release introduces a new attribute on the Option annotation: fallbackValue for options with optional parameter: assign this value when the option was specified on the command line without parameter.

    This is different from the defaultValue, which is assigned if the option is not specified at all on the command line.

    Using a fallbackValue allows applications to distinguish between cases where

    • the option was not specified on the command line (default value assigned)
    • the option was specified without parameter on the command line (fallback value assigned)
    • the option was specified with parameter on the command line (command line argument value assigned)

    This is useful to define options that can function as a boolean "switch" and optionally allow users to provide a (strongly typed) extra parameter value.

    The option description may contain the ${FALLBACK-VALUE} variable which will be replaced with the actual fallback value when the usage help is shown.

    Synopsis Subcommand Label

    For commands with subcommands, the string [COMMAND] is appended to the end of the synopsis (whether the synopsis is abbreviated or not). This looks something like this:

    <cmd> [OPTIONS] FILES [COMMAND]
    

    From picocli 4.0, this can be customized with the synopsisSubcommandLabel attribute.

    For example, to clarify that a subcommand is mandatory, an application may specify COMMAND, without the [ and ] brackets:

    @Command(name = "git", synopsisSubcommandLabel = "COMMAND")
    class Git implements Runnable {
        @Spec CommandSpec spec;
        public void run() {
            throw new ParameterException(spec.commandLine(), "Missing required subcommand");
        }
    }
    

    An application with a limited number of subcommands may want to show them all in the synopsis, for example:

    @Command(name = "fs", synopsisSubcommandLabel = "(list | add | delete)",
             subcommands = {List.class, Add.class, Delete.class})
    class Fs { ... }
    

    Dynamically Detect Terminal Size

    From this release, commands defined with @Command(usageHelpAutoWidth = true) will try to adjust the usage message help layout to the terminal width. There is also programmatic API to control this via the CommandLine::setUsageHelpAutoWidth and UsageMessageSpec::autoWidth methods.

    End users may enable this by setting system property picocli.usage.width to AUTO, and may disable this by setting this system property to a numeric value.

    This feature requires Java 7.

    Custom Parameter Processing

    Options or positional parameters can be assigned a IParameterConsumer that implements custom logic to process the parameters for this option or this position. When an option or positional parameter with a custom IParameterConsumer is matched on the command line, picocli's internal parser is temporarily suspended, and the custom parameter consumer becomes responsible for consuming and processing as many command line arguments as needed.

    This can be useful when passing options through to another command.

    For example, the unix find command has a -exec option to execute some action for each file found. Any arguments following the -exec option until a ; or + argument are not options for the find command itself, but are interpreted as a separate command and its options.

    The example below demonstrates how to implement find -exec using this API:

    @Command(name = "find")
    class Find {
        @Option(names = "-exec", parameterConsumer = ExecParameterConsumer.class)
        List<String> list = new ArrayList<String>();
    }
    
    class ExecParameterConsumer implements IParameterConsumer {
        public void consumeParameters(Stack<String> args, ArgSpec argSpec, CommandSpec commandSpec) {
            List<String> list = argSpec.getValue();
            while (!args.isEmpty()) {
                String arg = args.pop();
                list.add(arg);
    
                // `find -exec` semantics: stop processing after a ';' or '+' argument
                if (";".equals(arg) || "+".equals(arg)) {
                    break;
                }
            }
        }
    }
    

    Fixed issues

    • [#280] API: @Option(fallbackValue = "...") for options with optional parameter: assign this value when the option was specified on the command line without parameter. Thanks to Paolo Di Tommaso and marinier for the suggestion and in-depth discussion.
    • [#625] API: @Command(synopsisSubcommandLabel = "...") to allow customization of the subcommands part of the synopsis: by default this is [COMMAND]. Thanks to Sebastian Thomschke and AlcaYezz for the feature request and subsequent discussion.
    • [#718] API: Add IParameterConsumer and @Option(parameterConsumer = Xxx.class) for passing arguments through to another command, like find -exec. Thanks to Reinhard Pointner for the suggestion.
    • [#721] API: Add public method Text.getCJKAdjustedLength().
    • [#634] API: Dynamically detect terminal size. Requires Java 7. Thanks to my colleague Takuya Ishibashi for the suggestion.
    • [#737] Deprecate the parse method in favor of parseArgs.
    • [#717] Negatable options change: avoid unmappable character ± for synopsis: it renders as scrambled characters in encoding ASCII and in some terminals.
    • [#734][#735] Make the picocli jar OSGi friendly. Thanks to Radu Cotescu for the pull request.
    • [#733] Improve error message for unmatched arguments. Thanks to my colleague Takuya Ishibashi for raising this.
    • [#719] Bugfix: options with variable arity should stop consuming arguments on custom end-of-options delimiter.
    • [#720] Bugfix: @Unmatched list should be cleared prior to subsequent invocations.
    • [#723] Bugfix: variables in defaultValue were not expanded in usage help option description line for showDefaultValues = true. Thanks to Mikaël Barbero for raising this.
    • [#722] Bugfix: synopsis of deeply nested @ArgGroup shows @Options duplicate on outer level of command. Thanks to Shane Rowatt for raising this.
    • [#724] Bugfix: Usage message exceeds width.
    • [#731] Doc: Add Zero Bugs Commitment to README.

    Deprecations

    From this release, the parse method is deprecated in favor of parseArgs.

    Potential breaking changes

    The error message for unmatched arguments now shows the index in the command line arguments where the unmatched argument was found, and shows the unmatched value in single quotes. This is useful when the unmatched value is whitespace or an empty String.

    For example:

    Previously:  Unmatched arguments: B, C
    New       :  Unmatched arguments from index 1: 'B', 'C'
    

    This may break tests that rely on the exact error message.

    Source code(tar.gz)
    Source code(zip)
    picocli-4.0.0-beta-2.jar(333.79 KB)
    picocli-all-4.0.0-beta-2.zip(3.30 MB)
    picocli-codegen-4.0.0-beta-2.jar(114.78 KB)
    picocli-groovy-4.0.0-beta-2.jar(7.17 KB)
    picocli-shell-jline2-4.0.0-beta-2.jar(1.68 KB)
    picocli-shell-jline3-4.0.0-beta-2.jar(1.86 KB)
  • v4.0.0-beta-1b(Jun 5, 2019)

    Picocli 4.0.0-beta-1b

    The picocli community is pleased to announce picocli 4.0.0-beta-1b. (That should have been 4.0.0-beta-1, :-) there were a few hiccups along the way...)

    Annotation Processor

    This release includes the first cut of an annotation processor that can build a model from the picocli annotations at compile time rather than at runtime.

    Use this if you’re interested in:

    • Compile time error checking. The annotation processor shows errors for invalid annotations and attributes immediately when you compile, instead of during testing at runtime, resulting in shorter feedback cycles.
    • Graal native images. The annotation processor generates Graal configuration files under META-INF/native-image/picocli-generated/$project during compilation, to be included in the application jar. By embedding these configuration files, your jar is instantly Graal-enabled. In most cases no further configuration is needed when generating a native image.

    Modular

    The main picocli-4.x.jar is now an explicit JPMS module, with a module-info.class located in META-INF/versions/9. The picocli-jpms-module subproject has been removed.

    Also, from this release the main picocli-4.x artifact no longer contains the picocli.groovy classes: these have been split off into a separate picocli-groovy-4.x artifact.

    Negatable Options

    From picocli 4.0, options can be negatable. When an option is negatable, picocli will recognize negative aliases of the option on the command line. See the New and Noteworthy section below for more details.

    Feedback Welcome

    Please try this and provide feedback. We can still make changes.

    What do you think of the @ArgGroup annotations API? What about the programmatic API? Does it work as expected? Are the input validation error messages correct and clear? Is the documentation clear and complete? Anything you want to change or improve? Any other feedback?

    Many thanks to the picocli community for the contributions!

    This is the fifty-fifth public release. Picocli follows semantic versioning.

    Table of Contents

    New and Noteworthy

    Annotation Processor

    This release includes the first cut of an annotation processor that can build a model from the picocli annotations at compile time rather than at runtime.

    Use this if you’re interested in:

    • Compile time error checking. The annotation processor shows errors for invalid annotations and attributes immediately when you compile, instead of during testing at runtime, resulting in shorter feedback cycles.
    • Graal native images. The annotation processor generates and updates Graal configuration files under META-INF/native-image/picocli-generated/$project during compilation, to be included in the application jar. This includes configuration files for reflection, resources and dynamic proxies. By embedding these configuration files, your jar is instantly Graal-enabled. The $project location is configurable, see processor options below. In most cases no further configuration is needed when generating a native image.

    Enabling the Annotation Processor

    Since Java 6, annotation processing is part of the standard javac compiler, but many IDEs and build tools require something extra to enable annotation processing.

    IDE

    This page shows the steps to configure Eclipse and IntelliJ IDEA to enable annotation processing.

    Maven

    In Maven, use annotationProcessorPaths in the configuration of the maven-compiler-plugin. This requires maven-compiler-plugin plugin version 3.5 or higher.

    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-compiler-plugin</artifactId>
      <!-- annotationProcessorPaths requires maven-compiler-plugin version 3.5 or higher -->
      <version>${maven-compiler-plugin-version}</version>
      <configuration>
        <annotationProcessorPaths>
          <path>
            <groupId>info.picocli</groupId>
            <artifactId>picocli-codegen</artifactId>
            <version>4.0.0-beta-1b</version>
          </path>
        </annotationProcessorPaths>
      </configuration>
    </plugin>
    

    An alternative that works with older versions of the maven-compiler-plugin is to specify the picocli-codegen module on the classpath as a provided dependency. This also prevents the picocli-codegen module from being included in the artifact the module produces as a transitive dependency.

    <dependency>
      <groupId>info.picocli</groupId>
      <artifactId>picocli</artifactId>
      <version>4.0.0-beta-1b</version>
    </dependency>
    
    <dependency>
      <groupId>info.picocli</groupId>
      <artifactId>picocli-codegen</artifactId>
      <version>4.0.0-beta-1b</version>
      <provided>true</provided>
    </dependency>
    

    See Processor Options below.

    Gradle

    Use the annotationProcessor path in Gradle 4.6 and higher:

    dependencies {
        compile 'info.picocli:picocli:4.0.0-beta-1b'
        annotationProcessor 'info.picocli:picocli-codegen:4.0.0-beta-1b'
    }
    

    For Gradle versions prior to 4.6, use compileOnly, to prevent the picocli-codegen jar from being a transitive dependency included in the artifact the module produces.

    dependencies {
        compile 'info.picocli:picocli:4.0.0-beta-1b'
        compileOnly 'info.picocli:picocli-codegen:4.0.0-beta-1b'
    }
    

    Picocli Processor Options

    The picocli annotation processor supports the options below.

    Recommended Options
    • project - output subdirectory

    The generated files are written to META-INF/native-image/picocli-generated/${project}.

    The project option can be omitted, but it is a good idea to specify the project option with a unique value for your project (e.g. ${groupId}/${artifactId}) if your jar may be shaded with other jars into an uberjar.

    Other Options
    • other.resource.patterns - comma-separated list of regular expressions matching additional resources to include in the image
    • other.resource.bundles - comma-separated list of the base names of additional resource bundles to include in the image
    • other.proxy.interfaces - comma-separated list of the fully qualified class names of additional interfaces for which to generate proxy classes when building the image
    • disable.proxy.config - don’t generate proxy-config.json
    • disable.reflect.config - don’t generate reflect-config.json
    • disable.resource.config - don’t generate resources-config.json
    Javac

    To pass an annotation processor option with javac, specify the -A command line option:

    javac -Aproject=org.myorg.myproject/myapp -cp ...
    

    The -A option lets you pass options to annotation processors. See the javac documentation for details.

    Maven

    To set an annotation processor option in Maven, you need to use the maven-compiler-plugin and configure the compilerArgs section.

    <build>
      <plugins>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-compiler-plugin</artifactId>
          <!-- annotationProcessorPaths requires maven-compiler-plugin version 3.5 or higher -->
          <version>${maven-compiler-plugin-version}</version>
          <configuration>
            <compilerArgs>
              <arg>-Aproject=${groupId}/${artifactId}</arg>
            </compilerArgs>
          </configuration>
        </plugin>
      </plugins>
    </build>
    

    See https://maven.apache.org/plugins/maven-compiler-plugin/compile-mojo.html for details.

    Gradle Example

    To set an annotation processor option in Gradle, add these options to the options.compilerArgs list in the compileJava block.

    compileJava {
        // minimum 1.6
        sourceCompatibility = ${java-version}
        targetCompatibility = ${java-version}
        options.compilerArgs += ["-Aproject=${project.group}/${project.name}"]
    }
    

    See the Gradle documentation for details.

    Negatable Options

    From picocli 4.0, options can be negatable.

    class App {
        @Option(names = "--verbose",           negatable = true) boolean verbose;
        @Option(names = "-XX:+PrintGCDetails", negatable = true) boolean printGCDetails;
        @Option(names = "-XX:-UseG1GC",        negatable = true) boolean useG1GC = true;
    }
    

    When an option is negatable, picocli will recognize negative aliases of the option on the command line.

    For *nix-style long options, aliases have the prefix 'no-' to the given names. For Java JVM-style options, the :+ is turned into :- and vice versa. (This can be changed by customizing the INegatableOptionTransformer.)

    If the negated form of the option is found, for example --no-verbose, the value is set to the provided default. Otherwise, with a regular call, for example --verbose, it is set to the opposite of the default.

    Fixed issues

    • [#500] Add a generic and extensible picocli annotation processor
    • [#699] Add annotation processor that generates reflect-config.json during build
    • [#703] Add annotation processor that generates resource-config.json during build
    • [#704] Add annotation processor that generates proxy-config.json during build
    • [#707] Add example maven/gradle projects that demonstrate using the annotation processor
    • [#711] API: Create separate picocli-groovy module, make picocli an explicit module (a modular multiversion jar)
    • [#694] API: negatable boolean options. Thanks to Michael D. Adams for the feature request.
    • [#712] Boolean options should not toggle by default, to be consistent with negatable options
    • [#709] Fix scrambled characters for the ± character when running on system with non-UTF8 encoding
    • [#717] Fix unmappable character for encoding ASCII by setting compiler encoding to UTF8 explicitly. Thanks to Liam Esteban Prince for raising this.
    • [#697] Option sort in usage help should ignore option name prefix; long options without short name should be inserted alphabetically, instead of always appear at the top.
    • [#695] Fix runtime warnings about illegal reflective access to field java.io.FilterOutputStream.out. Thanks to gitfineon for reporting this issue.
    • [#698] Reduce reflect-config.json used by GraalVM native-image generation
    • [#700] Change default exit codes to 1 for Exceptions in client code, 2 for invalid usage. Add links to ExitCode javadoc.
    • [#715] processor tests should not fail when running in different locale
    • [#710] Let annotation processor validate negatable options, usageHelp options
    • [#716] Revert @Inherited annotation for @Command. Thanks to Mikusch for raising this.

    Deprecations

    Potential breaking changes

    picocli.groovy Classes Moved to Separate Artifact

    From this release the main picocli-4.x artifact no longer contains the picocli.groovy classes: these have been split off into a separate picocli-groovy-4.x artifact.

    Scripts upgrading to picocli 4.0 must change more than just the version number! Scripts should use @Grab('info.picocli:picocli-groovy:4.x') from version 4.0, @Grab('info.picocli:picocli:4.x') will not work.

    Option Order Changed

    Previously, options that only have a long name (and do not have a short name) were always shown before options with a short name. From this release, they are inserted in the option list by their first non-prefix letter. This may break tests that expect a specific help message.

    Boolean Options Do Not Toggle By Default

    From this release, when a flag option is specified on the command line picocli will set its value to the opposite of its default value.

    Prior to 4.0, the default was to "toggle" boolean flags to the opposite of their current value: if the previous value was true it is set to false, and when the value was false it is set to true.

    Applications can call CommandLine.setToggleBooleanFlags(true) to enable toggling. Note that when toggling is enabled, specifying a flag option twice on the command line will have no effect because they cancel each other out.

    Revert @Inherited annotation on @Command

    The @Inherited annotated that was added to @Command in picocli 4.0.0-alpha-2 turned out to cause issues in scenarios with multiple levels of inheritance and is reverted in this release.

    Source code(tar.gz)
    Source code(zip)
    picocli-4.0.0-beta-1b.jar(323.90 KB)
    picocli-all-4.0.0-beta-1b.zip(3.22 MB)
    picocli-codegen-4.0.0-beta-1b.jar(114.78 KB)
    picocli-groovy-4.0.0-beta-1b.jar(7.17 KB)
    picocli-shell-jline2-4.0.0-beta-1b.jar(1.68 KB)
    picocli-shell-jline3-4.0.0-beta-1b.jar(1.86 KB)
  • v4.0.0-alpha-3(May 13, 2019)

    Picocli 4.0.0-alpha-3

    The picocli community is pleased to announce picocli 4.0.0-alpha-3.

    This release adds improved support for command execution via the new execute method. This method returns an exit code that applications can use to call System.exit.

    The older run, call, invoke and parseWithHandlers convenience methods that were similar to execute but had limited support for parser configuration and and limited support for exit codes are deprecated from this release.

    This release also improves the picocli tools for configuring GraalVM native image builds: there is now support for commands with resource bundles and jewelcli-style @Command-annotated interfaces for which picocli generates a dynamic proxy.

    Please try this and provide feedback. We can still make changes.

    What do you think of the @ArgGroup annotations API? What about the programmatic API? Does it work as expected? Are the input validation error messages correct and clear? Is the documentation clear and complete? Anything you want to change or improve? Any other feedback?

    Many thanks to the picocli community for the contributions!

    This is the fifty-fourth public release. Picocli follows semantic versioning.

    Table of Contents

    New and Noteworthy

    Executing Commands

    Picocli 4.0 introduces new API to execute commands. Let’s take a quick look at what changed.

    Exit Code

    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 introduced in picocli 4.0 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.

    Generating an Exit Code

    @Command-annotated classes that implement Callable and @Command-annotated methods can simply return an int or Integer, and this value 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;
      }
    }
    
    assert 1 == new CommandLine(new Greet()).execute();
    assert 2 == new CommandLine(new Greet()).execute("shout");
    

    Commands with a user object that implements Runnable can implement the IExitCodeGenerator interface to generate an exit code. For example:

    @Command(name = "wave")
    class Gesture implements Runnable, IExitCodeGenerator {
      public void run() {
        System.out.println("wave");
      }
      public int getExitCode() {
        return 3;
      }
    }
    
    assert 3 == new CommandLine(new Gesture()).execute();
    

    Exception Exit Codes

    By default, the execute method returns CommandLine.ExitCode.USAGE (64) for invalid input, and CommandLine.ExitCode.SOFTWARE (70) when an exception occurred in the Runnable, Callable or command method. (For reference, these values are EX_USAGE and EX_SOFTWARE, respectively, from Unix and Linux sysexits.h). This can be customized with the @Command annotation. For example:

    @Command(exitCodeOnInvalidInput = 123,
       exitCodeOnExecutionException = 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;
      }
    }
    

    When the end user specified invalid input, the execute method prints an error message followed by the usage help message of the command, and returns an exit code. This can be customized by configuring a IParameterExceptionHandler.

    If the business logic of the command throws an exception, the execute method prints the stack trace of the exception and returns an exit code. This can be customized by configuring a IExecutionExceptionHandler.

    Configuration

    The new CommandLine.execute method is an instance method. 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.setUnmarchedArgumentsAllowed(true);
      cmd.setStopAtPositional(true);
      cmd.setExpandAtFiles(false);
      cmd.execute(args);
    }
    

    Execution Configuration

    The following configuration methods are new and are only applicable with the execute method (and executeHelpRequest):

    • get/setOut
    • get/setErr
    • get/setColorScheme
    • get/setExecutionStrategy
    • get/setParameterExceptionHandler
    • get/setExecutionExceptionHandler
    • get/setExitCodeExceptionMapper

    The above methods are not applicable (and ignored) with other entry points like parse, parseArgs, populateCommand, run, call, invoke, parseWithHandler and parseWithHandlers.

    API Evolution and Trade-offs

    Previous versions of picocli offered the run, call and invoke methods to execute a Runnable, Callable or Method command. Here are some trade-offs versus the new execute method:

    • Static - These are static methods, with the drawback that they don't allow configuration, as mentioned above.
    • Type Safety - It is a compile-time error when an application tries to pass anything else than a Runnable to the run method, and a Callable to the call method. The execute method does not have this type safety, since the CommandLine constructor allows any Object as a parameter.
    • Return Value - The call and invoke static methods allow commands to return any value, while the execute method only returns an int exit code. From 4.0 the result object will be available from the CommandLine.getExecutionResult method.

    Feedback Requested

    With the new execute API the ColorScheme class will start to play a more central role. I decided to make the ColorScheme class immutable from this release. This is a breaking API change. Should it be deprecated first, or not changed at all, or is the 4.0 release a good time to make breaking changes? Your feedback is very welcome on https://github.com/remkop/picocli/issues/675.

    Tools for Configuring GraalVM Native Image Builds

    The picocli-codegen module now has two new tools, in addition to the existing ReflectionConfigGenerator:

    • ResourceConfigGenerator
    • DynamicProxyConfigGenerator

    ResourceConfigGenerator

    The GraalVM native-image builder by default will not integrate any of the classpath resources into the image it creates.

    ResourceConfigGenerator generates a JSON String with the resource bundles and other classpath resources that should be included in the Substrate VM native image.

    The output of ResourceConfigGenerator is intended to be passed to the -H:ResourceConfigurationFiles=/path/to/reflect-config.json option of the native-image GraalVM utility, or placed in a META-INF/native-image/ subdirectory of the JAR.

    This allows picocli-based native image applications to access these resources.

    DynamicProxyConfigGenerator

    Substrate VM doesn't provide machinery for generating and interpreting bytecodes at run time. Therefore all dynamic proxy classes need to be generated at native image build time.

    DynamicProxyConfigGenerator generates a JSON String with the fully qualified interface names for which dynamic proxy classes should be generated at native image build time.

    The output of DynamicProxyConfigGenerator is intended to be passed to the -H:DynamicProxyConfigurationFiles=/path/to/proxy-config.json option of the native-image GraalVM utility, or placed in a META-INF/native-image/ subdirectory of the JAR.

    This allows picocli-based native image applications that use @Command-annotated interfaces with @Option and @Parameters-annotated methods.

    Fixed issues

    • [#516] API: Add support for color schemes in the convenience methods and associated classes and interfaces. Thanks to Bob Tiernay for the suggestion.
    • [#561] API: Parser configuration for convenience methods.
    • [#650] API: Global parser configuration if using Runnable. Thanks to gitfineon for raising this.
    • [#424] API: Exit on help, version or invalid arguments. Thanks to Gerard Bosch for raising this.
    • [#541] API: Improved exception handling for Runnable/Callable.
    • [#680] API: Add annotation API for exitCodeList and exitCodeListHeading.
    • [#611] API: Add CommandLine.addSubcommand overloaded method without name or alias. Thanks to andrewbleonard for the request.
    • [#684] API: Make CommandLine.defaultFactory method public.
    • [#675] API: Make Help.ColorScheme immutable. This is a breaking API change.
    • [#673] API: Deprecate CommandLine.Range public fields, add accessor methods to use instead.
    • [#663] How to remove stacktraces on error. Thanks to Nicolas Mingo and jrevault for raising this and subsequent discussion.
    • [#672] Need way to send errors back from subcommand. Thanks to Garret Wilson for raising this.
    • [#678] Exit Status section in usage help message.
    • [#683] Ensure exitCodeList implementation is consistent with other usage message attributes.
    • [#575] Codegen: Use mixinStandardHelpOptions in AutoComplete$App (add support for the --version option)
    • [#645] Codegen: Exclude Jansi Console from generated GraalVM reflection configuration. Thanks to shanetreacy for raising this.
    • [#686] Codegen: Add support for @Command interfaces (dynamic proxies) in GraalVM native image.
    • [#669] Codegen: Add support for resource bundles in GraalVM native image.
    • [#691] Codegen bugfix: ReflectionConfigGenerator should not generate config for picocli.CommandLine$Model$ObjectScope.
    • [#674] JPMS module: move module-info.class to root of jar.
    • [#676] Bugfix: non-defined variables in defaultValue now correctly resolve to null, and options and positional parameters are now correctly considered required only if their default value is null after variable interpolation. Thanks to ifedorenko for raising this.
    • [#682] Bugfix: incorrect evaluation for multiple occurrences of a variable.
    • [#689] NPE in codegen OutputFileMixin.
    • [#679] Documentation: Update examples for new execute API. Add examples for exit code control and custom exception handlers.
    • [#681] Documentation: Add exit code section to Internationalization example in user manual.

    Deprecations

    Convenience Methods Replaced by execute

    All variants of the run, call, invoke, and parseWithHandlers methods are deprecated from this release, in favor of the new execute method.

    Similarly, the following classes and interfaces are deprecated:

    • IParseResultHandler2 is deprecated in favor of the new IExecutionStrategy interface.
    • IExceptionHandler2 is deprecated in favor of the new IParameterExceptionHandler IExecutionExceptionHandler interfaces.
    • The AbstractHandler and AbstractParseResultHandler classes are deprecated with no replacement.

    Range

    The public fields of the Range class have been deprecated and public methods min(), max(), isVariable() have been added that should be used instead.

    Potential breaking changes

    The Help.ColorScheme class has been made immutable. Its public fields are no longer public. A new Help.ColorScheme.Builder class has been introduced to create ColorScheme instances.

    This is a breaking API change: I could not think of a way to do this without breaking backwards compatibility.

    Source code(tar.gz)
    Source code(zip)
    picocli-4.0.0-alpha-3.jar(324.22 KB)
    picocli-all-4.0.0-alpha-3.zip(3.54 MB)
    picocli-codegen-4.0.0-alpha-3.jar(81.19 KB)
    picocli-jpms-module-4.0.0-alpha-3.jar(317.73 KB)
    picocli-shell-jline2-4.0.0-alpha-3.jar(1.68 KB)
    picocli-shell-jline3-4.0.0-alpha-3.jar(1.86 KB)
  • v4.0.0-alpha-2(Apr 18, 2019)

    Picocli 4.0.0-alpha-2

    The picocli community is pleased to announce picocli 4.0.0-alpha-2.

    Thanks to great feedback from the picocli community on the 4.0.0-alpha-1 release, this release contains many argument group-related bugfixes. See the 4.0.0-alpha-1 New and Noteworthy section below for more details on argument groups.

    Please try this and provide feedback. We can still make changes.

    What do you think of the annotations API? What about the programmatic API? Does it work as expected? Are the input validation error messages correct and clear? Is the documentation clear and complete? Anything you want to change or improve? Any other feedback?

    This release also has support for variable expansion and improved support for Chinese, Japanese and Korean.

    Many thanks to the picocli community for the contributions!

    This is the fifty-third public release. Picocli follows semantic versioning.

    Table of Contents

    New and Noteworthy

    Argument Groups

    Many bugfixes for argument groups.

    Variable Interpolation

    From this release, picocli supports variable interpolation (variable expansion) in annotation attributes as well as in text attributes of the programmatic API.

    Variable Interpolation Example

    @Command(name = "status", description = "This command logs the status for ${PARENT-COMMAND-NAME}.")
    class Status {
        @Option(names = {"${dirOptionName1:--d}", "${dirOptionName2:---directories}"}, // -d or --directories
                description = {"Specify one or more directories, separated by '${sys:path.separator}'.",
                               "The default is the user home directory (${DEFAULT-VALUE})."},  
                arity = "${sys:dirOptionArity:-1..*}",
                defaultValue = "${sys:user.home}",
                split = "${sys:path.separator}")
        String[] directories;
    }
    

    Predefined Variables

    The following variables are predefined:

    • ${DEFAULT-VALUE}: (since 3.2) - can be used in the description for an option or positional parameter, replaced with the default value for that option or positional parameter
    • ${COMPLETION-CANDIDATES}: (since 3.2) - can be used in the description for an option or positional parameter, replaced with the completion candidates for that option or positional parameter
    • ${COMMAND-NAME}: (since 4.0) - can be used in any section of the usage help message for a command, replaced with the name of the command
    • ${COMMAND-FULL-NAME}: (since 4.0) - can be used in any section of the usage help message for a command, replaced with the fully qualified name of the command (that is, preceded by its parent fully qualified name)
    • ${PARENT-COMMAND-NAME}: (since 4.0) - can be used in any section of the usage help message for a command, replaced with the name of its parent command
    • ${PARENT-COMMAND-FULL-NAME}: (since 4.0) - can be used in any section of the usage help message for a command, replaced with the fully qualified name of its parent command (that is, preceded by the name(s) of the parent command's ancestor commands)

    Custom Variables

    In addition, you can define your own variables. Currently the following syntaxes are supported:

    • ${sys:key}: system property lookup, replaced by the value of System.getProperty("key")
    • ${env:key}: environment variable lookup, replaced by the value of System.getEnv("key")
    • ${bundle:key}: look up the value of key in the resource bundle of the command
    • ${key}: search all of the above, first system properties, then environment variables, and finally the resource bundle of the command

    Default Values for Custom Variables

    You can specify a default value to use when no value is found for a custom variable. The syntax for specifying a default is ${a:-b}, where a is the variable name and b is the default value to use if a is not found.

    So, for the individual lookups, this looks like this:

    ${key:-defaultValue}
    ${sys:key:-defaultValue}
    ${env:key:-defaultValue}
    ${bundle:key:-defaultValue}
    

    The default value may contain other custom variables. For example:

    ${bundle:a:-${env:b:-${sys:c:-X}}}
    

    The above variable is expanded as follows. First, try to find key a in the command's resource bundle. If a is not found in the resource bundle, get the value of environment variable b. If no environment variable b exists, get the value of system property c. Finally, no system property c exists, the value of the expression becomes X.

    Escaping Variables

    Sometimes you want to show a string like "${VAR}" in a description. A $ character can be escaped with another $ character. Therefore, $${VAR} will not be interpreted as a VAR variable, but will be replaced by ${VAR} instead.

    Switching Off Variable Interpolation

    Variable interpolation can be switched off for the full command hierarchy by calling CommandLine.setInterpolateVariables(false), or for a particular command by calling CommandSpec.interpolateVariables(false).

    Limitations of Variable Interpolation

    Some attribute values need to be resolved early, when the model is constructed from the annotation values.

    Specifically:

    • command names and aliases, option names, mixin names
    • arity (for options and positional parameters)
    • index (for positional parameters)
    • separator (for commands)

    It is possible for these attributes to contain variables, but be aware of the limitations.

    If these attributes have variables, and the variables get a different value after the model is constructed, the change will not be reflected in the model.

    Improved Support for Chinese, Japanese and Korean

    Picocli will align the usage help message to fit within some user-defined width (80 columns by default). A number of characters in Chinese, Japanese and Korean (CJK) are wider than others. If those characters are treated to have the same width as other characters, the usage help message may extend past the right margin.

    From this release, picocli will use 2 columns for these wide characters when calculating where to put line breaks, resulting in better usage help message text.

    This can be switched off with CommandLine.setAdjustLineBreaksForWideCJKCharacters(false).

    Fixed issues

    • [#495] Publish picocli as a JPMS module in a new artifact picocli-core-module. Thanks to Warkdev for the pull request.
    • [#21] Count double-width Asian characters as two characters for line-breaking purposes.
    • [#526] Add support for variable interpolation in message strings. Thanks to Bob Tiernay for the suggestion.
    • [#660] Added @java.lang.annotation.Inherited to the @picocli.CommandLine.Command annotation. Thanks to Devin Smith for the suggestion.
    • [#661] Bugfix for stack overflow when option in an argument group had a default value. Thanks to Andreas Deininger for reporting this.
    • [#656] Bugfix for issue where synopsis for composite argument groups did not expand for n..* (n > 1). Thanks to Arno Tuomainen for finding this issue.
    • [#654] Bugfix: argument group heading text was not retrieved from ResourceBundle. Thanks to Andreas Deininger for raising this.
    • [#635] Bugfix in argument group validation: did not show an error if some but not all parts of a co-occurring group were specified. Thanks to Philipp Hanslovsky for the pull request.
    • [#653] Bugfix: argument group validation should be skipped if help was requested. Thanks to Andreas Deininger for raising this.
    • [#655] Bugfix: argument group validation silently accepts missing subgroup with multiplicity=1.
    • [#652] Documentation: fixes in user manual. Thanks to Andreas Deininger for the pull request.
    • [#651] Documentation: fixes in user manual. Thanks to Andreas Deininger for the pull request.

    Deprecations

    No features were deprecated in this release.

    Potential breaking changes

    The following classes and methods introduced in 4.0.0-alpha-1 have been renamed:

    Classes:

    • picocli.CommandLine.ParseResult.MatchedGroup -> picocli.CommandLine.ParseResult.GroupMatchContainer
    • picocli.CommandLine.ParseResult.MatchedGroupMultiple -> picocli.CommandLine.ParseResult.GroupMatch

    Methods:

    • ParseResult::getMatchedGroupMultiples has been renamed to ParseResult::getGroupMatches
    • ParseResult::findMatchedGroup(ArgGroupSpec) has been renamed to ParseResult::findMatches(ArgGroupSpec)

    Removed:

    These may be implemented in a future version.

    • picocli.CommandLine.Option.excludes() and picocli.CommandLine.Parameters.excludes()
    • picocli.CommandLine.Option.needs(() and picocli.CommandLine.Parameters.needs(()
    Source code(tar.gz)
    Source code(zip)
    picocli-4.0.0-alpha-2.jar(308.72 KB)
    picocli-all-4.0.0-alpha-2.zip(4.22 MB)
    picocli-codegen-4.0.0-alpha-2.jar(69.97 KB)
    picocli-jpms-module-all-4.0.0-alpha-2.jar(313.17 KB)
    picocli-shell-jline2-4.0.0-alpha-2.jar(1.68 KB)
    picocli-shell-jline3-4.0.0-alpha-2.jar(1.86 KB)
  • v3.9.6(Apr 6, 2019)

    Picocli 3.9.6

    The picocli community is pleased to announce picocli 3.9.6.

    This release improves support for interactive (password) options:

    • interactive options can now use type char[] instead of String, to allow applications to null out the array after use so that sensitive information is no longer resident in memory
    • interactive options can be optionally interactive if configured with arity = "0..1"

    This is the fifty-second public release. Picocli follows semantic versioning.

    Table of Contents

    New and Noteworthy

    This release improves support for interactive (password) options:

    • interactive options can now use type char[] instead of String, to allow applications to null out the array after use so that sensitive information is no longer resident in memory
    • interactive options can be optionally interactive if configured with arity = "0..1"

    For example, if an application has these options:

    @Option(names = "--user")
    String user;
    
    @Option(names = "--password", arity = "0..1", interactive = true)
    char[] password;
    

    With the following input, the password field will be initialized to "123" without prompting the user for input:

    --password 123 --user Joe
    

    However, if the password is not specified, the user will be prompted to enter a value. In the following example, the password option has no parameter, so the user will be prompted to type in a value on the console:

    --password --user Joe
    

    Fixed issues

    • [#657] Support type char[] for interactive options. Thanks to Lukáš Petrovický for raising this issue.
    • [#536] Support optionally interactive options. Thanks to Lukas Heumos for raising this issue.

    Deprecations

    No features were deprecated in this release.

    Potential breaking changes

    This release has no breaking changes.

    Source code(tar.gz)
    Source code(zip)
    picocli-3.9.6.jar(258.68 KB)
    picocli-all-3.9.6.zip(2.49 MB)
  • v4.0.0-alpha-1(Mar 30, 2019)

    Picocli 4.0.0-alpha-1

    The picocli community is pleased to announce picocli 4.0.0-alpha-1.

    This release adds support for argument groups (incubating). Argument groups enable the following:

    • mutually exclusive options
    • options that must co-occur (dependent options)
    • option sections in the usage help message
    • repeating composite arguments

    See the New and Noteworthy section below for more details.

    Please try this and provide feedback. We can still make changes.

    What do you think of the annotations API? What about the programmatic API? Does it work as expected? Are the input validation error messages correct and clear? Is the documentation clear and complete? Anything you want to change or improve? Any other feedback?

    Many thanks to the picocli community members who contributed!

    This is the fifty-first public release. Picocli follows semantic versioning.

    Table of Contents

    New and Noteworthy

    Argument Groups (Incubating)

    This release introduces a new @ArgGroup annotation and its ArgGroupSpec programmatic equivalent.

    Argument Groups can be used to define:

    • mutually exclusive options
    • options that must co-occur (dependent options)
    • option sections in the usage help message
    • repeating composite arguments

    To create a group using the annotations API, annotate a field or method with @ArgGroup. The field's type refers to the class containing the options and positional parameters in the group. (For annotated interface methods this would be the return type, for annotated setter methods in a concrete class this would be the setter's parameter type.)

    Picocli will instantiate this class as necessary to capture command line argument values in the @Option and @Parameters-annotated fields and methods of this class.

    Mutually Exclusive Options

    Annotate a field or method with @ArgGroup(exclusive = true) to create a group of mutually exclusive options and positional parameters. For example:

    @Command(name = "exclusivedemo")
    public class MutuallyExclusiveOptionsDemo {
    
        @ArgGroup(exclusive = true, multiplicity = "1")
        Exclusive exclusive;
    
        static class Exclusive {
            @Option(names = "-a", required = true) int a;
            @Option(names = "-b", required = true) int b;
            @Option(names = "-c", required = true) int c;
        }
    }
    

    The above example defines a command with mutually exclusive options -a, -b and -c.

    The group itself has a multiplicity attribute that defines how many times the group may be specified within the command. The default is multiplicity = "0..1", meaning that by default a group may be omitted or specified once. In this example the group has multiplicity = "1", so the group must occur once: one of the exclusive options must occur on the command line.

    The synopsis of this command is exclusivedemo (-a=<a> | -b=<b> | -c=<c>).

    Note that the options are defined as required = true; this means required within the group, not required within the command.

    Picocli will validate the arguments and throw a MutuallyExclusiveArgsException if multiple mutually exclusive arguments were specified. For example:

    MutuallyExclusiveOptionsDemo example = new MutuallyExclusiveOptionsDemo();
    CommandLine cmd = new CommandLine(example);
    
    try {
        cmd.parseArgs("-a=1", "-b=2");
    } catch (MutuallyExclusiveArgsException ex) {
        assert "Error: -a=<a>, -b=<b> are mutually exclusive (specify only one)"
                .equals(ex.getMessage());
    }
    

    For the above group, only one of the options can be specified. Any other combination of options, or the absence of options, is invalid.

    Co-occurring (Dependent) Options

    Annotate a field or method with @ArgGroup(exclusive = false) to create a group of dependent options and positional parameters that must co-occur. For example:

    @Command(name = "co-occur")
    public class DependentOptionsDemo {
    
        @ArgGroup(exclusive = false)
        Dependent dependent;
    
        static class Dependent {
            @Option(names = "-a", required = true) int a;
            @Option(names = "-b", required = true) int b;
            @Option(names = "-c", required = true) int c;
        }
    }
    

    The above example defines a command with dependent options -a, -b and -c that must co-occur.

    The group itself has a multiplicity attribute that defines how many times the group may be specified within the command. In this example the group uses the default multiplicity, multiplicity = "0..1", meaning that the group may be omitted or specified once.

    The synopsis of this command is co-occur [-a=<a> -b=<b> -c=<c>].

    Note that the options are defined as required = true; this means required within the group, not required within the command.

    Picocli will validate the arguments and throw a MissingParameterException if not all dependent arguments were specified. For example:

    DependentOptionsDemo example = new DependentOptionsDemo();
    CommandLine cmd = new CommandLine(example);
    
    try {
        cmd.parseArgs("-a=1", "-b=2");
    } catch (MissingParameterException ex) {
        assert "Error: Missing required argument(s): -c=<c>".equals(ex.getMessage());
    }
    

    Option Sections in Usage Help

    The example below uses groups to define options sections in the usage help. When a group has a non-null heading (or headingKey), the options in the group are given the specified heading in the usage help message. The headingKey attribute can be used to get the heading text from the command's resource bundle.

    This works for mutually exclusive or co-occurring groups, but it is also possible to define a group that does no validation but only creates an option section in the usage help.

    Annotate a field or method with @ArgGroup(validate = false) to create a group for display purposes only. For example:

    @Command(name = "sectiondemo", description = "Section demo")
    public class OptionSectionDemo {
    
        @ArgGroup(validate = false, heading = "This is the first section%n")
        Section1 section1;
    
        static class Section1 {
            @Option(names = "-a", description = "Option A") int a;
            @Option(names = "-b", description = "Option B") int b;
            @Option(names = "-c", description = "Option C") int c;
        }
    
        @ArgGroup(validate = false, heading = "This is the second section%n")
        Section2 section2;
    
        static class Section2 {
            @Option(names = "-x", description = "Option X") int x;
            @Option(names = "-y", description = "Option Y") int y;
            @Option(names = "-z", description = "Option X") int z;
        }
    
        public static void main(String[] args) {
            new CommandLine(new OptionSectionDemo()).usage(System.out);
        }
    }
    

    This prints the following usage help message:

    Usage: sectiondemo [-a=<a>] [-b=<b>] [-c=<c>] [-x=<x>] [-y=<y>] [-z=<z>]
    Section demo
    This is the first section
      -a=<a>    Option A
      -b=<b>    Option B
      -c=<c>    Option C
    This is the second section
      -x=<x>    Option X
      -y=<y>    Option Y
      -z=<z>    Option X
    

    Note that the heading text must end with %n to insert a newline between the heading text and the first option. This is for consistency with other headings in the usage help, like @Command(headerHeading = "Usage:%n", optionListHeading = "%nOptions:%n").

    Repeating Composite Argument Groups

    The below example shows how groups can be composed of other groups, and how arrays and collections can be used to capture repeating groups (with a multiplicity greater than one):

    public class CompositeGroupDemo {
    
        @ArgGroup(exclusive = false, multiplicity = "1..*")
        List<Composite> composites;
    
        static class Composite {
            @ArgGroup(exclusive = false, multiplicity = "1")
            Dependent dependent;
    
            @ArgGroup(exclusive = true, multiplicity = "1")
            Exclusive exclusive;
        }
    
        static class Dependent {
            @Option(names = "-a", required = true) int a;
            @Option(names = "-b", required = true) int b;
            @Option(names = "-c", required = true) int c;
        }
    
        static class Exclusive {
            @Option(names = "-x", required = true) boolean x;
            @Option(names = "-y", required = true) boolean y;
            @Option(names = "-z", required = true) boolean z;
        }
    }
    

    In the above example, the annotated composites field defines a composite group that must be specified at least once, and may be specified many times, on the command line. Each time the group is matched, picocli creates an instance of the Composite class and adds it to the composites list.

    The Composite class itself contains two groups: a group of dependent options that must co-occur, and another group of mutually exclusive options. Both of these subgroups have multiplicity = "1", so they can occur exactly once for each multiple of the Composite group. The below example illustrates:

    CompositeGroupDemo example = new CompositeGroupDemo();
    CommandLine cmd = new CommandLine(example);
    
    cmd.parseArgs("-x", "-a=1", "-b=1", "-c=1", "-a=2", "-b=2", "-c=2", "-y");
    assert example.composites.size() == 2;
    
    Composite c1 = example.composites.get(0);
    assert c1.exclusive.x;
    assert c1.dependent.a == 1;
    assert c1.dependent.b == 1;
    assert c1.dependent.c == 1;
    
    Composite c2 = example.composites.get(1);
    assert c2.exclusive.y;
    assert c2.dependent.a == 2;
    assert c2.dependent.b == 2;
    assert c2.dependent.c == 2;
    

    Positional Parameters

    When a @Parameters positional parameter is part of a group, its index is the index within the group, not within the command.

    Limitations and Points of Caution

    • Options with the same name cannot be defined in multiple groups. Similarly, it is not possible to define an option outside of a group with the same name as a different option that is part of a group.
    • Positional parameters in a single group work fine, but take care (or avoid) defining positional parameters in multiple groups or positional parameters in a group as well as outside a group. Positional parameters are matched by index, and while the index of a group is reset when a new group multiple is encountered, the index of positional parameters outside a group only increases and is never reset.

    Fixed issues

    • [#643] Change % to %% when using ${DEFAULT-VALUE} in option description. Thanks to Steffen Rehberg for the pull request.
    • [#638] Document fallback descriptionKey for options and parameters in user manual. Thanks to Mikusch for the suggestion.
    • [#199] mutually exclusive options
    • [#295] options that must co-occur (dependent options)
    • [#450] option grouping in the usage help message
    • [#358] (also [#635]) repeating composite arguments (this should also cover the use cases presented in #454 and #434 requests for repeatable subcommands)

    Deprecations

    No features were deprecated in this release.

    Potential breaking changes

    No breaking changes in this release.

    Source code(tar.gz)
    Source code(zip)
    picocli-4.0.0-alpha-1.jar(294.24 KB)
    picocli-all-4.0.0-alpha-1.zip(2.91 MB)
    picocli-codegen-4.0.0-alpha-1.jar(69.87 KB)
    picocli-shell-jline2-4.0.0-alpha-1.jar(1.68 KB)
    picocli-shell-jline3-4.0.0-alpha-1.jar(1.86 KB)
  • v3.9.5(Feb 18, 2019)

    Picocli 3.9.5

    The picocli community is pleased to announce picocli 3.9.5.

    This release contains a critical workaround to protect against JVM crashes when running on RedHat Linux 3.10.0-327.44.2.el7.x86_64.

    Picocli 3.9.0 introduced a change in the heuristics for detecting when to emit ANSI escape sequences. As part of this change, picocli may load the org.fusesource.jansi.AnsiConsole class from the JAnsi library when not running on Windows. This may crash the JVM.

    The underlying problem may be a bug in the native library in jansi 1.14, see fusesource/jansi-native#17 for details.

    The workaround in this release is to only load the AnsiConsole class when running on Windows.

    Users using 3.9.0 and higher are strongly recommended to upgrade to 3.9.5 or later.

    Note that this issue can manifest itself when running in Gradle (e.g. continuous integration tests) even if the application itself does not have the jansi library in the classpath, since the jansi classes can be loaded from the jansi-1.14 jar included in Gradle 4.5.x.

    This is the fiftieth public release. Picocli follows semantic versioning.

    Table of Contents

    New and Noteworthy

    Fixed issues

    • [#630] Avoid loading org.fusesource.jansi.AnsiConsole when not running on Windows to avoid JVM crashes on non-Windows platforms.
    • [#632] For generating GraalVM native images, ReflectionConfigGenerator in picocli-codegen now specifies the allowWrite = true attribute for final fields.

    Deprecations

    No features were deprecated in this release.

    Potential breaking changes

    This release has no breaking changes.

    Source code(tar.gz)
    Source code(zip)
    picocli-3.9.5.jar(256.84 KB)
    picocli-all-3.9.5.zip(2.46 MB)
    picocli-codegen-3.9.5.jar(13.26 KB)
    picocli-shell-jline2-3.9.5.jar(1.67 KB)
    picocli-shell-jline3-3.9.5.jar(1.85 KB)
Java annotation-based framework for parsing Git like command line structures

Airline Airline is a Java annotation-based framework for parsing Git like command line structures. Latest release is 0.8, available from Maven Central

null 847 Nov 26, 2022
Command line parsing framework for Java

JCommander This is an annotation based parameter parsing framework for Java 8. Here is a quick example: public class JCommanderTest { @Parameter

Cedric Beust 1.8k Dec 29, 2022
A command line parser generator

jbock is a command line parser that works similar to airline and picocli. While most of these other tools scan for annotations at runtime, jbock is an

H90 73 Dec 13, 2022
Command-line API for Atlassian JIRA using the Tomitribe CREST library

Atlassian JIRA Command-Line (CLI) Jamira is a command-line API for Atlassian JIRA using the Tomitribe CREST library. Installation Jamira can be downlo

Tomitribe 12 Sep 10, 2022
DeV Tools - Swiss Army Knife of command line utilities

dvt aims to bundle all small utilities used by developers (typically a mix of cli and online tools) into one binary that you can simply use in the console. No need for complex pipe-ing, copy-pasting on different sites or keep installing cli utilities for every need.

Madalin Ilie 13 Sep 15, 2022
AWS JSON TRANSLATOR CLI is a command line application to translate JSON files using AWS Translate

A command line tool to translate JSON files using AWS Translate.

Marc Guillem 0 May 30, 2022
Annotation-based command framework for Minestom

Minestand Annotation-based command framework for Minestom Advantages over other frameworks Minestand works by converting your classes into Minestom co

null 6 Aug 27, 2022
Wrapper around ping command for Windows and MacOS

Wrapper around ping command for Windows and MacOS. Extended with functionality to intercept results provided by the ping command output (latency, ttl and etc.)

Vladislav Kozlov 1 Jan 6, 2022
JCLR (JavaColor) is a library that allows you to write colored text in your terminal. It use the ANSI color system. Go check the README.md file to see how to use it.

JCLR JCLR (JavaColor) is a library that allows you to write colored text in your terminal. It use the ANSI color system. To start using it, go to the

Scythe 3 Aug 21, 2021
httpx is a CLI to execute requests from JetBrains Http File.

httpx: CLI for run http file httpx is a CLI to execute requests from JetBrains Http File. How to use? Create index.http file with following code, then

Libing Chen 106 Dec 29, 2022
Several implementations of a text table, originally using ASCII and UTF-8 characters for borders.

ASCII Table ASCII table - A simple tool to format tables with various row/column options for indentation, indentation character, alignment, padding (l

Sven van der Meer 415 Dec 26, 2022
Mp4grep - a CLI for transcribing and searching audio/video files

mp4grep mp4grep is a tool that transcribes and searches audio and video files for a regex pattern. mp4grep isn't just for mp4 files! It also supports

ooc 250 Dec 23, 2022
Jansi is a small java library that allows you to use ANSI escape sequences to format your console output which works even on windows.

Description Jansi is a small java library that allows you to use ANSI escape codes to format your console output which works even on Windows. It also

FuseSource 955 Dec 28, 2022
ASCII renderer in pure java with no external dependencies

Java ASCII Render ASCII renderer in pure java with no external dependencies. Java ASCII Render supports graphical primitives/elements, layers, context

David E. Veliev 140 Dec 12, 2022
JLine is a Java library for handling console input.

JLine JLine is a Java library for handling console input. It is similar in functionality to BSD editline and GNU readline but with additional features

null 1.2k Jan 5, 2023
A library for creating interactive console applications in Java

Text-IO Text-IO is a library for creating Java console applications. It can be used in applications that need to read interactive input from the user.

Beryx 295 Jan 5, 2023
Java library for creating text-based GUIs

Lanterna Lanterna is a Java library allowing you to write easy semi-graphical user interfaces in a text-only environment, very similar to the C librar

null 2k Dec 31, 2022
Dex : The Data Explorer -- A data visualization tool written in Java/Groovy/JavaFX capable of powerful ETL and publishing web visualizations.

Dex Dex : The data explorer is a powerful tool for data science. It is written in Groovy and Java on top of JavaFX and offers the ability to: Read in

Patrick Martin 1.3k Jan 8, 2023
A maven plugin to include features from jmeter-plugins.org for JMeterPluginsCMD Command Line Tool to create graphs, export csv files from jmeter result files and Filter Result tool.

jmeter-graph-tool-maven-plugin A maven plugin to create graphs using the JMeter Plugins CMDRunner from JMeter result files (*.jtl or *.csv) or using F

Vincent DABURON 6 Nov 3, 2022