Skip to content

Commits on Source 3

......@@ -45,7 +45,7 @@ Picocli-based applications can easily [integrate](https://picocli.info/#_depende
![Picocli Demo help message with ANSI colors](docs/images/picocli.Demo.png?raw=true)
### Releases
* [Releases](https://github.com/remkop/picocli/releases) - Latest: 3.9.2 [Release Notes](https://github.com/remkop/picocli/releases/tag/v3.9.2)
* [Releases](https://github.com/remkop/picocli/releases) - Latest: 3.9.6 [Release Notes](https://github.com/remkop/picocli/releases/tag/v3.9.6)
* Older: Picocli 3.0.0 [Release Notes](https://github.com/remkop/picocli/releases/tag/v3.0.0)
* Older: Picocli 2.0 [Release Notes](https://github.com/remkop/picocli/releases/tag/v2.0.0)
......@@ -181,35 +181,35 @@ See the [source code](https://github.com/remkop/picocli/blob/master/src/main/jav
### Gradle
```
compile 'info.picocli:picocli:3.9.2'
compile 'info.picocli:picocli:3.9.6'
```
### Maven
```
<dependency>
<groupId>info.picocli</groupId>
<artifactId>picocli</artifactId>
<version>3.9.2</version>
<version>3.9.6</version>
</dependency>
```
### Scala SBT
```
libraryDependencies += "info.picocli" % "picocli" % "3.9.2"
libraryDependencies += "info.picocli" % "picocli" % "3.9.6"
```
### Ivy
```
<dependency org="info.picocli" name="picocli" rev="3.9.2" />
<dependency org="info.picocli" name="picocli" rev="3.9.6" />
```
### Grape
```groovy
@Grapes(
@Grab(group='info.picocli', module='picocli', version='3.9.2')
@Grab(group='info.picocli', module='picocli', version='3.9.6')
)
```
### Leiningen
```
[info.picocli/picocli "3.9.2"]
[info.picocli/picocli "3.9.6"]
```
### Buildr
```
'info.picocli:picocli:jar:3.9.2'
'info.picocli:picocli:jar:3.9.6'
```
# picocli Release Notes
# <a name="3.9.6"></a> Picocli 3.9.6
The picocli community is pleased to announce picocli 3.9.6.
This release improves support for interactive (password) options:
* interactive options can now use type `char[]` instead of String, to allow applications to null out the array after use so that sensitive information is no longer resident in memory
* interactive options can be optionally interactive if configured with `arity = "0..1"`
This is the fifty-second public release.
Picocli follows [semantic versioning](http://semver.org/).
## <a name="3.9.6"></a> Table of Contents
* [New and noteworthy](#3.9.6-new)
* [Fixed issues](#3.9.6-fixes)
* [Deprecations](#3.9.6-deprecated)
* [Potential breaking changes](#3.9.6-breaking-changes)
## <a name="3.9.6-new"></a> New and Noteworthy
This release improves support for interactive (password) options:
* interactive options can now use type `char[]` instead of String, to allow applications to null out the array after use so that sensitive information is no longer resident in memory
* interactive options can be optionally interactive if configured with `arity = "0..1"`
For example, if an application has these options:
```java
@Option(names = "--user")
String user;
@Option(names = "--password", arity = "0..1", interactive = true)
char[] password;
```
With the following input, the `password` field will be initialized to `"123"` without prompting the user for input:
```
--password 123 --user Joe
```
However, if the password is not specified, the user will be prompted to enter a value. In the following example, the password option has no parameter, so the user will be prompted to type in a value on the console:
```
--password --user Joe
```
## <a name="3.9.6-fixes"></a> Fixed issues
* [#657] Support type `char[]` for interactive options. Thanks to [Lukáš Petrovický](https://github.com/triceo) for raising this issue.
* [#536] Support optionally interactive options. Thanks to [Lukas Heumos](https://github.com/Zethson) for raising this issue.
## <a name="3.9.6-deprecated"></a> Deprecations
No features were deprecated in this release.
## <a name="3.9.6-breaking-changes"></a> Potential breaking changes
This release has no breaking changes.
# <a name="3.9.5"></a> Picocli 3.9.5
The picocli community is pleased to announce picocli 3.9.5.
This release contains a critical workaround to protect against JVM crashes when running on RedHat Linux 3.10.0-327.44.2.el7.x86_64.
Picocli 3.9.0 introduced a change in the heuristics for emitting ANSI escape characters. As part of this change, picocli may load the `org.fusesource.jansi.AnsiConsole` class from the JAnsi library when not running on Windows. This may crash the JVM (see [fusesource/jansi-native#17](https://github.com/fusesource/jansi-native/issues/17)).
The workaround in this release is to only load the `AnsiConsole` class when running on Windows.
Users using 3.9.0 and higher are strongly recommended to upgrade to 3.9.5 or later.
This is the fiftieth public release.
Picocli follows [semantic versioning](http://semver.org/).
## <a name="3.9.5"></a> Table of Contents
* [New and noteworthy](#3.9.5-new)
* [Fixed issues](#3.9.5-fixes)
* [Deprecations](#3.9.5-deprecated)
* [Potential breaking changes](#3.9.5-breaking-changes)
## <a name="3.9.5-new"></a> New and Noteworthy
## <a name="3.9.5-fixes"></a> Fixed issues
- [#630] Avoid loading `org.fusesource.jansi.AnsiConsole` when not running on Windows to avoid JVM crashes on non-Windows platforms.
- [#632] ReflectionConfigGenerator now specifies the `allowWrite = true` attribute for final fields.
## <a name="3.9.5-deprecated"></a> Deprecations
No features were deprecated in this release.
## <a name="3.9.5-breaking-changes"></a> Potential breaking changes
This release has no breaking changes.
# <a name="3.9.4"></a> Picocli 3.9.4
The picocli community is pleased to announce picocli 3.9.4.
This release contains bugfixes and enhancements.
From this release, `enum`-typed options and positional parameters that are multi-value can be stored in `EnumSet` collections (in addition to other Collections, arrays and Maps).
Also, a better error message is now shown when unknown options are encountered while processing clustered short options. The new error message includes both the failing part and the original command line argument.
Bugfixes:
* `ReflectionConfigGenerator` incorrectly listed superclass fields as fields of the concrete subclass, causing "GraalVM error: Error parsing reflection configuration in json" when creating a native image.
* Method subcommands in commands that subclass another command caused `InitializationException`.
This is the forty-nineth public release.
Picocli follows [semantic versioning](http://semver.org/).
## <a name="3.9.4"></a> Table of Contents
* [New and noteworthy](#3.9.4-new)
* [Fixed issues](#3.9.4-fixes)
* [Deprecations](#3.9.4-deprecated)
* [Potential breaking changes](#3.9.4-breaking-changes)
## <a name="3.9.4-new"></a> New and Noteworthy
## <a name="3.9.4-fixes"></a> Fixed issues
- [#628] Add support for collecting `enum` multi-value options and positional parameters in `EnumSet<>` collections. Thanks to [Lee Atkinson](https://github.com/leeatkinson) for raising this.
- [#619] Bugfix: Method subcommands in commands that subclass another command caused `InitializationException`: "Another subcommand named 'method' already exists...". Thanks to [PorygonZRocks](https://github.com/PorygonZRocks) for the bug report.
- [#622] Bugfix: `ReflectionConfigGenerator` incorrectly listed superclass fields as fields of the concrete subclass, causing "GraalVM error: Error parsing reflection configuration in json". Thanks to [Sebastian Thomschke](https://github.com/sebthom) for the bug report.
- [#623] `ReflectionConfigGenerator` now generates json in alphabetic order.
- [#627] Improve error message for unknown options when processing clustered short options.
## <a name="3.9.4-deprecated"></a> Deprecations
No features were deprecated in this release.
## <a name="3.9.4-breaking-changes"></a> Potential breaking changes
This release has no breaking changes.
# <a name="3.9.3"></a> Picocli 3.9.3
The picocli community is pleased to announce picocli 3.9.3.
This release contains bugfixes and enhancements.
This is the forty-eight public release.
Picocli follows [semantic versioning](http://semver.org/).
## <a name="3.9.3"></a> Table of Contents
* [New and noteworthy](#3.9.3-new)
* [Fixed issues](#3.9.3-fixes)
* [Deprecations](#3.9.3-deprecated)
* [Potential breaking changes](#3.9.3-breaking-changes)
## <a name="3.9.3-new"></a> New and Noteworthy
## <a name="3.9.3-fixes"></a> Fixed issues
- [#613] Enhancement: Improve picocli heuristics for unmatched options: single-character arguments that don't exactly match options (like `-`) should be considered positional parameters. Thanks to [Oliver Weiler](https://github.com/helpermethod) for the bug report.
- [#615] Bugfix: Opaque stacktrace for "%" in Option description. Thanks to [petermr](https://github.com/petermr) for the bug report.
- [#616] Bugfix: showDefaultValues=true with defaultValueProvider did not render defaultValues in usage help. Thanks to [Sebastian Thomschke](https://github.com/sebthom) for the bug report.
## <a name="3.9.3-deprecated"></a> Deprecations
No features were deprecated in this release.
## <a name="3.9.3-breaking-changes"></a> Potential breaking changes
This release has no breaking changes.
# <a name="3.9.2"></a> Picocli 3.9.2
The picocli community is pleased to announce picocli 3.9.2.
......
......@@ -331,9 +331,8 @@ Release procedure:
(When releasing from branch)
25. Switch to master
26. Update RELEASE-NOTES.md (insert changes from branch)
27. Update last release version in README
28. Update `projectPreviousVersion` in build.gradle
29. gradlew copyDocs
30. commit -m "Update master for release x.x (from branch x.x)"
26. cherry-pick the "Release picocli version ..." commit
27. gradlew bumpVersion
28. check modified files
29. commit -m "Update master for next development cycle after release x.x (from branch x.x)"
*/
picocli (3.9.6-1) experimental; urgency=medium
* New upstream release
* debian/control: set Multi-Arch: foreign
-- Miroslav Kravec <kravec.miroslav@gmail.com> Tue, 23 Apr 2019 19:14:37 +0200
picocli (3.9.2-1) unstable; urgency=medium
* New upstream release
......
......@@ -17,6 +17,7 @@ Homepage: https://picocli.info
Package: libpicocli-java
Architecture: all
Multi-Arch: foreign
Depends: ${maven:Depends}, ${misc:Depends}
Description: Tiny command line interpreter library for Java applications
Picocli is a one-file framework for creating Java command line applications
......
......@@ -11,7 +11,7 @@ Subject: Adjust build to work without asciidoctor and bintray,
4 files changed, 2 insertions(+), 163 deletions(-)
diff --git a/build.gradle b/build.gradle
index ae743a8..711c1da 100644
index 242919d..eeb0222 100644
--- a/build.gradle
+++ b/build.gradle
@@ -2,21 +2,8 @@ group 'info.picocli'
......
......@@ -11,12 +11,12 @@ junitDepVersion = 4.11
junitVersion = 4.12
# projectPreviousReleaseVersion is non-SNAPSHOT, only published releases
projectPreviousReleaseVersion = 3\\.9\\.1
projectPreviousReleaseVersion = 3\\.9\\.5
# projectPreviousVersionRegex may be a SNAPSHOT
projectPreviousVersionRegex = 3\\.9\\.2-SNAPSHOT
projectVersion = 3.9.2
projectPreviousVersionRegex = 3\\.9\\.6-SNAPSHOT
projectVersion = 3.9.6
releaseDate = 2019-01-20
releaseDatePreviousRegex = 2019\\-01\\-10
releaseDate = 2019-04-06
releaseDatePreviousRegex = 2019\\-02\\-18
systemRulesVersion = 1.17.1
\ No newline at end of file
......@@ -63,7 +63,7 @@ Note that the `picocli-codegen` module is only added as a dependency for the `ex
<dependency>
<groupId>info.picocli</groupId>
<artifactId>picocli-codegen</artifactId>
<version>3.9.2</version>
<version>3.9.6</version>
<type>jar</type>
</dependency>
</dependencies>
......@@ -82,8 +82,8 @@ configurations {
generateConfig
}
dependencies {
compile 'info.picocli:picocli:3.9.2'
generateConfig 'info.picocli:picocli-codegen:3.9.2'
compile 'info.picocli:picocli:3.9.6'
generateConfig 'info.picocli:picocli-codegen:3.9.6'
}
```
......
......@@ -17,14 +17,9 @@ import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.*;
import java.util.concurrent.Callable;
/**
......@@ -138,13 +133,20 @@ public class ReflectionConfigGenerator {
}
static final class Visitor {
Map<String, ReflectedClass> visited = new LinkedHashMap<String, ReflectedClass>();
Map<String, ReflectedClass> visited = new TreeMap<String, ReflectedClass>();
Visitor() {
getOrCreateClass(Method.class);
getOrCreateClassName("java.lang.reflect.Executable").addMethod("getParameters");
getOrCreateClassName("java.lang.reflect.Parameter").addMethod("getName");
// ANSI color enabled detection
getOrCreateClassName("java.lang.System").addMethod("console");
getOrCreateClassName("org.fusesource.jansi.AnsiConsole").addField("out", false);
// picocli 4.0
getOrCreateClassName("java.util.ResourceBundle").addMethod("getBaseBundleName");
// type converters registered with reflection
getOrCreateClassName("java.time.Duration").addMethod("parse", CharSequence.class);
getOrCreateClassName("java.time.Instant").addMethod("parse", CharSequence.class);
......@@ -212,21 +214,25 @@ public class ReflectionConfigGenerator {
Field[] declaredFields = cls.getDeclaredFields();
for (Field f : declaredFields) {
if (f.isAnnotationPresent(CommandLine.Spec.class)) {
reflectedClass.addField(f.getName());
reflectedClass.addField(f.getName(), isFinal(f));
}
if (f.isAnnotationPresent(CommandLine.ParentCommand.class)) {
reflectedClass.addField(f.getName());
reflectedClass.addField(f.getName(), isFinal(f));
}
if (f.isAnnotationPresent(CommandLine.Mixin.class)) {
reflectedClass.addField(f.getName());
reflectedClass.addField(f.getName(), isFinal(f));
}
if (f.isAnnotationPresent(CommandLine.Unmatched.class)) {
reflectedClass.addField(f.getName());
reflectedClass.addField(f.getName(), isFinal(f));
}
}
visitAnnotatedFields(cls.getSuperclass());
}
private boolean isFinal(Field f) {
return (f.getModifiers() & Modifier.FINAL) == Modifier.FINAL;
}
private void visitArgSpec(ArgSpec argSpec) throws NoSuchFieldException, IllegalAccessException {
visitGetter(argSpec.getter());
visitSetter(argSpec.setter());
......@@ -280,8 +286,11 @@ public class ReflectionConfigGenerator {
private void visitFieldBinding(Object fieldBinding) throws IllegalAccessException, NoSuchFieldException {
Field field = (Field) accessibleField(fieldBinding.getClass(), REFLECTED_FIELD_BINDING_FIELD).get(fieldBinding);
getOrCreateClass(field.getDeclaringClass())
.addField(field.getName(), isFinal(field));
Object scope = accessibleField(fieldBinding.getClass(), REFLECTED_BINDING_FIELD_SCOPE).get(fieldBinding);
getOrCreateClass(scope.getClass()).addField(field.getName());
getOrCreateClass(scope.getClass());
}
private void visitMethodBinding(Object methodBinding) throws IllegalAccessException, NoSuchFieldException {
......@@ -332,15 +341,15 @@ public class ReflectionConfigGenerator {
}
static class ReflectedClass {
private final String name;
private final Set<ReflectedField> fields = new LinkedHashSet<ReflectedField>();
private final Set<ReflectedMethod> methods = new LinkedHashSet<ReflectedMethod>();
private final Set<ReflectedField> fields = new TreeSet<ReflectedField>();
private final Set<ReflectedMethod> methods = new TreeSet<ReflectedMethod>();
ReflectedClass(String name) {
this.name = name;
}
ReflectedClass addField(String fieldName) {
fields.add(new ReflectedField(fieldName));
ReflectedClass addField(String fieldName, boolean isFinal) {
fields.add(new ReflectedField(fieldName, isFinal));
return this;
}
......@@ -388,7 +397,7 @@ public class ReflectionConfigGenerator {
return result;
}
}
static class ReflectedMethod {
static class ReflectedMethod implements Comparable<ReflectedMethod> {
private final String name;
private final String[] paramTypes;
......@@ -418,12 +427,22 @@ public class ReflectionConfigGenerator {
}
return result.toString();
}
public int compareTo(ReflectedMethod o) {
int result = name.compareTo(o.name);
if (result == 0) {
result = Arrays.toString(this.paramTypes).compareTo(Arrays.toString(o.paramTypes));
}
static class ReflectedField {
return result;
}
}
static class ReflectedField implements Comparable<ReflectedField> {
private final String name;
private final boolean isFinal;
ReflectedField(String name) {
ReflectedField(String name, boolean isFinal) {
this.name = name;
this.isFinal = isFinal;
}
@Override public int hashCode() { return name.hashCode(); }
@Override public boolean equals(Object o) {
......@@ -432,7 +451,13 @@ public class ReflectionConfigGenerator {
@Override
public String toString() {
return String.format("{ \"name\" : \"%s\" }", name);
return isFinal
? String.format("{ \"name\" : \"%s\", \"allowWrite\" : true }", name)
: String.format("{ \"name\" : \"%s\" }", name);
}
public int compareTo(ReflectedField o) {
return name.compareTo(o.name);
}
}
}
......@@ -11,6 +11,7 @@ import picocli.CommandLine.Spec;
import picocli.CommandLine.Unmatched;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;
......@@ -26,7 +27,7 @@ public class Example implements Runnable {
}
@Option(names = "-t")
TimeUnit timeUnit;
final TimeUnit timeUnit = TimeUnit.SECONDS;
@Parameters(index = "0")
File file;
......@@ -38,10 +39,10 @@ public class Example implements Runnable {
ExampleMixin mixin;
@Unmatched
List<String> unmatched;
final List<String> unmatched = new ArrayList<String>();
private int minimum;
private File[] otherFiles;
private List<File> otherFiles;
@Command
int multiply(@Option(names = "--count") int count,
......@@ -59,7 +60,7 @@ public class Example implements Runnable {
}
@Parameters(index = "1..*")
public void setOtherFiles(File[] otherFiles) {
public void setOtherFiles(List<File> otherFiles) {
for (File f : otherFiles) {
if (!f.exists()) {
throw new ParameterException(spec.commandLine(), "File " + f.getAbsolutePath() + " must exist");
......@@ -70,7 +71,7 @@ public class Example implements Runnable {
public void run() {
System.out.printf("timeUnit=%s, length=%s, file=%s, unmatched=%s, minimum=%s, otherFiles=%s%n",
timeUnit, mixin.length, file, unmatched, minimum, Arrays.toString(otherFiles));
timeUnit, mixin.length, file, unmatched, minimum, otherFiles.toString());
}
public static void main(String[] args) {
......
package picocli.codegen.aot.graalvm;
import picocli.CommandLine.Option;
import picocli.CommandLine.Parameters;
import java.io.File;
public class Issue622AbstractCommand {
@Option(names = "-v")
boolean verbose;
@Parameters
File file;
}
package picocli.codegen.aot.graalvm;
import picocli.CommandLine.Command;
@Command(name = "app", subcommands = {Issue622Command1.class, Issue622Command2.class})
public class Issue622App extends Issue622AbstractCommand {
}
package picocli.codegen.aot.graalvm;
import picocli.CommandLine.Command;
@Command(name = "cmd1")
public class Issue622Command1 extends Issue622AbstractCommand {
}
package picocli.codegen.aot.graalvm;
import picocli.CommandLine.Command;
import picocli.CommandLine.Option;
@Command(name = "cmd2", subcommands = Issue622Command2Sub.class)
public class Issue622Command2 extends Issue622AbstractCommand {
@Option(names = "-x")
int x;
}
package picocli.codegen.aot.graalvm;
import picocli.CommandLine.Command;
import picocli.CommandLine.Option;
@Command(name = "sub")
public class Issue622Command2Sub extends Issue622AbstractCommand {
@Option(names = "-x")
int x;
}
......@@ -41,6 +41,23 @@ public class ReflectionConfigGeneratorTest {
expected = expected.replace("\n", System.getProperty("line.separator"));
String actual = readAndClose(new FileInputStream(file));
file.delete();
assertEquals(expected, actual);
}
@Test
public void testIssue622FieldsFromAbstractSuperclass() throws IOException {
File file = File.createTempFile("picocli-codegen", ".json");
ReflectionConfigGenerator.main("--output", file.getAbsolutePath(), Issue622App.class.getName());
String expected = read("/issue622-reflect.json");
expected = expected.replace("\r\n", "\n");
expected = expected.replace("\n", System.getProperty("line.separator"));
String actual = readAndClose(new FileInputStream(file));
file.delete();
assertEquals(expected, actual);
}
......
[
{
"name" : "java.lang.reflect.Method",
"name" : "[Ljava.lang.String;",
"allDeclaredConstructors" : true,
"allPublicConstructors" : true,
"allDeclaredMethods" : true,
"allPublicMethods" : true
},
{
"name" : "java.io.File",
"allDeclaredConstructors" : true,
"allPublicConstructors" : true,
"allDeclaredMethods" : true,
"allPublicMethods" : true
},
{
"name" : "java.lang.Object",
"allDeclaredConstructors" : true,
"allPublicConstructors" : true,
"allDeclaredMethods" : true,
"allPublicMethods" : true
},
{
"name" : "java.lang.String",
"allDeclaredConstructors" : true,
"allPublicConstructors" : true,
"allDeclaredMethods" : true,
"allPublicMethods" : true
},
{
"name" : "java.lang.System",
"allDeclaredConstructors" : true,
"allPublicConstructors" : true,
"allDeclaredMethods" : true,
"allPublicMethods" : true,
"methods" : [
{ "name" : "console", "parameterTypes" : [] }
]
},
{
"name" : "java.lang.reflect.Executable",
"allDeclaredConstructors" : true,
......@@ -16,6 +47,13 @@
{ "name" : "getParameters", "parameterTypes" : [] }
]
},
{
"name" : "java.lang.reflect.Method",
"allDeclaredConstructors" : true,
"allPublicConstructors" : true,
"allDeclaredMethods" : true,
"allPublicMethods" : true
},
{
"name" : "java.lang.reflect.Parameter",
"allDeclaredConstructors" : true,
......@@ -27,67 +65,59 @@
]
},
{
"name" : "java.time.Duration",
"name" : "java.nio.file.Path",
"allDeclaredConstructors" : true,
"allPublicConstructors" : true,
"allDeclaredMethods" : true,
"allPublicMethods" : true,
"methods" : [
{ "name" : "parse", "parameterTypes" : ["java.lang.CharSequence"] }
]
"allPublicMethods" : true
},
{
"name" : "java.time.Instant",
"name" : "java.nio.file.Paths",
"allDeclaredConstructors" : true,
"allPublicConstructors" : true,
"allDeclaredMethods" : true,
"allPublicMethods" : true,
"methods" : [
{ "name" : "parse", "parameterTypes" : ["java.lang.CharSequence"] }
{ "name" : "get", "parameterTypes" : ["java.lang.String", "[Ljava.lang.String;"] }
]
},
{
"name" : "java.time.LocalDate",
"name" : "java.sql.Connection",
"allDeclaredConstructors" : true,
"allPublicConstructors" : true,
"allDeclaredMethods" : true,
"allPublicMethods" : true,
"methods" : [
{ "name" : "parse", "parameterTypes" : ["java.lang.CharSequence"] }
]
"allPublicMethods" : true
},
{
"name" : "java.time.LocalDateTime",
"name" : "java.sql.Driver",
"allDeclaredConstructors" : true,
"allPublicConstructors" : true,
"allDeclaredMethods" : true,
"allPublicMethods" : true,
"methods" : [
{ "name" : "parse", "parameterTypes" : ["java.lang.CharSequence"] }
]
"allPublicMethods" : true
},
{
"name" : "java.time.LocalTime",
"name" : "java.sql.DriverManager",
"allDeclaredConstructors" : true,
"allPublicConstructors" : true,
"allDeclaredMethods" : true,
"allPublicMethods" : true,
"methods" : [
{ "name" : "parse", "parameterTypes" : ["java.lang.CharSequence"] }
{ "name" : "getConnection", "parameterTypes" : ["java.lang.String"] },
{ "name" : "getDriver", "parameterTypes" : ["java.lang.String"] }
]
},
{
"name" : "java.time.MonthDay",
"name" : "java.sql.Timestamp",
"allDeclaredConstructors" : true,
"allPublicConstructors" : true,
"allDeclaredMethods" : true,
"allPublicMethods" : true,
"methods" : [
{ "name" : "parse", "parameterTypes" : ["java.lang.CharSequence"] }
{ "name" : "valueOf", "parameterTypes" : ["java.lang.String"] }
]
},
{
"name" : "java.time.OffsetDateTime",
"name" : "java.time.Duration",
"allDeclaredConstructors" : true,
"allPublicConstructors" : true,
"allDeclaredMethods" : true,
......@@ -97,7 +127,7 @@
]
},
{
"name" : "java.time.OffsetTime",
"name" : "java.time.Instant",
"allDeclaredConstructors" : true,
"allPublicConstructors" : true,
"allDeclaredMethods" : true,
......@@ -107,7 +137,7 @@
]
},
{
"name" : "java.time.Period",
"name" : "java.time.LocalDate",
"allDeclaredConstructors" : true,
"allPublicConstructors" : true,
"allDeclaredMethods" : true,
......@@ -117,7 +147,7 @@
]
},
{
"name" : "java.time.Year",
"name" : "java.time.LocalDateTime",
"allDeclaredConstructors" : true,
"allPublicConstructors" : true,
"allDeclaredMethods" : true,
......@@ -127,7 +157,7 @@
]
},
{
"name" : "java.time.YearMonth",
"name" : "java.time.LocalTime",
"allDeclaredConstructors" : true,
"allPublicConstructors" : true,
"allDeclaredMethods" : true,
......@@ -137,7 +167,7 @@
]
},
{
"name" : "java.time.ZonedDateTime",
"name" : "java.time.MonthDay",
"allDeclaredConstructors" : true,
"allPublicConstructors" : true,
"allDeclaredMethods" : true,
......@@ -147,125 +177,124 @@
]
},
{
"name" : "java.time.ZoneId",
"name" : "java.time.OffsetDateTime",
"allDeclaredConstructors" : true,
"allPublicConstructors" : true,
"allDeclaredMethods" : true,
"allPublicMethods" : true,
"methods" : [
{ "name" : "of", "parameterTypes" : ["java.lang.String"] }
{ "name" : "parse", "parameterTypes" : ["java.lang.CharSequence"] }
]
},
{
"name" : "java.time.ZoneOffset",
"name" : "java.time.OffsetTime",
"allDeclaredConstructors" : true,
"allPublicConstructors" : true,
"allDeclaredMethods" : true,
"allPublicMethods" : true,
"methods" : [
{ "name" : "of", "parameterTypes" : ["java.lang.String"] }
{ "name" : "parse", "parameterTypes" : ["java.lang.CharSequence"] }
]
},
{
"name" : "java.nio.file.Path",
"name" : "java.time.Period",
"allDeclaredConstructors" : true,
"allPublicConstructors" : true,
"allDeclaredMethods" : true,
"allPublicMethods" : true
"allPublicMethods" : true,
"methods" : [
{ "name" : "parse", "parameterTypes" : ["java.lang.CharSequence"] }
]
},
{
"name" : "java.nio.file.Paths",
"name" : "java.time.Year",
"allDeclaredConstructors" : true,
"allPublicConstructors" : true,
"allDeclaredMethods" : true,
"allPublicMethods" : true,
"methods" : [
{ "name" : "get", "parameterTypes" : ["java.lang.String", "[Ljava.lang.String;"] }
{ "name" : "parse", "parameterTypes" : ["java.lang.CharSequence"] }
]
},
{
"name" : "java.sql.Connection",
"name" : "java.time.YearMonth",
"allDeclaredConstructors" : true,
"allPublicConstructors" : true,
"allDeclaredMethods" : true,
"allPublicMethods" : true
"allPublicMethods" : true,
"methods" : [
{ "name" : "parse", "parameterTypes" : ["java.lang.CharSequence"] }
]
},
{
"name" : "java.sql.Driver",
"name" : "java.time.ZoneId",
"allDeclaredConstructors" : true,
"allPublicConstructors" : true,
"allDeclaredMethods" : true,
"allPublicMethods" : true
"allPublicMethods" : true,
"methods" : [
{ "name" : "of", "parameterTypes" : ["java.lang.String"] }
]
},
{
"name" : "java.sql.DriverManager",
"name" : "java.time.ZoneOffset",
"allDeclaredConstructors" : true,
"allPublicConstructors" : true,
"allDeclaredMethods" : true,
"allPublicMethods" : true,
"methods" : [
{ "name" : "getConnection", "parameterTypes" : ["java.lang.String"] },
{ "name" : "getDriver", "parameterTypes" : ["java.lang.String"] }
{ "name" : "of", "parameterTypes" : ["java.lang.String"] }
]
},
{
"name" : "java.sql.Timestamp",
"name" : "java.time.ZonedDateTime",
"allDeclaredConstructors" : true,
"allPublicConstructors" : true,
"allDeclaredMethods" : true,
"allPublicMethods" : true,
"methods" : [
{ "name" : "valueOf", "parameterTypes" : ["java.lang.String"] }
{ "name" : "parse", "parameterTypes" : ["java.lang.CharSequence"] }
]
},
{
"name" : "picocli.codegen.aot.graalvm.Example",
"name" : "java.util.Collections$UnmodifiableRandomAccessList",
"allDeclaredConstructors" : true,
"allPublicConstructors" : true,
"allDeclaredMethods" : true,
"allPublicMethods" : true,
"fields" : [
{ "name" : "spec" },
{ "name" : "mixin" },
{ "name" : "unmatched" },
{ "name" : "timeUnit" },
{ "name" : "file" }
],
"methods" : [
{ "name" : "setMinimum", "parameterTypes" : ["int"] },
{ "name" : "setOtherFiles", "parameterTypes" : ["[Ljava.io.File;"] },
{ "name" : "multiply", "parameterTypes" : ["int", "int"] }
]
"allPublicMethods" : true
},
{
"name" : "java.lang.Object",
"name" : "java.util.List",
"allDeclaredConstructors" : true,
"allPublicConstructors" : true,
"allDeclaredMethods" : true,
"allPublicMethods" : true
},
{
"name" : "java.util.concurrent.TimeUnit",
"name" : "java.util.ResourceBundle",
"allDeclaredConstructors" : true,
"allPublicConstructors" : true,
"allDeclaredMethods" : true,
"allPublicMethods" : true
"allPublicMethods" : true,
"methods" : [
{ "name" : "getBaseBundleName", "parameterTypes" : [] }
]
},
{
"name" : "java.util.Collections$UnmodifiableRandomAccessList",
"name" : "java.util.concurrent.TimeUnit",
"allDeclaredConstructors" : true,
"allPublicConstructors" : true,
"allDeclaredMethods" : true,
"allPublicMethods" : true
},
{
"name" : "picocli.codegen.aot.graalvm.Example$ExampleMixin",
"name" : "org.fusesource.jansi.AnsiConsole",
"allDeclaredConstructors" : true,
"allPublicConstructors" : true,
"allDeclaredMethods" : true,
"allPublicMethods" : true,
"fields" : [
{ "name" : "length" }
{ "name" : "out" }
]
},
{
......@@ -279,20 +308,6 @@
{ "name" : "versionRequested" }
]
},
{
"name" : "java.io.File",
"allDeclaredConstructors" : true,
"allPublicConstructors" : true,
"allDeclaredMethods" : true,
"allPublicMethods" : true
},
{
"name" : "[Ljava.io.File;",
"allDeclaredConstructors" : true,
"allPublicConstructors" : true,
"allDeclaredMethods" : true,
"allPublicMethods" : true
},
{
"name" : "picocli.CommandLine$HelpCommand",
"allDeclaredConstructors" : true,
......@@ -300,22 +315,37 @@
"allDeclaredMethods" : true,
"allPublicMethods" : true,
"fields" : [
{ "name" : "helpRequested" },
{ "name" : "commands" }
{ "name" : "commands" },
{ "name" : "helpRequested" }
]
},
{
"name" : "[Ljava.lang.String;",
"name" : "picocli.codegen.aot.graalvm.Example",
"allDeclaredConstructors" : true,
"allPublicConstructors" : true,
"allDeclaredMethods" : true,
"allPublicMethods" : true
"allPublicMethods" : true,
"fields" : [
{ "name" : "file" },
{ "name" : "mixin" },
{ "name" : "spec" },
{ "name" : "timeUnit", "allowWrite" : true },
{ "name" : "unmatched", "allowWrite" : true }
],
"methods" : [
{ "name" : "multiply", "parameterTypes" : ["int", "int"] },
{ "name" : "setMinimum", "parameterTypes" : ["int"] },
{ "name" : "setOtherFiles", "parameterTypes" : ["java.util.List"] }
]
},
{
"name" : "java.lang.String",
"name" : "picocli.codegen.aot.graalvm.Example$ExampleMixin",
"allDeclaredConstructors" : true,
"allPublicConstructors" : true,
"allDeclaredMethods" : true,
"allPublicMethods" : true
"allPublicMethods" : true,
"fields" : [
{ "name" : "length" }
]
}
]
[
{
"name" : "java.io.File",
"allDeclaredConstructors" : true,
"allPublicConstructors" : true,
"allDeclaredMethods" : true,
"allPublicMethods" : true
},
{
"name" : "java.lang.Object",
"allDeclaredConstructors" : true,
"allPublicConstructors" : true,
"allDeclaredMethods" : true,
"allPublicMethods" : true
},
{
"name" : "java.lang.System",
"allDeclaredConstructors" : true,
"allPublicConstructors" : true,
"allDeclaredMethods" : true,
"allPublicMethods" : true,
"methods" : [
{ "name" : "console", "parameterTypes" : [] }
]
},
{
"name" : "java.lang.reflect.Executable",
"allDeclaredConstructors" : true,
"allPublicConstructors" : true,
"allDeclaredMethods" : true,
"allPublicMethods" : true,
"methods" : [
{ "name" : "getParameters", "parameterTypes" : [] }
]
},
{
"name" : "java.lang.reflect.Method",
"allDeclaredConstructors" : true,
"allPublicConstructors" : true,
"allDeclaredMethods" : true,
"allPublicMethods" : true
},
{
"name" : "java.lang.reflect.Parameter",
"allDeclaredConstructors" : true,
"allPublicConstructors" : true,
"allDeclaredMethods" : true,
"allPublicMethods" : true,
"methods" : [
{ "name" : "getName", "parameterTypes" : [] }
]
},
{
"name" : "java.nio.file.Path",
"allDeclaredConstructors" : true,
"allPublicConstructors" : true,
"allDeclaredMethods" : true,
"allPublicMethods" : true
},
{
"name" : "java.nio.file.Paths",
"allDeclaredConstructors" : true,
"allPublicConstructors" : true,
"allDeclaredMethods" : true,
"allPublicMethods" : true,
"methods" : [
{ "name" : "get", "parameterTypes" : ["java.lang.String", "[Ljava.lang.String;"] }
]
},
{
"name" : "java.sql.Connection",
"allDeclaredConstructors" : true,
"allPublicConstructors" : true,
"allDeclaredMethods" : true,
"allPublicMethods" : true
},
{
"name" : "java.sql.Driver",
"allDeclaredConstructors" : true,
"allPublicConstructors" : true,
"allDeclaredMethods" : true,
"allPublicMethods" : true
},
{
"name" : "java.sql.DriverManager",
"allDeclaredConstructors" : true,
"allPublicConstructors" : true,
"allDeclaredMethods" : true,
"allPublicMethods" : true,
"methods" : [
{ "name" : "getConnection", "parameterTypes" : ["java.lang.String"] },
{ "name" : "getDriver", "parameterTypes" : ["java.lang.String"] }
]
},
{
"name" : "java.sql.Timestamp",
"allDeclaredConstructors" : true,
"allPublicConstructors" : true,
"allDeclaredMethods" : true,
"allPublicMethods" : true,
"methods" : [
{ "name" : "valueOf", "parameterTypes" : ["java.lang.String"] }
]
},
{
"name" : "java.time.Duration",
"allDeclaredConstructors" : true,
"allPublicConstructors" : true,
"allDeclaredMethods" : true,
"allPublicMethods" : true,
"methods" : [
{ "name" : "parse", "parameterTypes" : ["java.lang.CharSequence"] }
]
},
{
"name" : "java.time.Instant",
"allDeclaredConstructors" : true,
"allPublicConstructors" : true,
"allDeclaredMethods" : true,
"allPublicMethods" : true,
"methods" : [
{ "name" : "parse", "parameterTypes" : ["java.lang.CharSequence"] }
]
},
{
"name" : "java.time.LocalDate",
"allDeclaredConstructors" : true,
"allPublicConstructors" : true,
"allDeclaredMethods" : true,
"allPublicMethods" : true,
"methods" : [
{ "name" : "parse", "parameterTypes" : ["java.lang.CharSequence"] }
]
},
{
"name" : "java.time.LocalDateTime",
"allDeclaredConstructors" : true,
"allPublicConstructors" : true,
"allDeclaredMethods" : true,
"allPublicMethods" : true,
"methods" : [
{ "name" : "parse", "parameterTypes" : ["java.lang.CharSequence"] }
]
},
{
"name" : "java.time.LocalTime",
"allDeclaredConstructors" : true,
"allPublicConstructors" : true,
"allDeclaredMethods" : true,
"allPublicMethods" : true,
"methods" : [
{ "name" : "parse", "parameterTypes" : ["java.lang.CharSequence"] }
]
},
{
"name" : "java.time.MonthDay",
"allDeclaredConstructors" : true,
"allPublicConstructors" : true,
"allDeclaredMethods" : true,
"allPublicMethods" : true,
"methods" : [
{ "name" : "parse", "parameterTypes" : ["java.lang.CharSequence"] }
]
},
{
"name" : "java.time.OffsetDateTime",
"allDeclaredConstructors" : true,
"allPublicConstructors" : true,
"allDeclaredMethods" : true,
"allPublicMethods" : true,
"methods" : [
{ "name" : "parse", "parameterTypes" : ["java.lang.CharSequence"] }
]
},
{
"name" : "java.time.OffsetTime",
"allDeclaredConstructors" : true,
"allPublicConstructors" : true,
"allDeclaredMethods" : true,
"allPublicMethods" : true,
"methods" : [
{ "name" : "parse", "parameterTypes" : ["java.lang.CharSequence"] }
]
},
{
"name" : "java.time.Period",
"allDeclaredConstructors" : true,
"allPublicConstructors" : true,
"allDeclaredMethods" : true,
"allPublicMethods" : true,
"methods" : [
{ "name" : "parse", "parameterTypes" : ["java.lang.CharSequence"] }
]
},
{
"name" : "java.time.Year",
"allDeclaredConstructors" : true,
"allPublicConstructors" : true,
"allDeclaredMethods" : true,
"allPublicMethods" : true,
"methods" : [
{ "name" : "parse", "parameterTypes" : ["java.lang.CharSequence"] }
]
},
{
"name" : "java.time.YearMonth",
"allDeclaredConstructors" : true,
"allPublicConstructors" : true,
"allDeclaredMethods" : true,
"allPublicMethods" : true,
"methods" : [
{ "name" : "parse", "parameterTypes" : ["java.lang.CharSequence"] }
]
},
{
"name" : "java.time.ZoneId",
"allDeclaredConstructors" : true,
"allPublicConstructors" : true,
"allDeclaredMethods" : true,
"allPublicMethods" : true,
"methods" : [
{ "name" : "of", "parameterTypes" : ["java.lang.String"] }
]
},
{
"name" : "java.time.ZoneOffset",
"allDeclaredConstructors" : true,
"allPublicConstructors" : true,
"allDeclaredMethods" : true,
"allPublicMethods" : true,
"methods" : [
{ "name" : "of", "parameterTypes" : ["java.lang.String"] }
]
},
{
"name" : "java.time.ZonedDateTime",
"allDeclaredConstructors" : true,
"allPublicConstructors" : true,
"allDeclaredMethods" : true,
"allPublicMethods" : true,
"methods" : [
{ "name" : "parse", "parameterTypes" : ["java.lang.CharSequence"] }
]
},
{
"name" : "java.util.ResourceBundle",
"allDeclaredConstructors" : true,
"allPublicConstructors" : true,
"allDeclaredMethods" : true,
"allPublicMethods" : true,
"methods" : [
{ "name" : "getBaseBundleName", "parameterTypes" : [] }
]
},
{
"name" : "org.fusesource.jansi.AnsiConsole",
"allDeclaredConstructors" : true,
"allPublicConstructors" : true,
"allDeclaredMethods" : true,
"allPublicMethods" : true,
"fields" : [
{ "name" : "out" }
]
},
{
"name" : "picocli.codegen.aot.graalvm.Issue622AbstractCommand",
"allDeclaredConstructors" : true,
"allPublicConstructors" : true,
"allDeclaredMethods" : true,
"allPublicMethods" : true,
"fields" : [
{ "name" : "file" },
{ "name" : "verbose" }
]
},
{
"name" : "picocli.codegen.aot.graalvm.Issue622App",
"allDeclaredConstructors" : true,
"allPublicConstructors" : true,
"allDeclaredMethods" : true,
"allPublicMethods" : true
},
{
"name" : "picocli.codegen.aot.graalvm.Issue622Command1",
"allDeclaredConstructors" : true,
"allPublicConstructors" : true,
"allDeclaredMethods" : true,
"allPublicMethods" : true
},
{
"name" : "picocli.codegen.aot.graalvm.Issue622Command2",
"allDeclaredConstructors" : true,
"allPublicConstructors" : true,
"allDeclaredMethods" : true,
"allPublicMethods" : true,
"fields" : [
{ "name" : "x" }
]
},
{
"name" : "picocli.codegen.aot.graalvm.Issue622Command2Sub",
"allDeclaredConstructors" : true,
"allPublicConstructors" : true,
"allDeclaredMethods" : true,
"allPublicMethods" : true,
"fields" : [
{ "name" : "x" }
]
}
]
package picocli.examples.interactive;
import picocli.CommandLine;
import picocli.CommandLine.Model.CommandSpec;
import picocli.CommandLine.Option;
import picocli.CommandLine.ParameterException;
import picocli.CommandLine.Spec;
import java.io.File;
public class PasswordDemo implements Runnable {
@Option(names = "--password:file")
File passwordFile;
@Option(names = "--password:env")
String passwordEnvironmentVariable;
@Option(names = "--password", interactive = true)
String password;
@Spec
CommandSpec spec;
public void run() {
if (password != null) {
login(password);
} else if (passwordEnvironmentVariable != null) {
login(System.getenv(passwordEnvironmentVariable));
} else if (passwordFile != null) {
// below uses Java 8 NIO, create your own on older Java versions
/*
login(new String(Files.readAllBytes(passwordFile.toPath())));
*/
} else {
throw new ParameterException(spec.commandLine(), "Password required");
}
}
private void login(String pwd) {
System.out.printf("Password: %s%n", pwd);
}
public static void main(String[] args) {
CommandLine.run(new PasswordDemo(), args);
}
}
This diff is collapsed.