Picocli Versions Save

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.

v4.5.2

3 years ago

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.

v4.5.1

3 years ago

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.

v4.5.0

3 years ago

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.

v4.4.0

3 years ago

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.

v4.3.2

4 years ago

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.

v4.3.1

4 years ago

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.

v4.3.0

4 years ago

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>'

v4.2.0

4 years ago

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.

v4.1.4

4 years ago

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.

v4.1.3

4 years ago

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.