@remkop remkop released this Jan 5, 2019 · 41 commits to master since this release

Assets 7

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 a CommandLine 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

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):

  1. SECTION_KEY_HEADER_HEADING
  2. SECTION_KEY_HEADER
  3. SECTION_KEY_SYNOPSIS_HEADING
  4. SECTION_KEY_SYNOPSIS
  5. SECTION_KEY_DESCRIPTION_HEADING
  6. SECTION_KEY_DESCRIPTION
  7. SECTION_KEY_PARAMETER_LIST_HEADING
  8. SECTION_KEY_PARAMETER_LIST
  9. SECTION_KEY_OPTION_LIST_HEADING
  10. SECTION_KEY_OPTION_LIST
  11. SECTION_KEY_COMMAND_LIST_HEADING
  12. SECTION_KEY_COMMAND_LIST
  13. SECTION_KEY_FOOTER_HEADING
  14. 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's DefaultParser 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 both name and aliases.
  • [#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 throws picocli.CommandLine.InitializationException instead of java.lang.UnsupportedOperationException when the user object of the parent command is a java.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 custom IFactory 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.