Skip to content

Releases: remkop/picocli

picocli 3.0.0-alpha-5

10 Apr 18:30
Compare
Choose a tag to compare

Picocli 3.0.0-alpha-5

The picocli community is pleased to announce picocli 3.0.0-alpha-5.

This release contains enhancements and bug fixes.

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

Table of Contents

New and Noteworthy

Promoted Features

Promoted features are features that were incubating in previous versions of picocli but are now supported and subject to backwards compatibility.

No features have been promoted in this picocli release.

Fixed issues

  • [#329] New API: Add parser configuration to control whether boolean flags should be toggled.
  • [#328] New API: Provide getter methods on OptionSpec.Builder and PositionalParamSpec.Builder.
  • [#326] New API: Add parser configuration to treat unmatched options as positional parameters.
  • [#283] New API: Provide getMissing method on MissingParameterException to get a reference to the problematic options and positional parameters. Thanks to jcapsule for the suggestion.
  • [#334] API Change: Rename ArgSpec.rawStringValues() to ArgSpec.stringValues().
  • [#342] API Change: Prefix ParseResult methods with matched if they return only matched options/positionals.
  • [#340] API Change: Rename ParseResult.optionValue(String, T) to matchedOptionValue(String, T).
  • [#338] API Change: Remove ParseResult.rawOptionValue(s) and rawPositionalValue(s) methods.
  • [#339] API Change: Remove ParseResult.matchedOptionValue(OptionSpec) and matchedPositionalValue(PositionalParamSpec) methods.
  • [#347] API Change: Make ArgSpec.getValue, setValue and isMultiValue public methods.
  • [#333] Enhancement: Added subcommand to synopsis in generated usage help. Thanks to jcapsule for the pull request.
  • [#323] Enhancement: Remove dependency on java.sql package: picocli should only require the java.base module when running in Java 9.
  • [#325] Enhancement: Allow custom type converter to map empty String to custom default value for empty options. Thanks to jesselong for the suggestion.
  • [#303] Enhancement: Improve validation to prevent common mistakes.
  • [#70] Enhancement: Positional parameters should only consume values where type conversion succeeds.
  • [#346] Enhancement: Validate that arity min is never greater than max.
  • [#348] Enhancement: Interpreter should call ArgSpec.setValue for every matched option or positional parameter.
  • [#327] Bugfix: Default values should not cause options and positional parameters to be added to ParseResult.
  • [#330] Bugfix: Interpreter should clear option's and positional parameter's stringValues list before parsing new input.
  • [#335] Bugfix: Abstract class ArgSpec should not implement equals and hashCode.
  • [#345] Bugfix: Stop processing varargs when cumulative size reached.

Deprecations

See 3.0.0-alpha-1

Potential breaking changes

  • Renamed ArgSpec.rawStringValues() to ArgSpec.stringValues().
  • Renamed ParseResult methods with matched if they return only matched options/positionals:
    • options to matchedOptions
    • positionalParams to matchedPositionals
    • option(char), option(String) to matchedOption
    • positional(int) to matchedPositional
    • hasOption(char), hasOption(String), hasOption(OptionSpec) to hasMatchedOption
    • hasPositional(int), hasPositional(PositionalParamSpec) to hasMatchedPositional
  • Renamed ParseResult.optionValue(String, T) to matchedOptionValue(String, T), and positionalValue to matchedPositionalValue.
  • Removed ParseResult::rawOptionValue(s) and rawPositionalValue(s) methods.
  • Removed ParseResult.matchedOptionValue(OptionSpec) and matchedPositionalValue(PositionalParamSpec) methods.

See also breaking changes for
3.0.0-alpha-4, 3.0.0-alpha-3, 3.0.0-alpha-2, and 3.0.0-alpha-1.

picocli 3.0.0-alpha-4

03 Apr 11:55
Compare
Choose a tag to compare

Picocli 3.0.0-alpha-4

The picocli community is pleased to announce picocli 3.0.0-alpha-4.

This release contains bug fixes and enhancements.

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

Table of Contents

New and Noteworthy

Promoted Features

Promoted features are features that were incubating in previous versions of picocli but are now supported and subject to backwards compatibility.

No features have been promoted in this picocli release.

Fixed issues

[#318] API Change: Split model IBinding into IGetter and ISetter.
[#320] API Change: Rename parser config maxArityIsMaxTotalParams to arityRestrictsCumulativeSize.
[#216] Enhancement: Parsed values now replace the default value of multi-value (array, Collection or Map) options and positional parameters instead of being appended to them. Thanks to wiwie for the request.
[#261] Enhancement: Options and positional parameters with a defaultValue are never required. Thanks to ymenager for the request.
[#315] Enhancement: Initialize ArgSpec value with defaultValue before parsing command line.
[#263] Bugfix: positional parameter defaults were not shown in usage help message. Thanks to ymenager for the bug report.

Deprecations

See 3.0.0-alpha-1

Potential breaking changes

  • Parsed values now replace the default value of multi-value (array, Collection or Map) options and positional parameters instead of being appended to them.
  • The IBinding interface introduced in v3.0.0-alpha-1 has been replaced with two functional interfaces IGetter and ISetter.
  • The UnmatchedArgsBinding factory methods introduced in v3.0.0-alpha-1 have been replaced with forStringArrayConsumer and forStringCollectionSupplier.

See also breaking changes for 3.0.0-alpha-3, 3.0.0-alpha-2, and 3.0.0-alpha-1.

picocli 3.0.0-alpha-3

31 Mar 02:19
Compare
Choose a tag to compare

Picocli 3.0.0-alpha-3

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

This release includes changes to allow picocli to be configured to function like Apache Commons CLI, to support GROOVY-8520:

  • maxArityIsMaxTotalParams parser configuration option to use arity to limit the total number of values accumulated in an option or positional parameter.
  • Usage message width can now be configured programmatically.
  • "Lenient" mode when extracting annotations from a class where picocli annotations are optional (to allow mixing Groovy CLI annotations in Groovy CliBuilder).
  • Change semantics of ParseResult.rawOptionValue to mean values after split (but before type conversion).

See 3.0.0-alpha-1 and 3.0.0-alpha-2 for recent functional changes.

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

Table of Contents

New and Noteworthy

Max Arity Is Max Total Params

This release introduces a maxArityIsMaxTotalParams parser configuration option.

By default, the arity of an option is the number of arguments for each occurrence of the option.
For example, if option -a has arity = "2", then the following is a perfectly valid command:
for each occurrence of the option, two option parameters are specified.

<command> -a 1 2 -a 3 4 -a 5 6

However, if CommandLine.setMaxArityIsMaxTotalParams(true) is called first, the above example would result in a MaxValuesExceededException because the total number of values (6) exceeds the arity of 2.

Additionally, by default, when maxArityIsMaxTotalParams is false, arity is only applied before the argument is split into parts,
while when maxArityIsMaxTotalParams is set to true, validation is applied after a command line argument has been split into parts.

For example, if we have an option like this:

@Option(name = "-a", arity = "1..2", split = ",") String[] values;

By default, the following input would be a valid command:

<command> -a 1,2,3

By default, the option arity tells the parser to consume 1 to 2 arguments, and the option was followed by a single parameter, "1,2,3", which is fine.

However, if maxArityIsMaxTotalParams is set to true, the above example would result in a MaxValuesExceededException because the argument is split into 3 parts, which exceeds the max arity of 2.

Promoted Features

Promoted features are features that were incubating in previous versions of picocli but are now supported and subject to backwards compatibility.

No features have been promoted in this picocli release.

Fixed issues

  • [#313] Enhancement and API Change: add method CommandLine::setMaxArityIsMaxTotalParams to configure the parser to use arity to limit the total number of values accumulated in an option or positional parameter.
  • [#314] Enhancement and API Change: add method CommandLine::setUsageHelpWidth and UsageMessageSpec::width to set the max usage help message width.
  • [#316] Enhancement: Support lenient mode where annotations are optional when extracting annotations.
  • [#317] Enhancement: Change semantics of ParseResult.rawOptionValue to mean values after split (but before type conversion).

Deprecations

See 3.0.0-alpha-1

Potential breaking changes

  • Utility method CommandLine.Help.join signature changed: now takes an additional usageHelpWidth parameter.
  • Constructor CommandLine.Help.Layout(ColorScheme) signature changed: now takes an additional usageHelpWidth parameter.
  • Public field CommandLine.Help.TextTable.columns is now private; added public method CommandLine.Help.TextTable.columns().
  • Constructor CommandLine.Help.TextTable(Ansi) is replaced with factory method CommandLine.Help.TextTable.forDefaultColumns(Ansi, int).
  • Constructor CommandLine.Help.TextTable(Ansi, int...) is replaced with factory method CommandLine.Help.TextTable.forColumnWidths(Ansi, int...).
  • Constructor CommandLine.Help.TextTable(Ansi, Column...) modifier changed from public to protected.
  • Added factory method CommandLine.Help.TextTable.forColumns(Ansi, Column...).
  • Renamed CommandLine.MaxValuesforFieldExceededException to CommandLine.MaxValuesExceededException.

See 3.0.0-alpha-2.
See 3.0.0-alpha-1.

picocli 3.0.0-alpha-2

27 Mar 12:58
Compare
Choose a tag to compare

Picocli 3.0.0-alpha-2

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

This release includes some bug fixes and small enhancements. See 3.0.0-alpha-1 for recent functional changes.

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

Fixed issues

  • [#312] Enhancement and API change: Remove AbstractSimpleParseResultHandler class and parseWithSimpleHandlers method.
  • [#311] Enhancement and API change: Simplify parseWithHandlers: removed prototypeReturnValue parameter.
  • [#307] Enhancement: Provide CommandLine.usage(PrintWriter) method for testing and to facilitate GROOVY-8520 migration from commons-cli to picocli.
  • [#306] Enhancement: Support generating autocompletion scripts for non-public @command classes. Thanks to cbeams for the request.
  • [#308] Enhancement: Provide API to disallow POSIX clustered short options.
  • [#310] Enhancement: PicocliBaseScript should follow conventions for stdout and stderr: requested help to stdout, invalid input usage help to stderr.
  • [#309] Bugfix: Tests were failing on environments that support ANSI colors.

Deprecations

See 3.0.0-alpha-1

Potential breaking changes

  • [#311] API change from 3.0.0-alpha-1: the parseWithHandlers methods signature changed: removed the prototypeReturnValue parameter.
  • [#312] API change from 3.0.0-alpha-1: Remove AbstractSimpleParseResultHandler class and parseWithSimpleHandlers method.

See 3.0.0-alpha-1

picocli 3.0.0-alpha-1

20 Mar 16:57
Compare
Choose a tag to compare

Picocli 3.0.0-alpha-1

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

This release offers a programmatic API for creating command line applications, in addition to annotations. The programmatic API allows applications to dynamically create command line options on the fly, and also makes it possible to create idiomatic domain-specific languages for processing command line arguments, using picocli, in other JVM languages.

Another new feature in this release are Mixins. Mixins allow reusing common options, parameters and command attributes in multiple applications without copy-and-paste duplication.

Third, this release aims to reduce boilerplate code in user applications even further with the new mixinStandardHelpOptions command attribute. Picocli adds standard usageHelp and versionHelp options to commands with this attribute. Additionally picocli now offers a HelpCommand that can be installed as a subcommand on any application command to provide usage help for the parent command or sibling subcommands.

From this release, picocli is better at following unix conventions: print to stdout when the user requested help, and print to stderr when the input was invalid or an unexpected error occurred.

Also, this release gives better control over the process exit code.

Additionally, fields annotated with @Unmatched will be populated with the unmatched arguments.

Furthermore, this release adds a showDefaultValue attribute to the @Option and @Parameters annotation.

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

Table of Contents

New and Noteworthy

Programmatic API (INCUBATING)

This release offers a programmatic API for creating command line applications, in addition to annotations. The programmatic API allows applications to dynamically create command line options on the fly, and also makes it possible to create idiomatic domain-specific languages for processing command line arguments, using picocli, in other JVM languages.

Note that the programmatic API is incubating and the API may change in subsequent releases. If you have suggestions for improving the programmatic API, please raise a ticket on GitHub!

Example

CommandSpec spec = CommandSpec.create();
spec.mixinStandardHelpOptions(true); // usageHelp and versionHelp options
spec.addOption(OptionSpec.builder("-c", "--count")
        .paramLabel("COUNT")
        .type(int.class)
        .description("number of times to execute").build());
spec.addPositional(PositionalParamSpec.builder()
        .paramLabel("FILES")
        .type(List.class)
        .auxiliaryTypes(File.class) // List<File>
        .description("The files to process").build());
CommandLine commandLine = new CommandLine(spec);

commandLine.parseWithSimpleHandlers(new AbstractSimpleParseResultHandler() {
    public void handle(ParseResult pr) {
        int count = pr.optionValue('c', 1);
        List<File> files = pr.positionalValue(0, Collections.<File>emptyList());
        for (int i = 0; i < count; i++) {
            for (File f : files) {
                System.out.printf("%d: %s%n", i, f);
            }
        }
    }
}, args);

CommandSpec (INCUBATING)

CommandSpec models a command. It is the programmatic variant of the @Command annotation. It has a name and a version, both of which may be empty. It also has a UsageMessageSpec to configure aspects of the usage help message and a ParserSpec that can be used to control the behaviour of the parser.

OptionSpec and PositionalParamSpec (INCUBATING)

OptionSpec models a named option, and PositionalParamSpec models one or more positional parameters. They are the programmatic variant of the @Option and @Parameters annotations, respectively.

An OptionSpec must have at least one name, which is used during parsing to match command line arguments. Other attributes can be left empty and picocli will give them a reasonable default value. This defaulting is why OptionSpec objects are created with a builder: this allows you to specify only some attributes and let picocli initialise the other attributes. For example, if only the option’s name is specified, picocli assumes the option takes no parameters (arity = 0), and is of type boolean. Another example, if arity is larger than 1, picocli sets the type to List and the auxiliary type to String.

PositionalParamSpec objects don’t have names, but have an index range instead. A single PositionalParamSpec object can capture multiple positional parameters. The default index range is set to 0..* (all indices). A command may have multiple PositionalParamSpec objects to capture positional parameters at different index ranges. This can be useful if positional parameters at different index ranges have different data types.

Similar to OptionSpec objects, Once a PositionalParamSpec is constructed, its configuration becomes immutable, but its value can still be modified. Usually the value is set during command line parsing when a non-option command line argument is encountered at a position in its index range.

ParseResult (INCUBATING)

A ParseResult class is now available that allows applications to inspect the result of parsing a sequence of command line arguments.

This class provides methods to query whether the command line arguments included certain options or position parameters, and what the value or values of these options and positional parameters was. Both the original command line argument String value as well as a strongly typed value can be obtained.

Mixins for Reuse

Mixins are a convenient alternative to subclassing: picocli annotations from any class can be added to ("mixed in" with) another command. This includes options, positional parameters, subcommands and command attributes. Picocli autoHelp internally uses a mixin.

A mixin is a separate class with options, positional parameters, subcommands and command attributes that can be reused in other commands. Mixins can be installed by calling the CommandLine.addMixin method with an object of this class, or annotating a field in your command with @Mixin. Here is an example mixin class:

public class ReusableOptions {

    @Option(names = { "-v", "--verbose" }, description = {
        "Specify multiple -v options to increase verbosity.", "For example, `-v -v -v` or `-vvv`" })
    protected boolean[] verbosity = new boolean[0];
}

Adding Mixins Programmatically

The below example shows how a mixin can be added programmatically with the CommandLine.addMixin method.

CommandLine commandLine = new CommandLine(new MyCommand());
commandline.addMixin("myMixin", new ReusableOptions());

@Mixin Annotation

A command can also include mixins by annotating fields with @Mixin. All picocli annotations found in the mixin class
are added to the command that has a field annotated with @Mixin. For example:

@Command(name = "zip", description = "Example reuse with @Mixin annotation.")
public class MyCommand {

    // adds the options defined in ReusableOptions to this command
    @Mixin
    private ReusableOptions myMixin;
}

Standard Help Options

This release introduces the mixinStandardHelpOptions command attribute. When this attribute is set to true, picocli adds a mixin to the command that adds usageHelp and versionHelp options to the command. For example:

@Command(mixinStandardHelpOptions = true, version = "auto help demo - picocli 3.0")
class AutoHelpDemo implements Runnable {

    @Option(names = "--option", description = "Some option.")
    String option;

    @Override public void run() { }
}

Commands with mixinStandardHelpOptions do not need to explicitly declare fields annotated with @Option(usageHelp = true) and @Option(versionHelp = true) any more. The usage help message for the above example looks like this:

Usage: <main class> [-hV] [--option=<option>]
      --option=<option>       Some option.
  -h, --help                  Show this help message and exit.
  -V, --version               Print version information and exit.

Help Command

From this release, picocli provides a help subcommand (picocli.CommandLine.HelpCommand) that can be installed as a subcommand on any application command to provide usage help for the parent command or sibling subcommands. For example:

@Command(subcommands = HelpCommand.class)
class AutoHelpDemo implements Runnable {

    @Option(names = "--option", description = "Some option.")
    String option;

    @Override public void run() { }
}
# print help for the `maincommand` command
maincommand help

# print help for the `subcommand` command
maincommand help subcommand

For applications that want to create a custom help command, this release also introduces a new interface picocli.CommandLine.IHelpCommandInitializable that provides custom help commands with the information they need: access to the parent command and sibling commands, whether to use Ansi colors or not, and the streams to print the usage help message to.

@Unmatched Annotation

From this release, fields annot...

Read more

picocli 2.3.0

13 Feb 11:13
Compare
Choose a tag to compare

Picocli 2.3.0

The picocli community is pleased to announce picocli 2.3.0.

This release contains bugfixes and new features.

This release introduces a new parser flag stopAtPositional to treat the first positional parameter as end-of-options, and a stopAtUnmatched parser flag to stop matching options and positional parameters as soon as an unmatched argument is encountered.

These flags are useful for applications that need to delegate part of the command line to third party commands.

This release offers better support for options with optional values, allowing applications to distinguish between cases where the option was not specified at all, and cases where the option was specified without a value.

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

Table of Contents

New and noteworthy

Stop At Positional

By default, positional parameters can be mixed with options on the command line, but this is not always desirable. From this release, applications can call CommandLine.setStopAtPositional(true) to force the parser to treat all values following the first positional parameter as positional parameters.

When this flag is set, the first positional parameter effectively serves as an "end of options" marker, without requiring a separate -- argument.

Stop At Unmatched

From this release, applications can call CommandLine.setStopAtUnmatched(true) to force the parser to stop interpreting options and positional parameters as soon as it encounters an unmatched argument.

When this flag is set, the first unmatched argument and all subsequent command line arguments are added to the unmatched arguments list returned by CommandLine.getUnmatchedArguments().

Optional Values

If an option is defined with arity = "0..1", it may or not have a parameter value. If such an option is specified without a value on the command line, it is assigned an empty String. If the option is not specified, it keeps its default value. For example:

class OptionalValueDemo implements Runnable {
    @Option(names = "-x", arity = "0..1", description = "optional parameter")
    String x;

    public void run() { System.out.printf("x = '%s'%n", x); }

    public static void main(String... args) {
       CommandLine.run(new OptionalValueDemo(), System.out, args);
    }
}

Gives the following results:

java OptionalValueDemo -x value
x = 'value'

java OptionalValueDemo -x
x = ''

java OptionalValueDemo
x = 'null'

Promoted features

Promoted features are features that were incubating in previous versions of picocli but are now supported and subject to backwards compatibility.

No features have been promoted in this picocli release.

Fixed issues

  • [#215] API: stopAtUnmatched flag to stop parsing on first unmatched argument. Thanks to defnull for the request.
  • [#284] API: stopAtPositional flag to treat first positional parameter as end-of-options. Thanks to defnull and pditommaso for the request.
  • [#279] Enhancement: assign empty String when String option was specified without value. Thanks to pditommaso for the request.
  • [#285] Bugfix: Vararg positional parameters should not consume options. Thanks to pditommaso for the bug report.
  • [#286] Documentation: clarify when picocli instantiates fields for options and positional parameters. Thanks to JanMosigItemis for pointing this out.

Deprecations

This release has no additional deprecations.

Potential breaking changes

This release has no breaking changes.

picocli 2.2.2

07 Feb 14:27
Compare
Choose a tag to compare

Picocli 2.2.2

The picocli community is pleased to announce picocli 2.2.2.

This is a bugfix release.

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

Table of Contents

New and noteworthy

This is a bugfix release and does not include any new features.

Promoted features

Promoted features are features that were incubating in previous versions of picocli but are now supported and subject to backwards compatibility.

No features have been promoted in this picocli release.

Fixed issues

  • [#282] Bugfix: unmatched option heuristic did not work when there were no options to compare against. Thanks to jcapsule.

Deprecations

This release has no additional deprecations.

Potential breaking changes

This release has no breaking changes.

picocli 2.2.1

02 Jan 18:00
Compare
Choose a tag to compare

Picocli 2.2.1

The picocli community is pleased to announce picocli 2.2.1.

This is a bugfix release.

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

Table of Contents

New and noteworthy

This is a bugfix release and does not include any new features.

Promoted features

Promoted features are features that were incubating in previous versions of picocli but are now supported and subject to backwards compatibility.

No features have been promoted in this picocli release.

Fixed issues

  • [#254] Bugfix: Starting from 2.0.3, usage help didn't render empty lines in multi-line descriptions.
  • [#255] Documentation: Update Kotlin example in user manual for the new Kotlin 1.2 array literal syntax in annotations.

Deprecations

This release has no additional deprecations.

Potential breaking changes

This release has no breaking changes.

picocli 2.2.0

21 Dec 12:24
Compare
Choose a tag to compare

Picocli 2.2.0

The picocli community is pleased to announce picocli 2.2.

This release is a "Project Coin"-like release for picocli: small changes that add a lot of value.

In command line applications with subcommands, options of the parent command are often intended as "global" options that apply to all the subcommands. This release introduces a new @ParentCommand annotation that makes it easy for subcommands to access such parent command options: fields of the subcommand annotated with @ParentCommand are initialized with a reference to the parent command.

This release adds support for more built-in types, so applications don't need to register custom converters for common types. The new types include Java 7 classes like java.nio.file.Path and Java 8 classes like the value classes in the java.time package. These converters are loaded using reflection and are not available when running on Java 5 or Java 6.

This release also adds a converter attribute to the @Option and @Parameter annotations. This allows a specific option or positional parameter to use a different converter than would be used by default based on the type of the field.

Furthermore, the @Command annotation now supports a versionProvider attribute. This is useful when the version of an application should be detected dynamically at runtime. For example, an implementation may return version information obtained from the JAR manifest, a properties file or some other source.

Finally, applications may now specify a custom factory for instantiating classes that were configured as annotation attributes, like subcommands, type converters and version providers.

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

Table of Contents

New and noteworthy

New @ParentCommand annotation

In command line applications with subcommands, options of the top level command are often intended as "global" options that apply to all the subcommands. Prior to this release, subcommands had no easy way to access their parent command options unless the parent command made these values available in a global variable.

The @ParentCommand annotation makes it easy for subcommands to access their parent command options: subcommand fields annotated with @ParentCommand are initialized with a reference to the parent command. For example:

@Command(name = "fileutils", subcommands = List.class)
class FileUtils {

    @Option(names = {"-d", "--directory"},
            description = "this option applies to all subcommands")
    File baseDirectory;
}

@Command(name = "list")
class List implements Runnable {

    @ParentCommand
    private FileUtils parent; // picocli injects reference to parent command

    @Option(names = {"-r", "--recursive"}, 
            description = "Recursively list subdirectories")
    private boolean recursive;

    @Override
    public void run() {
        list(new File(parent.baseDirectory, "."));
    }

    private void list(File dir) {
        System.out.println(dir.getAbsolutePath());
        if (dir.isDirectory()) {
            for (File f : dir.listFiles()) {
                System.out.println(f.getAbsolutePath());
                if (f.isDirectory() && recursive) {
                    list(f);
                }
            }
        }
    }
}

More built-in types

This release adds support for more built-in types, so applications don't need to register custom converters for common types. The new types include Java 7 classes like java.nio.file.Path and Java 8 classes like the value classes in the java.time package. These converters are loaded using reflection and are not available when running on Java 5 or Java 6.

Converters for the following types were added in this release:

  • java.nio.file.Path (requires Java 7 or higher)
  • java.time value objects: Duration, Instant, LocalDate, LocalDateTime, LocalTime, MonthDay, OffsetDateTime, OffsetTime, Period, Year, YearMonth, ZonedDateTime, ZoneId, ZoneOffset (requires Java 8 or higher, invokes the parse method of these classes)
  • java.lang.Class (for the fully qualified class name)
  • java.nio.ByteOrder (for the Strings "BIG_ENDIAN" or "LITTLE_ENDIAN")
  • java.util.Currency (for the ISO 4217 code of the currency)
  • java.net.NetworkInterface (for the InetAddress or name of the network interface)
  • java.util.TimeZoneConverter (for the ID for a TimeZone)
  • java.sql.Connection (for a database url of the form jdbc:subprotocol:subname)
  • java.sql.Driver (for a database URL of the form jdbc:subprotocol:subname)
  • java.sql.Timestamp (for values in the "yyyy-MM-dd HH:mm:ss" or "yyyy-MM-dd HH:mm:ss.fffffffff" formats)

Option-specific Type Converters

This release adds a converter attribute to the @Option and @Parameter annotations. This allows a specific option or positional parameter to use a different converter than would be used by default based on the type of the field.

For example, you may want to convert the constant names defined in java.sql.Types to their int value for a specific field, but this should not impact any other int fields: other int fields should continue to use the default int converter that parses numeric values.

Example usage:

class App {
    @Option(names = "--sqlType", converter = SqlTypeConverter.class)
    int sqlType;
}

Example implementation:

class SqlTypeConverter implements ITypeConverter<Integer> {
    public Integer convert(String value) throws Exception {
        switch (value) {
            case "ARRAY"  : return Types.ARRAY;
            case "BIGINT" : return Types.BIGINT;
            case "BINARY" : return Types.BINARY;
            case "BIT"    : return Types.BIT;
            case "BLOB"   : return Types.BLOB;
            ...
        }
    }
}

Dynamic Version Information

From this release, the @Command annotation supports a versionProvider attribute. Applications may specify a IVersionProvider implementation in this attribute, and picocli will instantiate this class
and invoke it to collect version information.

This is useful when the version of an application should be detected dynamically at runtime. For example, an implementation may return version information obtained from the JAR manifest, a properties file or some other source.

Custom version providers need to implement the picocli.CommandLine.IVersionProvider interface:

public interface IVersionProvider {
    /**
     * Returns version information for a command.
     * @return version information (each string in the array is displayed on a separate line)
     * @throws Exception an exception detailing what went wrong when obtaining version information
     */
    String[] getVersion() throws Exception;
}

The GitHub project has a manifest file-based example and a build-generated version properties file-based example version provider implementation.

Custom factory

Declaratively registered subcommands, type converters and version providers must be instantiated somehow. From this release, a custom factory can be specified when constructing a CommandLine instance. This allows full control over object creation and opens possibilities for Inversion of Control and Dependency Injection. For example:

IFactory myFactory = getCustomFactory();
CommandLine cmdLine = new CommandLine(new Git(), myFactory);

Promoted features

Promoted features are features that were incubating in previous versions of picocli but are now supported and subject to backwards compatibility.

No features have been promoted in this picocli release.

Fixed issues

  • [#247] New @ParentCommand annotation to inject a reference to the parent command into subcommand fields. Thanks to michaelpj for the request.
  • [#83] Add more built-in converters. Thanks to garydgregory for the inspiration.
  • [#237] Option and Positional Parameter-specific type converters. Thanks to godzsa for the request.
  • [#236] Allow obtaining version information dynamically at runtime. Thanks to kcris for the request.
  • [#169] Configurable factory to instantiate subcommands that are registered via annotation attributes. Thanks to kakawait for the request.
  • [#252] Example version provider implementations.

Deprecations

This release has no additional deprecations.

Potential breaking changes

This release has no breaking changes.

picocli 2.1.0

29 Nov 15:40
Compare
Choose a tag to compare

Picocli 2.1.0

This release contains bugfixes and new features.

Users sometimes run into system limitations on the length of a command line when creating a command line with lots of options or with long arguments for options. Starting from this release, picocli supports "argument files" or "@-files". Argument files are files that themselves contain arguments to the command. When picocli encounters an argument beginning with the character `@', it expands the contents of that file into the argument list.

Secondly, this release adds support for multi-value boolean flags. A common use case where this is useful is to let users control the level of output verbosity by specifying more -v flags on the command line. For example, -v could give high-level output, -vv could show more detailed output, and -vvv could show debug-level information.

Finally, thanks to aadrian and RobertZenz, an examples subproject containing running examples has been added. (Your contributions are welcome!)

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

Table of Contents

New and noteworthy

Argument Files (@-files)

An argument file can include options and positional parameters in any combination. The arguments within a file can be space-separated or newline-separated. If an argument contains embedded whitespace, put the whole argument in double or single quotes ("-f=My Files\Stuff.java").

Lines starting with # are comments and are ignored. The file may itself contain additional @-file arguments; any such arguments will be processed recursively.

Multiple @-files may be specified on the command line.

For example, suppose a file with arguments exists at /home/foo/args, with these contents:

# This line is a comment and is ignored.
ABC -option=123
'X Y Z'

A command may be invoked with the @file argument, like this:

java MyCommand @/home/foo/args

The above will be expanded to the contents of the file:

java MyCommand ABC -option=123 "X Y Z"

This feature is similar to the 'Command Line Argument File' processing supported by gcc, javadoc and javac. The documentation for these tools shows further examples.

Repeated Boolean Flags

Multi-valued boolean options are now supported. For example:

@Option(names = "-v", description = { "Specify multiple -v options to increase verbosity.",
                                      "For example, `-v -v -v` or `-vvv`"})
boolean[] verbosity;

Users may specify multiple boolean flag options without parameters. For example:

<command> -v -v -v -vvv

The above example results in six true values being added to the verbosity array.

Promoted features

Promoted features are features that were incubating in previous versions of picocli but are now supported and subject to backwards compatibility.

No features have been promoted in this picocli release.

Fixed issues

  • [#126] New feature: Support expanding argument files, also called @-files.
  • [#241] New feature (enhancing [#126]): Recursively process nested @-files; allow multiple arguments per line, allow quoted arguments with embedded whitespace.
  • [#217] New feature: Support repeated boolean flag options captured in multi-valued fields.
  • [#223] New feature: Added examples subproject containing running examples. Thanks to aadrian and RobertZenz.
  • [#68] Enhancement: Reject private final primitive fields annotated with @option or @parameters: because compile-time constants are inlined, updates by picocli to such fields would not be visible to the application.
  • [#239] Enhancement: Improve error message when Exception thrown from Runnable/Callable.
  • [#240] Bugfix: RunAll handler should return empty list, not null, when help is requested.
  • [#244] Bugfix: the parser only considered help options instead of any of help, usageHelp and versionHelp to determine if missing required options can be ignored when encountering a subcommand. Thanks to mkavanagh.

Deprecations

The Range::defaultArity(Class) method is now deprecated in favour of the Range::defaultArity(Field) method introduced in v2.0.

Potential breaking changes

Private final fields that are either String or primitive types can no longer be annotated with @Option or @Parameters.
Picocli will throw an InitializationException when it detects such fields,
because compile-time constants are inlined, and updates by picocli to such fields would not be visible to the application.