Skip to content

Picocli 3.5.0

Compare
Choose a tag to compare
@remkop remkop released this 07 Aug 15:12
· 3398 commits to main since this release

Picocli 3.5.0

The picocli community is pleased to announce picocli 3.5.0.

This release contains new features, bugfixes and enhancements.

Password support: for options and positional parameters marked as interactive, the user is prompted to enter a value on the console. When running on Java 6 or higher, picocli will use the Console.readPassword API so that user input is not echoed to the console.

Client code can now perform simple validation in annotated setter methods by throwing a ParameterException on invalid input.

Also, from this release, the comment character in @-files (argument files) and the end-of-options delimiter (-- by default) are configurable.

This is the thirty-sixth public release.
Picocli follows semantic versioning.

Table of Contents

New and Noteworthy

Interactive Options for Passwords or Passphrases

This release introduces password support: for options and positional parameters marked as interactive, the user is prompted to enter a value on the console. When running on Java 6 or higher, picocli will use the Console.readPassword API so that user input is not echoed to the console.

Example usage:

class Login implements Callable<Object> {
    @Option(names = {"-u", "--user"}, description = "User name")
    String user;

    @Option(names = {"-p", "--password"}, description = "Passphrase", interactive = true)
    String password;

    public Object call() throws Exception {
        MessageDigest md = MessageDigest.getInstance("SHA-256");
        md.update(password.getBytes());
        System.out.printf("Hi %s, your passphrase is hashed to %s.%n", user, base64(md.digest()));
        return null;
    }
    
    private String base64(byte[] arr) { /* ... */ }
}

When this command is invoked like this:

CommandLine.call(new Login(), "-u", "user123", "-p");

Then the user will be prompted to enter a value:

Enter value for --password (Passphrase): 

When running on Java 6 or higher, the user input is not echoed to the console.
After the user enters a value and presses enter, the call() method is invoked, which prints the following:

Hi user123, your passphrase is hashed to 75K3eLr+dx6JJFuJ7LwIpEpOFmwGZZkRiB84PURz6U8=.

Simple Validation in Setter Methods

Methods annotated with @Option and @Parameters can do simple input validation by throwing a ParameterException when invalid values are specified on the command line.

class ValidationExample {
    @Spec private CommandSpec spec; // injected by picocli
    
    private Map<String, String> properties = new LinkedHashMap<>();
    
    @Option(names = {"-D", "--property"}, paramLabel = "KEY=VALUE")
    public void setProperty(Map<String, String> map) {
        for (String key : map.keySet()) {
            String newValue = map.get(key);
            validateUnique(key, newValue);
            properties.put(key, newValue);
        }
    }

    private void validateUnique(String key, String newValue) {
        String existing = properties.get(key);
        if (existing != null && !existing.equals(newValue)) {
            throw new ParameterException(spec.commandLine(),
                    String.format("Duplicate key '%s' for values '%s' and '%s'.",
                    key, existing, newValue));
        }
    }
}

Prior to this release, the exception thrown from the method was wrapped in a java.lang.reflect.InvocationTargetException, which in turn was wrapped in a PicocliException, and finally in another ParameterException.

By following the recipe above and throwing a ParameterException on invalid input, all these intermediate exceptions are skipped.

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

  • [#430] Bugfix: formatting was incorrect (did not break on embedded newlines) in the subcommands list descriptions. Thanks to Benny Bottema for the bug report.
  • [#431] Better support for validation in setter methods: cleaner stack trace.
  • [#432] Make comment character in @-files (argument files) configurable.
  • [#359] Make end-of-options delimiter configurable.
  • [#82] Support reading passwords from the console with echoing disabled.

Deprecations

No features were deprecated in this release.

Potential breaking changes

This release has no breaking changes.