github remkop/picocli v4.0.0-beta-2
Picocli 4.0.0-beta-2

latest releases: v4.7.6, v4.7.5, v4.7.4...
5 years ago

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
  • Fixed issues
  • Deprecations
  • Potential breaking changes

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.

Don't miss a new picocli release

NewReleases is sending notifications on new releases.