Picocli 3.9.0
The picocli community is pleased to announce picocli 3.9.0.
This release contains bugfixes and enhancements in the main picocli module, and adds a new module: picocli-shell-jline3
.
The new module Picocli Shell JLine3 (picocli-shell-jline3
) contains components and documentation for building
interactive shell command line applications with JLine 3 and picocli.
This release contains API enhancements to allow customization of the usage help message:
- help section renderers can be added, replaced or removed
- help section keys to reorder sections in the usage help message
- help factory to create custom
Help
instances - option order attribute to reorder options in the usage help message option list
This release also has improved heuristics to decide whether ANSI escape codes should be emitted or not.
The simplified @-file (argument file) format is now fully compatible with JCommander: empty lines are ignored and comments may start with leading whitespace.
The picocli.Autocompletion
application now accepts a parameter specifying a custom factory, and returns a non-zero exit code on error, to facilitate incorporating it into the build.
Bug fixes in this release:
@Command
method options and positional parameter values are now cleared correctly when reusing aCommandLine
instance- the default exception handler now correctly respects the exit code for all exceptions
Finally, this release improves internal quality and robustness by increasing the test code coverage. About 300 tests were added to bring the total to 1300+ tests. This improved line coverage to 98% (was 88%) and complexity coverage to 98% (was 82%).
This is the forty-fifth public release.
Picocli follows semantic versioning.
Table of Contents
- New and noteworthy
- Fixed issues
- Deprecations
- Potential breaking changes
New and Noteworthy
Help Section Renderer API
This release introduces new API to facilitate customizing the usage help message: IHelpFactory
allows applications to plug in Help
subclasses, and IHelpSectionRenderer
allows applications to add custom sections to the usage help message, or redefine existing sections.
The usage help message is no longer hard-coded, but is now constructed from the section renderers defined in CommandLine::getHelpSectionMap
(or UsageMessageSpec::sectionMap
for a single CommandSpec
).
By default this map contains the predefined section renderers:
// The default section renderers delegate to methods in Help for their implementation
// (using Java 8 lambda notation for brevity):
Map<String, IHelpSectionRenderer> map = new HashMap<>();
map.put(SECTION_KEY_HEADER_HEADING, help -> help.headerHeading());
map.put(SECTION_KEY_HEADER, help -> help.header());
//e.g. Usage:
map.put(SECTION_KEY_SYNOPSIS_HEADING, help -> help.synopsisHeading());
//e.g. <cmd> [OPTIONS] <subcmd> [COMMAND-OPTIONS] [ARGUMENTS]
map.put(SECTION_KEY_SYNOPSIS, help -> help.synopsis(help.synopsisHeadingLength()));
//e.g. %nDescription:%n%n
map.put(SECTION_KEY_DESCRIPTION_HEADING, help -> help.descriptionHeading());
//e.g. {"Converts foos to bars.", "Use options to control conversion mode."}
map.put(SECTION_KEY_DESCRIPTION, help -> help.description());
//e.g. %nPositional parameters:%n%n
map.put(SECTION_KEY_PARAMETER_LIST_HEADING, help -> help.parameterListHeading());
//e.g. [FILE...] the files to convert
map.put(SECTION_KEY_PARAMETER_LIST, help -> help.parameterList());
//e.g. %nOptions:%n%n
map.put(SECTION_KEY_OPTION_LIST_HEADING, help -> help.optionListHeading());
//e.g. -h, --help displays this help and exits
map.put(SECTION_KEY_OPTION_LIST, help -> help.optionList());
//e.g. %nCommands:%n%n
map.put(SECTION_KEY_COMMAND_LIST_HEADING, help -> help.commandListHeading());
//e.g. add adds the frup to the frooble
map.put(SECTION_KEY_COMMAND_LIST, help -> help.commandList());
map.put(SECTION_KEY_FOOTER_HEADING, help -> help.footerHeading());
map.put(SECTION_KEY_FOOTER, help -> help.footer());
Applications can add, remove or replace sections in this map. The CommandLine::getHelpSectionKeys
method (or UsageMessageSpec::sectionKeys
for a single CommandSpec
) returns the section keys in the order that the usage help message should render the sections. The default keys are (in order):
- SECTION_KEY_HEADER_HEADING
- SECTION_KEY_HEADER
- SECTION_KEY_SYNOPSIS_HEADING
- SECTION_KEY_SYNOPSIS
- SECTION_KEY_DESCRIPTION_HEADING
- SECTION_KEY_DESCRIPTION
- SECTION_KEY_PARAMETER_LIST_HEADING
- SECTION_KEY_PARAMETER_LIST
- SECTION_KEY_OPTION_LIST_HEADING
- SECTION_KEY_OPTION_LIST
- SECTION_KEY_COMMAND_LIST_HEADING
- SECTION_KEY_COMMAND_LIST
- SECTION_KEY_FOOTER_HEADING
- SECTION_KEY_FOOTER
This ordering may be modified with the CommandLine::setHelpSectionKeys
setter method (or UsageMessageSpec::sectionKeys(List)
for a single CommandSpec
).
Option order
Attribute
Options are sorted alphabetically by default, but this can be switched off by specifying @Command(sortOptions = false)
on the command declaration. This displays options in the order they are declared.
However, when mixing @Option
methods and @Option
fields, options do not reliably appear in declaration order.
The @Option(order = <int>)
attribute can be used to explicitly control the position in the usage help message at which the option should be shown. Options with a lower number are shown before options with a higher number.
New Module picocli-shell-jline3
Picocli Shell JLine3 contains components and documentation for building interactive shell command line applications with JLine 3 and picocli.
This release contains the picocli.shell.jline3.PicocliJLineCompleter
class.
PicocliJLineCompleter
is a small component that generates completion candidates to allow users to get command line TAB auto-completion for a picocli-based application running in a JLine 3 shell.
It is similar to the class with the same name in the picocli.shell.jline2
package in the picocli-shell-jline2
module.
See the module's README for more details.
Improved ANSI Heuristics
This release has improved heuristics to decide whether ANSI escape codes should be emitted or not.
Support was added for the following environment variables to control enabling ANSI:
Fixed issues
- [#574] Add
picocli-shell-jline3
module. Thanks to mattirn for the pull request. - [#587] Enhance
picocli-shell-jline3
example by using JLine'sDefaultParser
to split lines into arguments. Thanks to mattirn for the pull request. - [#567] Usage message customization API initial implementation. Thanks to Christian Helmer for the pull request.
- [#530] Added API for easily customizing the usage help message. Thanks to stechio for raising the request and productive discussions.
- [#569] Facilitate customization of the synopsis: split
Help.detailedSynopsis()
into protected methods. - [#508] Annotation API: added
@Option(order = <int>)
attribute to allow explicit control of option ordering in the usage help message; useful when mixing methods and fields with@Option
annotation. - [#588] Added method
CommandSpec.names
returning bothname
andaliases
. - [#578] Add API for simplified @files argument files.
- [#573] Make simplified @files JCommander-compatible: ignore empty lines and comments starting with whitespace. Thanks to Lukáš Petrovický for the pull request with test to reproduce the issue.
- [#572]
CommandSpec.addMethodSubcommands
now throwspicocli.CommandLine.InitializationException
instead ofjava.lang.UnsupportedOperationException
when the user object of the parent command is ajava.lang.reflect.Method
. - [#581] Added support for ConEmu, ANSICON and other environment variables to improve the ANSI heuristics. Documented the heuristics in the user manual.
- [#579] Improved
AutoComplete
error message when not overwriting existing files. - [#585]
picocli.AutoComplete
now accepts a parameter specifying a customIFactory
implementation. Thanks to Bob Tiernay for the suggestion. - [#582]
picocli.AutoComplete
now returns a non-zero return code on error. Thanks to Bob Tiernay for the suggestion. - [#570] Bugfix: Command method options and positional parameter Object values are now cleared correctly when reusing CommandLine. Thanks to Christian Helmer for the pull request.
- [#576] Bugfix: fixed StringIndexOutOfBoundsException in shell-jline2 completion when cursor was before
=
when option parameter was attached to option name. - [#583] Bugfix: Default exception handler now exits on exception if exitCode was set, regardless of exception type.
- [#584] Add documentation for generating autocompletion script during a Maven build. Thanks to Bob Tiernay.
- [#586] Replace Ansi.Text.clone() with copy constructor.
- [#571] Improve test code coverage. Added ~300 tests to bring the total to 1300+ tests. Improved line coverage to 98% (was 88%) and complexity coverage to 98% (was 82%).
- [#590] Fail the build if test coverage falls below minimum threshold.
- [#589] Fix index.adoc to eliminate warnings; suppress javadoc warnings.
- [#566] Add example showing how to customize the usage help message to show the full command tree including nested subcommands. Thanks to lgawron for the request.
Deprecations
No features were deprecated in this release.
Potential breaking changes
CommandSpec.addMethodSubcommands
now throws InitializationException
instead of java.lang.UnsupportedOperationException
when the user object of the parent command is a java.lang.reflect.Method
.
AutoComplete application now prints different error message when not overwriting existing script files. This may break tests that verify the console output.