From 03541f6d411e2bd511915ab18fdc262d4a03a8b2 Mon Sep 17 00:00:00 2001 From: Remko Popma Date: Fri, 5 Nov 2021 20:16:43 +0900 Subject: [PATCH] Release picocli version 4.6.2 --- README.md | 22 +- RELEASE-NOTES.md | 4 +- docs/A-Whirlwind-Tour-of-Picocli.html | 160 +- docs/announcing-picocli-1.0.html | 154 +- docs/apidocs/allclasses-frame.html | 2 +- docs/apidocs/allclasses-noframe.html | 2 +- docs/apidocs/constant-values.html | 6 +- docs/apidocs/deprecated-list.html | 25 +- docs/apidocs/help-doc.html | 4 +- docs/apidocs/index-all.html | 22 +- docs/apidocs/index.html | 2 +- docs/apidocs/overview-summary.html | 6 +- docs/apidocs/overview-tree.html | 4 +- .../AutoComplete.GenerateCompletion.html | 4 +- docs/apidocs/picocli/AutoComplete.html | 4 +- .../picocli/CommandLine.AbstractHandler.html | 4 +- ...ommandLine.AbstractParseResultHandler.html | 4 +- .../apidocs/picocli/CommandLine.ArgGroup.html | 4 +- docs/apidocs/picocli/CommandLine.Command.html | 4 +- .../CommandLine.DefaultExceptionHandler.html | 4 +- .../CommandLine.DuplicateNameException.html | 4 +- ...e.DuplicateOptionAnnotationsException.html | 4 +- .../CommandLine.ExecutionException.html | 4 +- .../apidocs/picocli/CommandLine.ExitCode.html | 4 +- .../picocli/CommandLine.Help.Ansi.IStyle.html | 4 +- .../picocli/CommandLine.Help.Ansi.Style.html | 4 +- .../picocli/CommandLine.Help.Ansi.Text.html | 4 +- .../picocli/CommandLine.Help.Ansi.html | 4 +- .../CommandLine.Help.ColorScheme.Builder.html | 4 +- .../picocli/CommandLine.Help.ColorScheme.html | 4 +- .../CommandLine.Help.Column.Overflow.html | 4 +- .../picocli/CommandLine.Help.Column.html | 4 +- .../CommandLine.Help.IOptionRenderer.html | 4 +- .../CommandLine.Help.IParamLabelRenderer.html | 4 +- .../CommandLine.Help.IParameterRenderer.html | 4 +- .../picocli/CommandLine.Help.Layout.html | 4 +- .../CommandLine.Help.TextTable.Cell.html | 4 +- .../picocli/CommandLine.Help.TextTable.html | 4 +- .../picocli/CommandLine.Help.Visibility.html | 4 +- docs/apidocs/picocli/CommandLine.Help.html | 4 +- .../picocli/CommandLine.HelpCommand.html | 4 +- .../CommandLine.IDefaultValueProvider.html | 4 +- .../CommandLine.IExceptionHandler.html | 4 +- .../CommandLine.IExceptionHandler2.html | 4 +- ...ommandLine.IExecutionExceptionHandler.html | 4 +- .../CommandLine.IExecutionStrategy.html | 4 +- .../CommandLine.IExitCodeExceptionMapper.html | 4 +- .../CommandLine.IExitCodeGenerator.html | 4 +- .../apidocs/picocli/CommandLine.IFactory.html | 4 +- ...CommandLine.IHelpCommandInitializable.html | 4 +- ...ommandLine.IHelpCommandInitializable2.html | 4 +- .../picocli/CommandLine.IHelpFactory.html | 4 +- .../CommandLine.IHelpSectionRenderer.html | 4 +- .../CommandLine.IModelTransformer.html | 4 +- ...mmandLine.INegatableOptionTransformer.html | 4 +- .../CommandLine.IParameterConsumer.html | 8 +- ...ommandLine.IParameterExceptionHandler.html | 4 +- .../CommandLine.IParameterPreprocessor.html | 4 +- .../CommandLine.IParseResultHandler.html | 4 +- .../CommandLine.IParseResultHandler2.html | 4 +- .../picocli/CommandLine.ITypeConverter.html | 4 +- .../picocli/CommandLine.IVersionProvider.html | 4 +- .../CommandLine.InitializationException.html | 4 +- ...ommandLine.MaxValuesExceededException.html | 4 +- ...CommandLine.MissingParameterException.html | 4 +- ...andLine.MissingTypeConverterException.html | 4 +- docs/apidocs/picocli/CommandLine.Mixin.html | 4 +- ...ommandLine.Model.ArgGroupSpec.Builder.html | 4 +- .../CommandLine.Model.ArgGroupSpec.html | 4 +- .../picocli/CommandLine.Model.ArgSpec.html | 6 +- .../CommandLine.Model.CommandSpec.html | 4 +- .../CommandLine.Model.IAnnotatedElement.html | 4 +- .../CommandLine.Model.IExtensible.html | 4 +- .../picocli/CommandLine.Model.IGetter.html | 4 +- .../picocli/CommandLine.Model.IOrdered.html | 4 +- .../picocli/CommandLine.Model.IScope.html | 4 +- .../picocli/CommandLine.Model.ISetter.html | 4 +- .../picocli/CommandLine.Model.ITypeInfo.html | 4 +- .../picocli/CommandLine.Model.Messages.html | 4 +- .../CommandLine.Model.MethodParam.html | 4 +- .../CommandLine.Model.OptionSpec.Builder.html | 8 +- .../picocli/CommandLine.Model.OptionSpec.html | 4 +- .../picocli/CommandLine.Model.ParserSpec.html | 4 +- ...ine.Model.PositionalParamSpec.Builder.html | 8 +- ...CommandLine.Model.PositionalParamSpec.html | 4 +- ...ommandLine.Model.UnmatchedArgsBinding.html | 4 +- .../CommandLine.Model.UsageMessageSpec.html | 4 +- docs/apidocs/picocli/CommandLine.Model.html | 4 +- ...ndLine.MutuallyExclusiveArgsException.html | 4 +- docs/apidocs/picocli/CommandLine.Option.html | 54 +- ...ommandLine.OverwrittenOptionException.html | 4 +- .../CommandLine.ParameterException.html | 4 +- ...ommandLine.ParameterIndexGapException.html | 4 +- .../picocli/CommandLine.Parameters.html | 4 +- .../picocli/CommandLine.ParentCommand.html | 4 +- .../CommandLine.ParseResult.Builder.html | 4 +- .../CommandLine.ParseResult.GroupMatch.html | 4 +- ...dLine.ParseResult.GroupMatchContainer.html | 4 +- .../picocli/CommandLine.ParseResult.html | 4 +- .../picocli/CommandLine.PicocliException.html | 4 +- ...CommandLine.PropertiesDefaultProvider.html | 4 +- docs/apidocs/picocli/CommandLine.Range.html | 19 +- .../CommandLine.RegexTransformer.Builder.html | 4 +- .../picocli/CommandLine.RegexTransformer.html | 4 +- docs/apidocs/picocli/CommandLine.RunAll.html | 45 +- .../apidocs/picocli/CommandLine.RunFirst.html | 45 +- docs/apidocs/picocli/CommandLine.RunLast.html | 45 +- .../picocli/CommandLine.ScopeType.html | 4 +- .../picocli/CommandLine.Spec.Target.html | 4 +- docs/apidocs/picocli/CommandLine.Spec.html | 4 +- .../CommandLine.TypeConversionException.html | 4 +- .../picocli/CommandLine.Unmatched.html | 4 +- ...ommandLine.UnmatchedArgumentException.html | 4 +- docs/apidocs/picocli/CommandLine.html | 8 +- docs/apidocs/picocli/package-frame.html | 2 +- docs/apidocs/picocli/package-summary.html | 4 +- docs/apidocs/picocli/package-tree.html | 20 +- docs/apidocs/serialized-form.html | 4 +- docs/autocomplete.adoc | 4 +- docs/autocomplete.html | 158 +- ...apps-in-java-with-graalvm-and-picocli.html | 154 +- docs/feedback.html | 152 +- docs/groovy-2.5-clibuilder-renewal-part1.html | 154 +- docs/groovy-2.5-clibuilder-renewal-part2.html | 154 +- docs/groovy-2.5-clibuilder-renewal.html | 154 +- docs/index.adoc | 62 +- docs/index.html | 1437 +++++++++++------ docs/man/gen-manpage.html | 6 +- docs/man/gen-proxy-config.html | 6 +- docs/man/gen-reflect-config.html | 6 +- docs/man/gen-resource-config.html | 6 +- docs/man/generate-completion.html | 4 +- docs/man/index.html | 154 +- docs/man/picocli.AutoComplete.html | 6 +- docs/migrating-from-commons-cli.html | 154 +- docs/picocli-2.0-do-more-with-less.html | 154 +- ...icocli-2.0-groovy-scripts-on-steroids.html | 154 +- docs/picocli-on-graalvm.html | 154 +- docs/picocli-programmatic-api.adoc | 4 +- docs/picocli-programmatic-api.html | 158 +- docs/quick-guide.adoc | 10 +- docs/quick-guide.html | 170 +- docs/zh/picocli-2.0-do-more-with-less.html | 154 +- ...icocli-2.0-groovy-scripts-on-steroids.html | 154 +- gradle.properties | 6 +- gradle/release-tasks.gradle | 20 +- picocli-codegen/README.adoc | 46 +- .../graalvm/DynamicProxyConfigGenerator.java | 2 +- .../aot/graalvm/JniConfigGenerator.java | 2 +- .../graalvm/ReflectionConfigGenerator.java | 2 +- .../aot/graalvm/ResourceConfigGenerator.java | 2 +- .../docgen/manpage/ManPageGenerator.java | 2 +- .../build.gradle | 4 +- .../example-gradle-project/build.gradle | 6 +- .../example-maven-project-shading/pom.xml | 4 +- .../example-maven-project-simple/pom.xml | 4 +- .../example-gradle-project/build.gradle | 4 +- .../example-maven-project/pom.xml | 6 +- picocli-groovy/README.md | 2 +- picocli-shell-jline2/README.md | 2 +- picocli-shell-jline3/README.md | 2 +- picocli-spring-boot-starter/README.md | 4 +- src/main/java/picocli/AutoComplete.java | 2 +- src/main/java/picocli/CommandLine.java | 8 +- src/test/java/picocli/AutoCompleteTest.java | 2 +- src/test/java/picocli/CommandLineTest.java | 2 +- 166 files changed, 2812 insertions(+), 2258 deletions(-) diff --git a/README.md b/README.md index c9772ae9f..8cef55b34 100644 --- a/README.md +++ b/README.md @@ -76,7 +76,7 @@ The user manual has examples of integrating with [Guice](https://picocli.info/#_ ### Releases * [All Releases](https://github.com/remkop/picocli/releases) -* Latest: 4.6.1 [Release Notes](https://github.com/remkop/picocli/releases/tag/v4.6.1) +* Latest: 4.6.2 [Release Notes](https://github.com/remkop/picocli/releases/tag/v4.6.2) * Older: Picocli 4.0 [Release Notes](https://github.com/remkop/picocli/releases/tag/v4.0.0) * Older: Picocli 3.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) @@ -246,9 +246,9 @@ If you like picocli, there are a few things you can do to help: * Upvote my [Quora answer](https://www.quora.com/What-is-the-best-way-to-parse-command-line-arguments-with-Java/answer/Remko-Popma) to "What is the best way to parse command-line arguments with Java?" * Upvote my [StackOverflow answer](https://stackoverflow.com/a/43780433/1446916) to "How do I parse command line arguments in Java?" -If you like picocli and your project is on GitHub, consider adding this badge to your README.md: [![picocli](https://img.shields.io/badge/picocli-4.6.1-green.svg)](https://github.com/remkop/picocli) +If you like picocli and your project is on GitHub, consider adding this badge to your README.md: [![picocli](https://img.shields.io/badge/picocli-4.6.2-green.svg)](https://github.com/remkop/picocli) ``` -[![picocli](https://img.shields.io/badge/picocli-4.6.1-green.svg)](https://github.com/remkop/picocli) +[![picocli](https://img.shields.io/badge/picocli-4.6.2-green.svg)](https://github.com/remkop/picocli) ``` @@ -336,41 +336,41 @@ See the [source code](https://github.com/remkop/picocli/blob/master/src/main/jav ### Gradle ``` -implementation 'info.picocli:picocli:4.6.1' +implementation 'info.picocli:picocli:4.6.2' ``` ### Maven ``` info.picocli picocli - 4.6.1 + 4.6.2 ``` ### Scala SBT ``` -libraryDependencies += "info.picocli" % "picocli" % "4.6.1" +libraryDependencies += "info.picocli" % "picocli" % "4.6.2" ``` ### Ivy ``` - + ``` ### Grape ```groovy @Grapes( - @Grab(group='info.picocli', module='picocli', version='4.6.1') + @Grab(group='info.picocli', module='picocli', version='4.6.2') ) ``` ### Leiningen ``` -[info.picocli/picocli "4.6.1"] +[info.picocli/picocli "4.6.2"] ``` ### Buildr ``` -'info.picocli:picocli:jar:4.6.1' +'info.picocli:picocli:jar:4.6.2' ``` ### JBang ``` -//DEPS info.picocli:picocli:4.6.1 +//DEPS info.picocli:picocli:4.6.2 ``` diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md index bc6bedbb7..a7946150f 100644 --- a/RELEASE-NOTES.md +++ b/RELEASE-NOTES.md @@ -3,7 +3,9 @@ # Picocli 4.6.2 The picocli community is pleased to announce picocli 4.6.2. -This release includes bugfixes and enhancements. +This release includes bugfixes and enhancements. Many improvements in the documentation. + +Thanks to the many people in the picocli community for raising issues and contributing pull requests to fix issues! From this release, picocli uses system properties `sun.stdout.encoding` and `sun.stderr.encoding` when creating the `PrintWriters` returned by `CommandLine::getOut` and `CommandLine::getErr`. When these system properties do not exist, picocli falls back to the default charset (determined by `file.encoding`). diff --git a/docs/A-Whirlwind-Tour-of-Picocli.html b/docs/A-Whirlwind-Tour-of-Picocli.html index 0224c4fa6..6c2bca36a 100644 --- a/docs/A-Whirlwind-Tour-of-Picocli.html +++ b/docs/A-Whirlwind-Tour-of-Picocli.html @@ -1566,81 +1566,81 @@ }); }); - - - + + + @@ -1648,7 +1648,7 @@

A Whirlwind Tour of Picocli

Remko Popma
-version 4.6.1 +version 4.6.2
@@ -1722,7 +1722,7 @@

A CheckSum Utility

@Option(names = {"-a", "--algorithm"}, description = "MD5, SHA-1, SHA-256, ...") private String algorithm = "MD5"; - public static void main(String[] args) throws Exception { + public static void main(String[] args) { // CheckSum implements Callable, so parsing, error handling and handling user // requests for usage help or version help can be done with one line of code. CommandLine.call(new CheckSum(), args); @@ -2928,7 +2928,7 @@

Micronaut

@Option(names = {"-x", "--option"}, description = "example option") boolean flag; - public static void main(String[] args) throws Exception { + public static void main(String[] args) { // let Micronaut instantiate and inject services PicocliRunner.run(MyMicronautApp.class, args); } @@ -3086,8 +3086,8 @@

Conclusion

diff --git a/docs/announcing-picocli-1.0.html b/docs/announcing-picocli-1.0.html index 330ab85fc..6330fea13 100644 --- a/docs/announcing-picocli-1.0.html +++ b/docs/announcing-picocli-1.0.html @@ -528,81 +528,81 @@ .CodeRay .change .change{color:#66f} .CodeRay .head .head{color:#f4f} - - - + + + @@ -610,7 +610,7 @@

Announcing picocli 1.0 - a mighty tiny command line interface

Remko Popma
-version 4.6.1, +version 4.6.2, 2017-09-10
@@ -734,7 +734,7 @@

Feedback Welcome

diff --git a/docs/apidocs/allclasses-frame.html b/docs/apidocs/allclasses-frame.html index 0a3f62f40..be9e90390 100644 --- a/docs/apidocs/allclasses-frame.html +++ b/docs/apidocs/allclasses-frame.html @@ -3,7 +3,7 @@ -All Classes (picocli 4.6.1 API) +All Classes (picocli 4.6.2 API) diff --git a/docs/apidocs/allclasses-noframe.html b/docs/apidocs/allclasses-noframe.html index 87974888e..53471a469 100644 --- a/docs/apidocs/allclasses-noframe.html +++ b/docs/apidocs/allclasses-noframe.html @@ -3,7 +3,7 @@ -All Classes (picocli 4.6.1 API) +All Classes (picocli 4.6.2 API) diff --git a/docs/apidocs/constant-values.html b/docs/apidocs/constant-values.html index d385785c9..793482d66 100644 --- a/docs/apidocs/constant-values.html +++ b/docs/apidocs/constant-values.html @@ -3,7 +3,7 @@ -Constant Field Values (picocli 4.6.1 API) +Constant Field Values (picocli 4.6.2 API) @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,13 +11,13 @@ @@ -11,13 +11,13 @@ @@ -11,13 +11,13 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ diff --git a/docs/apidocs/picocli/package-summary.html b/docs/apidocs/picocli/package-summary.html index 5fb0ca01f..171d0092b 100644 --- a/docs/apidocs/picocli/package-summary.html +++ b/docs/apidocs/picocli/package-summary.html @@ -3,7 +3,7 @@ -picocli (picocli 4.6.1 API) +picocli (picocli 4.6.2 API) @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@ - - - + + + diff --git a/docs/groovy-2.5-clibuilder-renewal-part1.html b/docs/groovy-2.5-clibuilder-renewal-part1.html index ada458c88..61b584c60 100644 --- a/docs/groovy-2.5-clibuilder-renewal-part1.html +++ b/docs/groovy-2.5-clibuilder-renewal-part1.html @@ -527,88 +527,88 @@ .CodeRay .change .change{color:#66f} .CodeRay .head .head{color:#f4f} - - - + + + @@ -1053,7 +1053,7 @@

Wait, There’s More…​

diff --git a/docs/groovy-2.5-clibuilder-renewal-part2.html b/docs/groovy-2.5-clibuilder-renewal-part2.html index 46a082ab2..b33e9cb9e 100644 --- a/docs/groovy-2.5-clibuilder-renewal-part2.html +++ b/docs/groovy-2.5-clibuilder-renewal-part2.html @@ -527,88 +527,88 @@ .CodeRay .change .change{color:#66f} .CodeRay .head .head{color:#f4f} - - - + + + @@ -1059,7 +1059,7 @@

Conclusion

diff --git a/docs/groovy-2.5-clibuilder-renewal.html b/docs/groovy-2.5-clibuilder-renewal.html index abe93c9c6..44a9fdf9a 100644 --- a/docs/groovy-2.5-clibuilder-renewal.html +++ b/docs/groovy-2.5-clibuilder-renewal.html @@ -527,88 +527,88 @@ .CodeRay .change .change{color:#66f} .CodeRay .head .head{color:#f4f} - - - + + + @@ -1430,7 +1430,7 @@

Conclusion

diff --git a/docs/index.adoc b/docs/index.adoc index 7fb802826..70ab3999b 100644 --- a/docs/index.adoc +++ b/docs/index.adoc @@ -1,8 +1,8 @@ = picocli - a mighty tiny command line interface //:author: Remko Popma //:email: rpopma@apache.org -:revnumber: 4.6.2-SNAPSHOT -:revdate: 2021-01-03 +:revnumber: 4.6.2 +:revdate: 2021-11-05 :toc: left :numbered: :toclevels: 2 @@ -120,7 +120,7 @@ class CheckSum implements Callable { [[CheckSum-App-Groovy]] [source,groovy,role="secondary"] ---- -@Grab('info.picocli:picocli-groovy:4.6.2-SNAPSHOT') +@Grab('info.picocli:picocli-groovy:4.6.2') import picocli.CommandLine import static picocli.CommandLine.* @@ -152,7 +152,7 @@ class Checksum implements Callable { [[CheckSum-App-Groovy-Script]] [source,groovy,role="secondary"] ---- -@Grab('info.picocli:picocli-groovy:4.6.2-SNAPSHOT') +@Grab('info.picocli:picocli-groovy:4.6.2') import static picocli.CommandLine.* import groovy.transform.Field import java.security.MessageDigest @@ -273,7 +273,7 @@ Below are examples of configuring Gradle or Maven to use picocli as an external [source,groovy,role="primary"] ---- dependencies { - implementation 'info.picocli:picocli:4.6.2-SNAPSHOT' + implementation 'info.picocli:picocli:4.6.2' } ---- .Maven @@ -282,7 +282,7 @@ dependencies { info.picocli picocli - 4.6.2-SNAPSHOT + 4.6.2 ---- @@ -319,8 +319,8 @@ https://immutables.github.io/apt.html[This page] shows the steps to configure Ec [source,groovy,role="primary"] ---- dependencies { - implementation 'info.picocli:picocli:4.6.2-SNAPSHOT' - annotationProcessor 'info.picocli:picocli-codegen:4.6.2-SNAPSHOT' + implementation 'info.picocli:picocli:4.6.2' + annotationProcessor 'info.picocli:picocli-codegen:4.6.2' } @@ -342,7 +342,7 @@ compileJava { info.picocli picocli-codegen - 4.6.2-SNAPSHOT + 4.6.2 @@ -362,7 +362,7 @@ then replace `annotationProcessor` with `kapt`: apply plugin: 'kotlin-kapt' // required dependencies { // ... - kapt 'info.picocli:picocli-codegen:4.6.2-SNAPSHOT' + kapt 'info.picocli:picocli-codegen:4.6.2' } ``` @@ -393,7 +393,7 @@ Now, assuming we created a jar named `checksum.jar` containing our compiled `Che [source,bash] ---- -java -cp "picocli-4.6.2-SNAPSHOT.jar:checksum.jar" CheckSum --algorithm SHA-1 hello.txt +java -cp "picocli-4.6.2.jar:checksum.jar" CheckSum --algorithm SHA-1 hello.txt ---- You may want to package your application in such a way that end users can invoke it with a short command like this: @@ -9709,7 +9709,7 @@ Eventually, we are ready to run our application: [source,bash] ---- -java -cp "picocli-4.6.2-SNAPSHOT.jar;myapp.jar" org.myorg.GreetingApp Sarah Lea +java -cp "picocli-4.6.2.jar;myapp.jar" org.myorg.GreetingApp Sarah Lea ---- With no command line parameter `--locale` given, the message texts are printed in the default language (here: English): @@ -9723,7 +9723,7 @@ In order to control the locale choosen for our output, we have to make use of th [source,bash] ---- -java -cp "picocli-4.6.2-SNAPSHOT.jar;myapp.jar" org.myorg.GreetingApp --locale=es Sarah Lea +java -cp "picocli-4.6.2.jar;myapp.jar" org.myorg.GreetingApp --locale=es Sarah Lea ---- Now our message texts are printed in Spanish: @@ -10994,21 +10994,21 @@ Since picocli dependencies are not available in the Spring Initializr, we have t info.picocli picocli-spring-boot-starter - 4.6.2-SNAPSHOT + 4.6.2 ---- .Gradle (Groovy) [source,groovy,role="secondary"] ---- dependencies { - implementation 'info.picocli:picocli-spring-boot-starter:4.6.2-SNAPSHOT' + implementation 'info.picocli:picocli-spring-boot-starter:4.6.2' } ---- .Gradle (Kotlin) [source,kotlin,role="secondary"] ---- dependencies { - implementation("info.picocli:picocli-spring-boot-starter:4.6.2-SNAPSHOT") + implementation("info.picocli:picocli-spring-boot-starter:4.6.2") } ---- @@ -12296,7 +12296,7 @@ As mentioned in <>, earlier in this manual, one way to [source,bash] ---- -java -cp "picocli-4.6.2-SNAPSHOT.jar;myapp.jar" org.myorg.MyMainClass --option=value arg0 arg1 +java -cp "picocli-4.6.2.jar;myapp.jar" org.myorg.MyMainClass --option=value arg0 arg1 ---- That is quite verbose. You may want to package your application in such a way that end users can invoke it by its command name like this: @@ -12315,7 +12315,7 @@ On unix-based operating systems, you can ask your users to define an alias. For [source,bash] ---- -alias mycommand='java -cp "/path/to/picocli-4.6.2-SNAPSHOT.jar:/path/to/myapp.jar" org.myorg.MainClass' +alias mycommand='java -cp "/path/to/picocli-4.6.2.jar:/path/to/myapp.jar" org.myorg.MainClass' ---- Append the above line to your `~/.bashrc` file to make this alias available in every new shell session. @@ -12364,7 +12364,7 @@ After installing GraalVM and installing the `native-image` generator utility (wi you can then create a native image by invoking the `native-image` command: ---- -path/to/native-image -cp picocli-4.6.2-SNAPSHOT.jar --static -jar myapp.jar +path/to/native-image -cp picocli-4.6.2.jar --static -jar myapp.jar ---- CAUTION: To create a native image, the compiler toolchain for your platform needs to be installed. See https://www.infoq.com/articles/java-native-cli-graalvm-picocli/[Build Great Native CLI Apps in Java with Graalvm and Picocli] for details. @@ -12483,7 +12483,7 @@ The script body is executed if the user input was valid and did not request usag [source,groovy] ---- -@Grab('info.picocli:picocli-groovy:4.6.2-SNAPSHOT') +@Grab('info.picocli:picocli-groovy:4.6.2') @GrabConfig(systemClassLoader=true) @Command(name = "myScript", mixinStandardHelpOptions = true, // add --help and --version options @@ -12524,7 +12524,7 @@ The table below compares these two base classes. WARNING: When upgrading scripts from picocli versions older than 4.0, just changing the version number is not enough! -Scripts should use `@Grab('info.picocli:picocli-groovy:4.6.2-SNAPSHOT')`. The old artifact id `@Grab('info.picocli:picocli:4.6.2-SNAPSHOT')` will not work, +Scripts should use `@Grab('info.picocli:picocli-groovy:4.6.2')`. The old artifact id `@Grab('info.picocli:picocli:4.6.2')` will not work, because the `@picocli.groovy.PicocliScript` annotation class and supporting classes have been moved into a separate module, `picocli-groovy`. ==== Closures in Annotations @@ -12581,7 +12581,7 @@ NOTE: When using a Groovy version older than 2.4.7, use this workaround for the [source,groovy] ---- -@Grab('info.picocli:picocli-groovy:4.6.2-SNAPSHOT') +@Grab('info.picocli:picocli-groovy:4.6.2') @GrabExclude('org.codehaus.groovy:groovy-all') // work around GROOVY-7613 ... ---- @@ -12724,14 +12724,14 @@ You can add picocli as an external dependency to your project, or you can includ .Gradle [source,groovy,role="primary"] ---- -implementation 'info.picocli:picocli:4.6.2-SNAPSHOT' +implementation 'info.picocli:picocli:4.6.2' ---- .Gradle (Kotlin) [source,kotlin,role="secondary"] ---- dependencies { - implementation("info.picocli:picocli:4.6.2-SNAPSHOT") + implementation("info.picocli:picocli:4.6.2") } ---- @@ -12741,46 +12741,46 @@ dependencies { info.picocli picocli - 4.6.2-SNAPSHOT + 4.6.2 ---- .Scala SBT [source,role="secondary"] ---- -libraryDependencies += "info.picocli" % "picocli" % "4.6.2-SNAPSHOT" +libraryDependencies += "info.picocli" % "picocli" % "4.6.2" ---- .Ivy [source,role="secondary"] ---- - + ---- .Grape [source,role="secondary"] ---- @Grapes( - @Grab(group='info.picocli', module='picocli', version='4.6.2-SNAPSHOT') + @Grab(group='info.picocli', module='picocli', version='4.6.2') ) ---- .Leiningen [source,role="secondary"] ---- -[info.picocli/picocli "4.6.2-SNAPSHOT"] +[info.picocli/picocli "4.6.2"] ---- .Buildr [source,role="secondary"] ---- -'info.picocli:picocli:jar:4.6.2-SNAPSHOT' +'info.picocli:picocli:jar:4.6.2' ---- .JBang [source,role="secondary"] ---- -//DEPS info.picocli:picocli:4.6.2-SNAPSHOT +//DEPS info.picocli:picocli:4.6.2 ---- === Source diff --git a/docs/index.html b/docs/index.html index 4e8f9f59d..2de2bfce3 100644 --- a/docs/index.html +++ b/docs/index.html @@ -545,6 +545,10 @@ pre.rouge .m, pre.rouge .mb, pre.rouge .mx { color: #009999; } +pre.rouge .sa { + color: #000000; + font-weight: bold; +} pre.rouge .sb { color: #d14; } @@ -578,7 +582,7 @@ pre.rouge .ss { color: #990073; } -pre.rouge .s, pre.rouge .sa, pre.rouge .dl { +pre.rouge .s, pre.rouge .dl { color: #d14; } pre.rouge .na { @@ -1707,164 +1711,89 @@ }); }); - - - - - - + + + @@ -2536,8 +2465,8 @@
Usi
Gradle
dependencies {
-    implementation 'info.picocli:picocli:4.6.1'
-    annotationProcessor 'info.picocli:picocli-codegen:4.6.1'
+    implementation 'info.picocli:picocli:4.6.2'
+    annotationProcessor 'info.picocli:picocli-codegen:4.6.2'
 }
 
 
@@ -2559,7 +2488,7 @@ 
Usi <path> <groupId>info.picocli</groupId> <artifactId>picocli-codegen</artifactId> - <version>4.6.1</version> + <version>4.6.2</version> </path> </annotationProcessorPaths> <compilerArgs> @@ -2584,7 +2513,7 @@
apply plugin: 'kotlin-kapt' // required dependencies { // ... - kapt 'info.picocli:picocli-codegen:4.6.1' + kapt 'info.picocli:picocli-codegen:4.6.2' }
@@ -2627,7 +2556,7 @@

-
java -cp "picocli-4.6.1.jar:checksum.jar" CheckSum --algorithm SHA-1 hello.txt
+
java -cp "picocli-4.6.2.jar:checksum.jar" CheckSum --algorithm SHA-1 hello.txt
+
+ + + + + +
+ + +
POSIX short options and usability
+
+

Applications can give a subtle hint to end users that an option is common and encouraged by providing both a short and a long name for an option. +Conversely, the absence of a short option can signal that the option is unusual or perhaps should be used with care.

+
+
+

Multi-value options and positional parameters can be defined with a split regular expression to allow end users to specify multiple values in a single parameter. @@ -5133,7 +5078,7 @@

6.5.1. Option

boolean

-

0

+

0..1

Boolean options by default don’t require an option parameter. The field is set to the opposite of its default value when the option name is recognized. (This can be configured.)

@@ -6541,8 +6486,7 @@

< -
-
Java / Kotlin
+
@Command(exitCodeOnInvalidInput = 123,
    exitCodeOnExecutionException = 456)
@@ -8413,7 +8357,7 @@

-Make sure any nested classes are static, or picocli will not be able to instantiate them without a Custom Factory. +Make sure any nested classes are static, or picocli will not be able to instantiate them. @@ -8534,7 +8478,7 @@

Examp -Make sure any nested classes are static, or picocli will not be able to instantiate them without a Custom Factory. +Make sure any nested classes are static, or picocli will not be able to instantiate them. @@ -8796,8 +8740,7 @@

Custom help subcommands should mark themselves as a help command to tell picocli not to throw a MissingParameterException when required options are missing.

-
-
Java / Kotlin
+
@Command(helpCommand = true)
@@ -9305,8 +9248,7 @@

14.2. Command

In the above example, the program name is taken from the name attribute of the Command annotation:

-
-
Java / Kotlin
+
@Command(name = "cat")
@@ -9384,19 +9326,20 @@

14.3.

-

14.4. Unsorted Option List

+

14.4. Option List

+
+

14.4.1. Unsorted Option List

By default the options list displays options in alphabetical order. Use the sortOptions = false attribute to display options in the order they are declared in your class.

-
-
Java / Kotlin
+
@Command(sortOptions = false)
-
-

14.5. Reordering Options

+
+

14.4.2. Reordering Options

When mixing @Option methods and @Option fields, options do not reliably appear in declaration order.

@@ -9405,98 +9348,247 @@

1 Options with a lower number are shown before options with a higher number.

-
-

14.6. Split Synopsis Label

-
-

Options and parameters may have a split attribute to split each parameter into smaller substrings. -Regular expressions may contain literal text, but may also contain special characters. -The regular expression in the split attribute may be quite different from what end users need to type.

-
+
+

14.4.3. Required-Option Marker

-

The example below uses the plus (+) character as a separator. -The regular expression in the split attribute uses backslash (\) characters to make sure that the plus character is treated as a literal.

+

Required options can be marked in the option list by the character specified with the requiredOptionMarker attribute. By default options are not marked because the synopsis shows users which options are required and which are optional. This feature may be useful in combination with the abbreviateSynopsis attribute. For example:

Java
-
@Parameters(split = "\\+", splitSynopsisLabel = "+", paramLabel = "VALUE")
-List<String> values;
+
@Command(requiredOptionMarker = '*', abbreviateSynopsis = true)
+class Example {
+    @Option(names = {"-a", "--alpha"}, description = "optional alpha") String alpha;
+    @Option(names = {"-b", "--beta"}, required = true, description = "mandatory beta") String beta;
+}
Kotlin
-
@Parameters(split = "\\+", splitSynopsisLabel = "+", paramLabel = "VALUE")
-lateinit var values: List<String>
+
@Command(requiredOptionMarker = '*', abbreviateSynopsis = true)
+class Example {
+    @Option(names = ["-a", "--alpha"], description = ["optional alpha"])
+    lateinit var alpha: String
+
+    @Option(names = ["-b", "--beta"], required = true, description = ["mandatory beta"])
+    lateinit var beta: String
+}
-

However, end users can type simply A+B+C (using the plus character separator), not A\+B\+C. -We want the usage help message to show this.

+

Produces the following usage help message:

+
+
+
+
Usage: <main class> [OPTIONS]
+  -a, --alpha=<alpha>   optional alpha
+* -b, --beta=<beta>     mandatory beta
+
+
+
+

14.4.4. Short and Long Option Columns

-

The splitSynopsisLabel attribute, introduced in picocli 4.3, controls what is shown in the synopsis of the usage help message.

+

The default layout shows short options and long options in separate columns, followed by the description column.

-

With the example above, the synopsis of the usage help looks like this:

+

Only POSIX short options are shown in the first column, that is, options that start with a single - dash and are one character long.

-
-
-
Usage: cmd [VALUE[+VALUE...]...]
+
+ + + + + +
+ + +Options with two characters are not considered short options and are shown in the long option column. +
+
+
+

This is a common layout for Unix utilities, and can enhance usability: +applications can give a subtle hint to end users that an option is common and encouraged by providing both a short and a long name for the option. +Conversely, the absence of a short option can signal that the option is unusual or perhaps should be used with care.

+
+
+ + + + + +
+ + +It is possible to left-align all options by using a custom layout. +See LeftAlignOptions.java in the picocli-examples module for an example. +
+
+

14.4.5. Long Option Column Width

+
+

The default layout shows short options and long options in separate columns, followed by the description column. +The width of the long options column shrinks automatically if all long options are very short, +but by default this column does not grow larger than 20 characters.

-
-

14.7. Abbreviated Synopsis

-

If a command is very complex and has many options, it is sometimes desirable to suppress details from the synopsis with the abbreviateSynopsis attribute. For example:

+

If the long option with its option parameter is longer than 20 characters +(for example: --output=<outputFolder>), the long option overflows into the description column, and the option description is shown on the next line.

+
+
+

This (the default) looks like this:

-
Usage: <main class> [OPTIONS] [<files>...]
+
Usage: myapp [-hV] [-o=<outputFolder>]
+  -h, --help      Show this help message and exit.
+  -o, --output=<outputFolder>
+                  Output location full path.
+  -V, --version   Print version information and exit.
-

Note that the positional parameters are not abbreviated.

+

As of picocli 4.2, there is programmatic API to change this via the CommandLine::setUsageHelpLongOptionsMaxWidth and UsageMessageSpec::longOptionsMaxWidth methods.

-
-
Java
+
+

In the above example, if we call commandLine.setUsageHelpLongOptionsMaxWidth(23) before printing the usage help, we get this result:

+
+
-
@Command(abbreviateSynopsis = true)
-class App {
-    @Parameters File[] files;
-    @Option(names = {"--count", "-c"}) int count;
-    // ...
-}
+
Usage: myapp [-hV] [-o=<outputFolder>]
+  -h, --help                    Show this help message and exit.
+  -o, --output=<outputFolder>   Output location full path.
+  -V, --version                 Print version information and exit.
-
-
Kotlin
-
-
@Command(abbreviateSynopsis = true)
-class App {
-    @Parameters lateinit var files: Array<File>
-    @Option(names = ["--count", "-c"]) var count = 0
-    // ...
-}
+
+

The minimum value that can be specified for longOptionsMaxWidth is 20, the maximum value is the usage width minus 20.

-

14.8. Custom Synopsis

+

14.5. Usage Width

-

For even more control of the synopsis, use the customSynopsis attribute to specify one ore more synopsis lines. For example:

+

The default width of the usage help message is 80 characters. +Commands defined with @Command(usageHelpWidth = NUMBER) in the annotations will use the specified width.

-
-
-
Usage: ln [OPTION]... [-T] TARGET LINK_NAME   (1st form)
-  or:  ln [OPTION]... TARGET                  (2nd form)
-  or:  ln [OPTION]... TARGET... DIRECTORY     (3rd form)
-  or:  ln [OPTION]... -t DIRECTORY TARGET...  (4th form)
+
+

Picocli 3.0 also introduced programmatic API for this via the CommandLine::setUsageHelpWidth and UsageMessageSpec::width methods.

+
+

End users can use system property picocli.usage.width to specify a custom width that overrides the programmatically set value.

-

To produce a synopsis like the above, specify the literal text in the customSynopsis attribute:

+

The minimum width that can be configured is 55 characters.

+
+
+
+

14.6. Auto (Terminal) Width

+
+

As of picocli 4.0, 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.

+
+
+
+

14.7. Split Synopsis Label

+
+

Options and parameters may have a split attribute to split each parameter into smaller substrings. +Regular expressions may contain literal text, but may also contain special characters. +The regular expression in the split attribute may be quite different from what end users need to type.

+
+
+

The example below uses the plus (+) character as a separator. +The regular expression in the split attribute uses backslash (\) characters to make sure that the plus character is treated as a literal.

+
+
+
Java
+
+
@Parameters(split = "\\+", splitSynopsisLabel = "+", paramLabel = "VALUE")
+List<String> values;
+
+
+
+
Kotlin
+
+
@Parameters(split = "\\+", splitSynopsisLabel = "+", paramLabel = "VALUE")
+lateinit var values: List<String>
+
+
+
+

However, end users can type simply A+B+C (using the plus character separator), not A\+B\+C. +We want the usage help message to show this.

+
+
+

The splitSynopsisLabel attribute, introduced in picocli 4.3, controls what is shown in the synopsis of the usage help message.

+
+
+

With the example above, the synopsis of the usage help looks like this:

+
+
+
+
Usage: cmd [VALUE[+VALUE...]...]
+
+
+
+
+

14.8. Abbreviated Synopsis

+
+

If a command is very complex and has many options, it is sometimes desirable to suppress details from the synopsis with the abbreviateSynopsis attribute. For example:

+
+
+
+
Usage: <main class> [OPTIONS] [<files>...]
+
+
+
+

Note that the positional parameters are not abbreviated.

+
+
+
Java
+
+
@Command(abbreviateSynopsis = true)
+class App {
+    @Parameters File[] files;
+    @Option(names = {"--count", "-c"}) int count;
+    // ...
+}
+
+
+
+
Kotlin
+
+
@Command(abbreviateSynopsis = true)
+class App {
+    @Parameters lateinit var files: Array<File>
+    @Option(names = ["--count", "-c"]) var count = 0
+    // ...
+}
+
+
+
+
+

14.9. Custom Synopsis

+
+

For even more control of the synopsis, use the customSynopsis attribute to specify one ore more synopsis lines. For example:

+
+
+
+
Usage: ln [OPTION]... [-T] TARGET LINK_NAME   (1st form)
+  or:  ln [OPTION]... TARGET                  (2nd form)
+  or:  ln [OPTION]... TARGET... DIRECTORY     (3rd form)
+  or:  ln [OPTION]... -t DIRECTORY TARGET...  (4th form)
+
+
+
+

To produce a synopsis like the above, specify the literal text in the customSynopsis attribute:

Java
@@ -9523,7 +9615,7 @@

14.8. C

-

14.9. Synopsis Subcommand Label

+

14.10. 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:

@@ -9538,8 +9630,7 @@

For example, to clarify that a subcommand is mandatory, an application may specify COMMAND, without the [ and ] brackets:

-
-
Java / Kotlin
+
@Command(name = "git", synopsisSubcommandLabel = "COMMAND")
 class Git { /* ... */ }
@@ -9575,7 +9666,7 @@

- +

The header will be shown at the top of the usage help message (before the synopsis). The first header line is also the line shown in the subcommand list if your command has subcommands (see Usage Help for Subcommands).

@@ -9587,7 +9678,7 @@
-

14.11. Exit Code List

+

14.12. Exit Code List

By default, the usage help message does not display exit code information. Applications that call System.exit need to configure the exitCodeListHeading and exitCodeList annotation attributes. @@ -9641,7 +9732,7 @@

14.11. Ex

-

14.12. Format Specifiers

+

14.13. Format Specifiers

All usage help message elements can have embedded line separator (%n) format specifiers. These are converted to the platform-specific line separator when the usage help message is printed.

@@ -9670,7 +9761,7 @@

14.

-

14.13. Section Headings

+

14.14. Section Headings

Section headers can be used to make usage message layout appear more spacious. The example below demonstrates the use of embedded line separator (%n) format specifiers:

@@ -9711,7 +9802,7 @@

14.13

-

14.14. Expanded Example

+

14.15. Expanded Example

The below example demonstrates what a customized usage message can look like. Note how section headings with line separators can create a more spacious usage message, @@ -9769,13 +9860,12 @@

14.14

-

14.15. Option-Parameter Separators

+

14.16. Option-Parameter Separators

The separator displayed between options and option parameters (= by default) in the synopsis and the option list can be configured with the separator attribute.

-
-
Java / Kotlin
+
@Command(separator = " ")
@@ -9794,7 +9884,7 @@

-

14.16. Hidden Options and Parameters

+

14.17. Hidden Options and Parameters

Options and Parameters with the hidden attribute set to true will not be shown in the usage help message. This is useful for example when a parameter at some index is captured into multiple fields: @@ -9846,12 +9936,12 @@

-

14.17. Show At Files

+

14.18. Show At Files

As of picocli 4.2, an entry for @<filename> can be shown in the options and parameters list of the usage help message of a command with the @Command(showAtFileInUsageHelp = true) annotation.

-

14.17.1. Example

+

14.18.1. Example

Example command:

@@ -9891,7 +9981,7 @@

14.17.1. Example

-

14.17.2. Changing the At File Entry Location

+

14.18.2. Changing the At File Entry Location

By default, the @<filename> entry is shown before the positional parameters in the synopsis as well as in the parameters list.

@@ -9962,7 +10052,7 @@

-

14.17.3. Changing the At File Entry Text

+

14.18.3. Changing the At File Entry Text

Both the label and the description of the @<filename> entry have been defined with custom variables, to allow applications to change the text. The variables are:

@@ -9982,8 +10072,7 @@

For example, if we define these system properties:

-
-
Java / Kotlin
+
System.setProperty("picocli.atfile.label", "my@@@@file");
 System.setProperty("picocli.atfile.description", "@files rock!");
@@ -10016,12 +10105,12 @@

-

14.18. Show End of Options

+

14.19. Show End of Options

As of picocli 4.3, an entry for the -- End of Options delimiter can be shown in the options list of the usage help message of a command with the @Command(showEndOfOptionsDelimiterInUsageHelp = true) annotation.

-

14.18.1. Example

+

14.19.1. Example

Example command:

@@ -10062,7 +10151,7 @@

14.18.1. Example

-

14.18.2. Changing the End of Options Entry Location

+

14.19.2. Changing the End of Options Entry Location

By default, the -- End of Options entry is shown between the options and the positional parameters in the synopsis, and at the end of the options list.

@@ -10136,7 +10225,7 @@

-

14.18.3. Changing the End of Options Entry Text

+

14.19.3. Changing the End of Options Entry Text

The description of the -- End of Options delimiter entry has been defined with a custom variable, to allow applications to change the text. The variable is:

@@ -10153,8 +10242,7 @@

For example, if we define this system property:

-
-
Java / Kotlin
+
System.setProperty("picocli.endofoptions.description", "End of options. Remainder are positional parameters.");
@@ -10186,9 +10274,9 @@

-

14.19. Show Default Values

+

14.20. Show Default Values

-

14.19.1. ${DEFAULT-VALUE} Variable

+

14.20.1. ${DEFAULT-VALUE} Variable

From picocli 3.2, it is possible to embed the default values in the description for an option or positional parameter by specifying the variable ${DEFAULT-VALUE} in the description text. @@ -10233,7 +10321,7 @@

-

14.19.2. ${COMPLETION-CANDIDATES} Variable

+

14.20.2. ${COMPLETION-CANDIDATES} Variable

Similarly, it is possible to embed the completion candidates in the description for an option or positional parameter by specifying the variable ${COMPLETION-CANDIDATES} in the description text.

@@ -10293,7 +10381,7 @@

-

14.19.3. Legacy Configuration for Displaying Default Values

+

14.20.3. Legacy Configuration for Displaying Default Values

Prior to picocli 3.2, you need to use the @Command(showDefaultValues = true) attribute to append the default value of all non-null options and positional parameters to the description column.

@@ -10321,115 +10409,6 @@

-
-

14.20. Required-Option Marker

-
-

Required options can be marked in the option list by the character specified with the requiredOptionMarker attribute. By default options are not marked because the synopsis shows users which options are required and which are optional. This feature may be useful in combination with the abbreviateSynopsis attribute. For example:

-
-
-
Java
-
-
@Command(requiredOptionMarker = '*', abbreviateSynopsis = true)
-class Example {
-    @Option(names = {"-a", "--alpha"}, description = "optional alpha") String alpha;
-    @Option(names = {"-b", "--beta"}, required = true, description = "mandatory beta") String beta;
-}
-
-
-
-
Kotlin
-
-
@Command(requiredOptionMarker = '*', abbreviateSynopsis = true)
-class Example {
-    @Option(names = ["-a", "--alpha"], description = ["optional alpha"])
-    lateinit var alpha: String
-
-    @Option(names = ["-b", "--beta"], required = true, description = ["mandatory beta"])
-    lateinit var beta: String
-}
-
-
-
-

Produces the following usage help message:

-
-
-
-
Usage: <main class> [OPTIONS]
-  -a, --alpha=<alpha>   optional alpha
-* -b, --beta=<beta>     mandatory beta
-
-
-
-
-

14.21. Usage Width

-
-

The default width of the usage help message is 80 characters. -Commands defined with @Command(usageHelpWidth = NUMBER) in the annotations will use the specified width.

-
-
-

Picocli 3.0 also introduced programmatic API for this via the CommandLine::setUsageHelpWidth and UsageMessageSpec::width methods.

-
-
-

End users can use system property picocli.usage.width to specify a custom width that overrides the programmatically set value.

-
-
-

The minimum width that can be configured is 55 characters.

-
-
-
-

14.22. Auto (Terminal) Width

-
-

As of picocli 4.0, 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.

-
-
-
-

14.23. Long Option Column Width

-
-

The default layout shows short options and long options in separate columns, followed by the description column. -The width of the long options column shrinks automatically if all long options are very short, -but by default this column does not grow larger than 20 characters.

-
-
-

If the long option with its option parameter is longer than 20 characters -(for example: --output=<outputFolder>), the long option overflows into the description column, and the option description is shown on the next line.

-
-
-

This (the default) looks like this:

-
-
-
-
Usage: myapp [-hV] [-o=<outputFolder>]
-  -h, --help      Show this help message and exit.
-  -o, --output=<outputFolder>
-                  Output location full path.
-  -V, --version   Print version information and exit.
-
-
-
-

As of picocli 4.2, there is programmatic API to change this via the CommandLine::setUsageHelpLongOptionsMaxWidth and UsageMessageSpec::longOptionsMaxWidth methods.

-
-
-

In the above example, if we call commandLine.setUsageHelpLongOptionsMaxWidth(23) before printing the usage help, we get this result:

-
-
-
-
Usage: myapp [-hV] [-o=<outputFolder>]
-  -h, --help                    Show this help message and exit.
-  -o, --output=<outputFolder>   Output location full path.
-  -V, --version                 Print version information and exit.
-
-
-
-

The minimum value that can be specified for longOptionsMaxWidth is 20, the maximum value is the usage width minus 20.

-
-
+
+

17.18. Subcommands and default values

+
+

There are some scenarios where picocli can not parse an option with a default value which is the same as a subcommand name. To work around this, you can parse the option yourself using IParameterConsumer. A simple implementation is shown below. See this issue for more details.

+
+
+
Kotlin
+
+
class MyParameterConsumer : CommandLine.IParameterConsumer {
+  override fun consumeParameters(
+    args: Stack<String>,
+    argSpec: CommandLine.Model.ArgSpec,
+    commandSpec: CommandLine.Model.CommandSpec
+  ) {
+    if (args.isEmpty()) {
+      throw CommandLine.ParameterException(
+        commandSpec.commandLine(),
+        "Missing required parameter for option " +
+            (argSpec as CommandLine.Model.OptionSpec).longestName()
+      )
+    }
+    argSpec.setValue(args.pop());
+  }
+}
+
+
+
@@ -13766,8 +13772,7 @@

19.1. Confi

Annotation example:

-
-
Java / Kotlin
+
@Command(name = "i18n-demo", resourceBundle = "my.org.I18nDemo_Messages")
 class I18nDemo {}
@@ -14020,37 +14025,178 @@

-

20. Variable Interpolation

-
+
+

19.6. Controlling the locale

-

As of version 4.0, picocli supports variable interpolation (variable expansion) in annotation attributes as well as in text attributes of the programmatic API.

+

In your localized application, it may be desirable to specify the locale in order to determine the language of message texts and help output. +One way of controlling the locale is to give -Duser.language=desiredLocale as VM argument when running the app. +A more accessible and user-friendly approach is to to implement a command line parameter (e. g. --locale) inside your app which can be used to change the locale. +The latter technique requires a two-phase approach to parsing in your application in order to get a valid load order. +The minimal example below demonstrates how to implement this two phase approach:

-
-

20.1. Variable Interpolation Example

Java
-
@Command(name = "status", mixinStandardHelpOptions = true,
-         description = "This command logs the ${COMMAND-NAME} for ${PARENT-COMMAND-NAME}.",
-         version = {
-            "Versioned Command 1.0",
-            "Picocli " + picocli.CommandLine.VERSION,
-            "JVM: ${java.version} (${java.vendor} ${java.vm.name} ${java.vm.version})",
-            "OS: ${os.name} ${os.version} ${os.arch}"})
-class Status {
-    // -d or --directories
-    @Option(names = {"${dirOptionName1:--d}", "${dirOptionName2:---directories}"},
-            description = {"Specify one or more directories, " +
-                               "separated by '${sys:path.separator}'.",
-                           "The default is the user home directory (${DEFAULT-VALUE})."},
-            arity = "${sys:dirOptionArity:-1..*}",
-            defaultValue = "${sys:user.home}",
-            split = "${sys:path.separator}")
-    String[] directories;
-}
+
class InitLocale {
+    @Option(names = { "-l", "--locale" }, description = "locale for message texts (phase 1)")
+    void setLocale(String locale) {
+        Locale.setDefault(new Locale(locale));
+    }
+
+    @Unmatched
+    List<String> remainder; // ignore any other parameters and options in the first parsing phase
+}
+
+@Command(name = "GreetingApp", resourceBundle = "mybundle", mixinStandardHelpOptions = true)
+public class GreetingApp implements Runnable {
+    @Option(names = { "-l", "--locale" }, paramLabel = "<locale>")
+    private String ignored;
+
+    @Parameters(arity = "1..", paramLabel = "<name1> <name2>")
+    private String[] names;
+
+    ResourceBundle bundle = ResourceBundle.getBundle("mybundle");
+
+    public void run() { // business logic here
+        for (String name : names) {
+            System.out.println(MessageFormat.format(bundle.getString("Hello"), name));
+        }
+    }
+
+    public static void main(String[] args) {
+        // first phase: configure locale
+        new CommandLine(new InitLocale()).parseArgs(args);
+
+        // second phase: parse all args (ignoring --locale) and run the app
+        new CommandLine(new GreetingApp()).execute(args);
+    }
+}
+
+
+
+
Kotlin
+
+
class InitLocale {
+    @Option(names = ["-l", "--locale"], description = ["locale for message texts (phase 1)"])
+    fun setLocale(locale: String?) {
+        Locale.setDefault(Locale(locale))
+    }
+
+    @Unmatched
+    lateinit var others : List<String> // ignore other parameters/options in first parsing phase
+}
+
+@Command(name = "GreetingApp", resourceBundle = "mybundle", mixinStandardHelpOptions = true)
+class GreetingApp : Runnable {
+    @Option(names = ["-l", "--locale"], paramLabel = "<locale>")
+    lateinit var ignored: String
+
+    @Parameters(arity = "1..", paramLabel = "<name1> <name2>")
+    lateinit var names: Array<String>
+
+    private var bundle = ResourceBundle.getBundle("mybundle")
+
+    override fun run() { // business logic here
+        names.onEach {
+            println(MessageFormat.format(bundle.getString("Hello"), it))
+        }
+    }
+}
+
+fun main(args: Array<String>)  {
+    // first phase: configure locale
+    CommandLine(picocli.examples.kotlin.i18n.localecontrol.InitLocale()).parseArgs(*args)
+
+    // second phase: parse all args (ignoring --locale) and run the app
+    exitProcess(CommandLine(GreetingApp()).execute(*args))
+}
+
+
+
+

Now put the default properties file (mybundle.properties, in English) and the Spanish language variant (mybundle_es.properties) in place:

+
+
+
mybundle.properties
+
+
Hello = Hello {0}!
+
+
+
+
mybundle_es.properties
+
+
Hello = ¡Hola {0}!
+
+
+
+

Eventually, we are ready to run our application:

+
+
+
+
java -cp "picocli-4.6.2.jar;myapp.jar" org.myorg.GreetingApp Sarah Lea
+
+
+
+

With no command line parameter --locale given, the message texts are printed in the default language (here: English):

+
+
+
+
Hello Sarah!
+Hello Lea!
+
+
+
+

In order to control the locale choosen for our output, we have to make use of the command line parameter --locale:

+
+
+
+
java -cp "picocli-4.6.2.jar;myapp.jar" org.myorg.GreetingApp --locale=es Sarah Lea
+
+
+
+

Now our message texts are printed in Spanish:

+
+
+
+
¡Hola Sarah!
+¡Hola Lea!
+
+
+
+

Using the command line parameter --locale, one can also determine the language of the help output of your application. +The picocli-examples module has examples with fully implemented, localized help output, coded both in Java and Kotlin.

+
+
+
+
+
+

20. Variable Interpolation

+
+
+

As of version 4.0, picocli supports variable interpolation (variable expansion) in annotation attributes as well as in text attributes of the programmatic API.

+
+
+

20.1. Variable Interpolation Example

+
+
Java
+
+
@Command(name = "status", mixinStandardHelpOptions = true,
+         description = "This command logs the ${COMMAND-NAME} for ${PARENT-COMMAND-NAME}.",
+         version = {
+            "Versioned Command 1.0",
+            "Picocli " + picocli.CommandLine.VERSION,
+            "JVM: ${java.version} (${java.vendor} ${java.vm.name} ${java.vm.version})",
+            "OS: ${os.name} ${os.version} ${os.arch}"})
+class Status {
+    // -d or --directories
+    @Option(names = {"${dirOptionName1:--d}", "${dirOptionName2:---directories}"},
+            description = {"Specify one or more directories, " +
+                               "separated by '${sys:path.separator}'.",
+                           "The default is the user home directory (${DEFAULT-VALUE})."},
+            arity = "${sys:dirOptionArity:-1..*}",
+            defaultValue = "${sys:user.home}",
+            split = "${sys:path.separator}")
+    String[] directories;
+}
@@ -14075,6 +14221,18 @@

}

+
+ + + + + +
+ + +In Kotlin, the dollar sign ($) has to be escaped with a backslash (\) in order to prevent Kotlin string interpolation to occur: \${DEFAULT-VALUE}. +
+

20.2. Predefined Variables

@@ -14883,7 +15041,7 @@

-If your model transformer is declared as nested class, make sure you mark this class as static, or picocli will not be able to instantiate your transformer class without a Custom Factory. +If your model transformer is declared as nested class, make sure you mark this class as static, or picocli will not be able to instantiate your transformer class. @@ -15561,7 +15719,7 @@

<dependency> <groupId>info.picocli</groupId> <artifactId>picocli-spring-boot-starter</artifactId> - <version>4.6.1</version> + <version>4.6.2</version> </dependency>

@@ -15569,7 +15727,7 @@

Gradle (Groovy)

dependencies {
-    implementation 'info.picocli:picocli-spring-boot-starter:4.6.1'
+    implementation 'info.picocli:picocli-spring-boot-starter:4.6.2'
 }
@@ -15577,7 +15735,7 @@

Gradle (Kotlin)

dependencies {
-    implementation("info.picocli:picocli-spring-boot-starter:4.6.1")
+    implementation("info.picocli:picocli-spring-boot-starter:4.6.2")
 }

@@ -15894,7 +16052,7 @@

-

Finally we have to configure our mail service. This can be done inside a file application properties, which we put in a config subdirectory of your project:

+

Finally we have to configure our mail service. This can be done inside a file application.properties, which we put in a config subdirectory of your project:

application.properties
@@ -16035,7 +16193,7 @@

22. defaultValue = "remkop/picocli") String slug; - public static void main(String[] args) throws Exception { + public static void main(String[] args) { PicocliRunner.execute(GitStarsCommand.class, args); } @@ -16648,7 +16806,8 @@

For example:

-
+ +
+
Kotlin
+
+
val app = MyApp()
+val cmd = CommandLine(app)
+
+val sw = StringWriter()
+cmd.out = PrintWriter(sw)
+
+// black box testing
+val exitCode = cmd.execute("-x", "-y=123")
+assertEquals(0, exitCode)
+assertEquals("Your output is abc...", sw.toString())
+
+// white box testing
+assertEquals("expectedValue1", app.state1)
+assertEquals("expectedValue2", app.state2)
+
-
-

28.2. Testing the Output

This assumes that the application uses the PrintWriter provided by CommandLine.getOut or CommandLine.getErr. Applications can get these writers via the @Spec annotation:

-
+
+
Java
@Command
 class MyApp implements Runnable {
@@ -16686,8 +16862,100 @@ 

2 }

+
+
Kotlin
+
+
@Command
+class MyApp : Runnable {
+    @Spec lateinit var spec: CommandSpec
+
+    override fun run() {
+        // make testing easier by printing to the Err and Out streams provided by picocli
+        spec.commandLine().out.println("Your output is abc...")
+    }
+}
+
+
+
+
+

28.2. Testing the Output

+
+

Applications that print to System.out or System.err directly, or use a version of picocli lower than 4.0, can be tested by capturing the standard output and error streams. +There are various options for doing this, some of which are shown below.

+
+
+

28.2.1. Java 8+ with System-Lambda

+
+

Applications that use JUnit 5 or Java 8+ can use Stephan Birkner’s System-Lambda project for capturing output. +This library has facilities for capturing the standard output and standard error streams separately or mixed together, and for normalizing line breaks.

+
-

Applications that use a version of picocli older than 4.0, or applications that print to System.out or System.err directly can be tested by capturing the standard output and error streams like this:

+

Example usage:

+
+
+
+
import static com.github.stefanbirkner.systemlambda.SystemLambda.tapSystemErr;
+import static com.github.stefanbirkner.systemlambda.SystemLambda.tapSystemOutNormalized;
+// ...
+
+class MyTest {
+    @Test
+    void testMyApp() throws Exception {
+        String errText = tapSystemErr(() -> {
+            String outText = tapSystemOutNormalized(() -> {
+                new CommandLine(new MyApp()).execute("--option=value", "arg0", "arg1");
+            });
+            assertEquals("--option='value'\n" +
+                         "position[0]='arg0'\n" +
+                         "position[1]='arg1'\n", outText);
+        });
+        assertEquals("", errText);
+    }
+}
+
+
+
+
+

28.2.2. JUnit 4 with System-Rules

+
+

Applications that use JUnit 4 can use Stephan Birkner’s System-Rules project for capturing output.

+
+
+

Example usage:

+
+
+
+
import org.junit.contrib.java.lang.system.SystemErrRule;
+import org.junit.contrib.java.lang.system.SystemOutRule;
+// ...
+
+class MyTest {
+    @Rule
+    SystemErrRule systemErrRule = new SystemErrRule().enableLog().muteForSuccessfulTests();
+
+    @Rule
+    SystemOutRule systemOutRule = new SystemOutRule().enableLog().muteForSuccessfulTests();
+
+    @Test
+    void testMyApp() throws Exception {
+        new CommandLine(new MyApp()).execute("--option=value", "arg0", "arg1");
+        String expected = String.format("--option='value'%n" +
+                                        "position[0]='arg0'%n" +
+                                        "position[1]='arg1'%n");
+        assertEquals(expected, systemOutRule.getLog());
+        assertEquals("", systemErrRule.getLog());
+    }
+}
+
+
+
+
+

28.2.3. DIY Output Capturing

+
+

It is also possible to capture output in the tests yourself without using a library.

+
+
+

For example:

@@ -16709,7 +16977,10 @@

2

-

If you’re testing with JUnit 4, you can do the setup in a @org.junit.Before-annotated method and teardown in an @org.junit.After-annotated method. +

This looks verbose, but can be simplified a lot by letting the test framework do the setup and cleanup.

+
+
+

JUnit 4 lets you do setup in a @org.junit.Before-annotated method and teardown in an @org.junit.After-annotated method. The JUnit 5 equivalent annotations are @org.junit.jupiter.api.BeforeEach and @org.junit.jupiter.api.AfterEach, respectively. For example:

@@ -16753,17 +17024,90 @@

2

+

28.3. Testing the Exit Code

-

Testing the exit code of applications that call System.exit can be tricky but is not impossible.

+

Testing the exit code of applications that call System.exit can be tricky but is not impossible. +Depending on your programming language, your environment and your testing framework, you have several options:

+
+
+
    +
  • +

    Java 8: You can use Stephan Birkner’s System-Lambda project for testing the exit code

    +
  • +
  • +

    Java/Kotlin + Junit 5: You can use Todd Ginsberg’s System.exit() extension for Junit 5. The project README mentions common use cases.

    +
  • +
  • +

    Java + Junit 4: You can use Stephan Birkner’s System-Rules project for testing the exit code.

    +
  • +
  • +

    Kotlin + Kotest: Kotlin coders you may use the Kotest test framework which comes with System Exit extensions that allow you to test the exit code.

    +
  • +
-

Applications that use JUnit 4 can use Stephan Birkner’s System-Rules project for testing the exit code. -(This library has many other nice features, including capturing the standard output and standard error streams, and more.) -For example:

+

The listing below provides code samples for all of the four options mentioned above:

-
+
+
Java 8
+
+
import static com.github.stefanbirkner.systemlambda.SystemLambda.catchSystemExit;
+// ...
+
+class MyTest {
+    @Command
+    static class MyApp implements Callable<Integer> {
+        public Integer call() {
+            System.out.println("Hi");
+            return 42;
+        }
+        public static void main(String[] args) {
+            System.exit(new CommandLine(new MyApp()).execute(args));
+        }
+    }
+
+    @Test
+    void testMyAppExit() throws Exception {
+        int exitCode = catchSystemExit(() -> {
+            MyApp.main();
+        });
+        assertEquals(42, exitCode);
+    }
+}
+
+
+
+
Java/Junit 5
+
+
import com.ginsberg.junit.exit.ExpectSystemExitWithStatus;
+import org.junit.jupiter.api.Test;
+// ...
+
+class MyTest {
+    @Command
+    static class MyApp implements Callable<Integer> {
+        @Override
+        public Integer call() throws Exception {
+            System.out.println("Hi");
+            return 42;
+        }
+        public static void main (String[] args) {
+            System.exit(new CommandLine(new MyApp()).execute(args));
+        }
+    }
+
+    @Test
+    @ExpectSystemExitWithStatus(42)
+    void testMyAppExit() {
+        MyApp.main(new String[] {});
+    }
+}
+
+
+ -
-

JUnit 5 users may be interested in Todd Ginsberg’s blog post Testing System.exit() with JUnit5.

+
+
Kotlin/Kotest
+
+
import io.kotest.assertions.throwables.shouldThrow
+import io.kotest.core.spec.style.StringSpec
+import io.kotest.extensions.system.*
+import io.kotest.matchers.shouldBe
+// ...
+
+class SystemExitTest : StringSpec() {
+
+    override fun listeners() = listOf(SpecSystemExitListener)
+
+    init {
+        "Picocli app should exit process with return code 42" {
+            shouldThrow<SystemExitException> {
+                main(arrayOf())
+            }.exitCode shouldBe 42
+        }
+    }
+}
+
+@Command
+class PicocliApp : Callable<Int> {
+    override fun call(): Int {
+        return 42
+    }
+}
+
+fun main(args: Array<String>) : Unit = exitProcess(CommandLine(PicocliApp()).execute(*args))
+

28.4. Testing Environment Variables

-

Since picocli offers support for using environment variables in the annotations, you may want to test this.

-
-
-

Applications that use JUnit 4 can use Stephan Birkner’s System-Rules project for testing environment variables.

-
-
-

JUnit 5 does not appear to provide an equivalent extension for testing environment variables. -JUnit 5 users can use Stephan Birkner’s @Rule EnvironmentVariables …​ for testing environment variables, but there are some things to be aware of.

+

Since picocli offers support for using environment variables in the annotations, you may want to test this. +Depending on your programming language, your environment and your testing framework, you have several options:

  • -

    Use com.github.stefanbirkner:system-rules version 1.17.2: the latest version, 1.18, has an issue that means the Environment Variables rule will not work in JUnit 5.

    +

    Java 8: You can use Stephan Birkner’s System-Lambda project for testing environment variables

  • -

    Apparently the JUnit 5 @EnableRuleMigrationSupport annotation is not sufficient to reliably use @Rule EnvironmentVariables in a JUnit 5 test.

    +

    Java + Junit 4: You can use Stephan Birkner’s System-Rules project for testing the environment variables.

  • -

    Instead, I recommend creating a separate JUnit 4 test class for the environment variable tests.

    +

    Kotlin + Kotest: Kotlin coders you may use the Kotest test framework which comes with System Environment extension that allow you to test environment variables.

-

In Gradle, use the following dependencies:

+

The listing below provides code samples for the three options mentioned above:

-
+
+
Java 8
-
dependencies {
-    implementation      "info.picocli:picocli:${picocliVersion}"
-    annotationProcessor "info.picocli:picocli-codegen:${picocliVersion}"
+
import static com.github.stefanbirkner.systemlambda.SystemLambda.withEnvironmentVariable;
+// ...
 
-    testImplementation("com.github.stefanbirkner:system-rules:1.17.2") {
-        exclude group:"junit"
-    }
-    testImplementation "junit:junit:${junit4Version}"
-    testImplementation "org.junit.jupiter:junit-jupiter-api:${junit5Version}"
+@Test
+void testEnvVar() throws Exception {
+    class MyApp {
+        @Option(names = "--option", defaultValue = "${env:MYVAR}",
+                description = "Some option. Default: ${DEFAULT-VALUE}")
+        String option;
+    }
+    String actual = withEnvironmentVariable("MYVAR", "some-value")
+            .and("OTHER_VAR", "second value")
+            .execute(() -> new CommandLine(new MyApp())
+                            .getUsageMessage(CommandLine.Help.Ansi.OFF));
+
+    String expected = String.format("" +
+            "Usage: <main class> [--option=<option>]%n" +
+            "      --option=<option>   Some option. Default: some-value%n");
+    assertEquals(expected, actual);
+}
+
+
+
+
Java/JUnit 4
+
+
import org.junit.contrib.java.lang.system.EnvironmentVariables;
+// ...
+
+class MyTest {
+    @Rule
+    public final EnvironmentVariables environmentVariables = new EnvironmentVariables();
 
-    testRuntimeOnly "org.junit.platform:junit-platform-launcher:1.6.0"
-    testRuntimeOnly "org.junit.vintage:junit-vintage-engine:${junit5Version}"
-    testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:${junit5Version}"
+    @Test
+    public void testEnvVar() {
+        class MyApp {
+            @Option(names = "--option", defaultValue = "${env:MYVAR}",
+                    description = "Some option. Default: ${DEFAULT-VALUE}")
+            String option;
+        }
+        environmentVariables.clear("MYVAR", "OTHER_VAR", "THIRD_VAR");
+        environmentVariables.set("MYVAR", "some-value");
+        environmentVariables.set("OTHER_VAR", "second value");
 
-    // ...
-}
+        String actual = new CommandLine(new MyApp())
+                .getUsageMessage(CommandLine.Help.Ansi.OFF);
 
-test {
-    useJUnitPlatform {
-        includeEngines 'junit-jupiter', 'junit-vintage'
-    }
-}
+ String expected = String.format("" + + "Usage: <main class> [--option=<option>]%n" + + " --option=<option> Some option. Default: some-value%n"); + assertEquals(expected, actual); + } +}
-
-

For more details, see the sample project provided by David M. Carr.

+
+
Kotlin/Kotest
+
+
import io.kotest.core.spec.style.StringSpec
+import io.kotest.extensions.system.withEnvironment
+import io.kotest.matchers.shouldBe
+import picocli.CommandLine
+import picocli.CommandLine.Command
+
+class EnvironmentVarTest : StringSpec() {
+    init {
+        "env var" {
+            withEnvironment(mapOf("MYVAR" to "some-value", "OTHER_VAR" to "second value")) {
+                CommandLine(MyApp()).getUsageMessage(CommandLine.Help.Ansi.OFF) shouldBe
+                "Usage: <main class> [--option=<option>]" + System.lineSeparator() +
+                "      --option=<option>   Some option. Default: some-value" + System.lineSeparator()
+            }
+        }
+    }
+}
+
+@Command
+class MyApp {
+    @CommandLine.Option(names = ["--option"], defaultValue = "\${env:MYVAR}",
+        description = ["Some option. Default: \${DEFAULT-VALUE}"])
+    lateinit var option: String
+}
+
+
+
+ + + + + +
+ + +The latest versions of com.github.stefanbirkner:system-rules, 1.18 and 1.19, have an issue that means the Environment Variables rule will not work in JUnit 5. Use System Rules version 1.17.2 instead when combining with JUnit 5. +
-
alias mycommand='java -cp "/path/to/picocli-4.6.1.jar:/path/to/myapp.jar" org.myorg.MainClass'
+
alias mycommand='java -cp "/path/to/picocli-4.6.2.jar:/path/to/myapp.jar" org.myorg.MainClass'
+
+

29.10. JReleaser

+
+

JReleaser enables several packaging options such as Homebrew, Chocolatey, +Snapcraft, Scoop, jbang, Docker, among others. +Currently two different distribution types are supported: jlink, and standard zip/tar distributions. The latter can be generated with a +combination of the appassembler-maven-plugin and +maven-assembly-plugin plugins if using Maven, or the +application plugin if using Gradle.

+
+
@@ -17171,7 +17624,7 @@

30.1.2. G

-
@Grab('info.picocli:picocli-groovy:4.6.1')
+
@Grab('info.picocli:picocli-groovy:4.6.2')
 @GrabConfig(systemClassLoader=true)
 @Command(name = "myScript",
         mixinStandardHelpOptions = true, // add --help and --version options
@@ -17257,7 +17710,7 @@ 

30.1.2. G When upgrading scripts from picocli versions older than 4.0, just changing the version number is not enough! -Scripts should use @Grab('info.picocli:picocli-groovy:4.6.1'). The old artifact id @Grab('info.picocli:picocli:4.6.1') will not work, +Scripts should use @Grab('info.picocli:picocli-groovy:4.6.2'). The old artifact id @Grab('info.picocli:picocli:4.6.2') will not work, because the @picocli.groovy.PicocliScript annotation class and supporting classes have been moved into a separate module, picocli-groovy. @@ -17352,7 +17805,7 @@

-
@Grab('info.picocli:picocli-groovy:4.6.1')
+
@Grab('info.picocli:picocli-groovy:4.6.2')
 @GrabExclude('org.codehaus.groovy:groovy-all') // work around GROOVY-7613
 ...
@@ -17543,14 +17996,14 @@

37.1. Build too
Gradle
-
implementation 'info.picocli:picocli:4.6.1'
+
implementation 'info.picocli:picocli:4.6.2'
Gradle (Kotlin)
dependencies {
-    implementation("info.picocli:picocli:4.6.1")
+    implementation("info.picocli:picocli:4.6.2")
 }
@@ -17560,46 +18013,46 @@

37.1. Build too
<dependency>
   <groupId>info.picocli</groupId>
   <artifactId>picocli</artifactId>
-  <version>4.6.1</version>
+  <version>4.6.2</version>
 </dependency>

Scala SBT
-
libraryDependencies += "info.picocli" % "picocli" % "4.6.1"
+
libraryDependencies += "info.picocli" % "picocli" % "4.6.2"
Ivy
-
<dependency org="info.picocli" name="picocli" rev="4.6.1" />
+
<dependency org="info.picocli" name="picocli" rev="4.6.2" />
Grape
@Grapes(
-    @Grab(group='info.picocli', module='picocli', version='4.6.1')
+    @Grab(group='info.picocli', module='picocli', version='4.6.2')
 )
Leiningen
-
[info.picocli/picocli "4.6.1"]
+
[info.picocli/picocli "4.6.2"]
Buildr
-
'info.picocli:picocli:jar:4.6.1'
+
'info.picocli:picocli:jar:4.6.2'
JBang
-
//DEPS info.picocli:picocli:4.6.1
+
//DEPS info.picocli:picocli:4.6.2
@@ -17616,8 +18069,8 @@

37.2. Source

diff --git a/docs/man/gen-manpage.html b/docs/man/gen-manpage.html index c5bbd96bb..a4bca79a8 100644 --- a/docs/man/gen-manpage.html +++ b/docs/man/gen-manpage.html @@ -579,7 +579,7 @@

Example

-
java -Duser.language=de -cp "myapp.jar;picocli-4.6.1.jar;picocli-codegen-4.6.1.jar" picocli.codegen.docgen.manpage.ManPageGenerator my.pkg.MyClass
+
java -Duser.language=de -cp "myapp.jar;picocli-4.6.2.jar;picocli-codegen-4.6.2.jar" picocli.codegen.docgen.manpage.ManPageGenerator my.pkg.MyClass
@@ -587,8 +587,8 @@

Example

diff --git a/docs/man/gen-proxy-config.html b/docs/man/gen-proxy-config.html index 3c800622c..598b43d78 100644 --- a/docs/man/gen-proxy-config.html +++ b/docs/man/gen-proxy-config.html @@ -540,7 +540,7 @@

Example

-
java -cp "myapp.jar;picocli-4.6.1.jar;picocli-codegen-4.6.1.jar" picocli.codegen.aot.graalvm.DynamicProxyConfigGenerator my.pkg.MyClass
+
java -cp "myapp.jar;picocli-4.6.2.jar;picocli-codegen-4.6.2.jar" picocli.codegen.aot.graalvm.DynamicProxyConfigGenerator my.pkg.MyClass
@@ -548,8 +548,8 @@

Example

diff --git a/docs/man/gen-reflect-config.html b/docs/man/gen-reflect-config.html index 52a10a8fb..ff4c44681 100644 --- a/docs/man/gen-reflect-config.html +++ b/docs/man/gen-reflect-config.html @@ -536,7 +536,7 @@

Example

-
java -cp "myapp.jar;picocli-4.6.1.jar;picocli-codegen-4.6.1.jar" picocli.codegen.aot.graalvm.ReflectionConfigGenerator my.pkg.MyClass
+
java -cp "myapp.jar;picocli-4.6.2.jar;picocli-codegen-4.6.2.jar" picocli.codegen.aot.graalvm.ReflectionConfigGenerator my.pkg.MyClass
@@ -544,8 +544,8 @@

Example

diff --git a/docs/man/gen-resource-config.html b/docs/man/gen-resource-config.html index 83dbcbc16..3acda7ea6 100644 --- a/docs/man/gen-resource-config.html +++ b/docs/man/gen-resource-config.html @@ -545,7 +545,7 @@

Example

-
java -cp "myapp.jar;picocli-4.6.1.jar;picocli-codegen-4.6.1.jar" picocli.codegen.aot.graalvm.ResourceConfigGenerator my.pkg.MyClass
+
java -cp "myapp.jar;picocli-4.6.2.jar;picocli-codegen-4.6.2.jar" picocli.codegen.aot.graalvm.ResourceConfigGenerator my.pkg.MyClass
@@ -553,8 +553,8 @@

Example

diff --git a/docs/man/generate-completion.html b/docs/man/generate-completion.html index f0c5f45cf..456ff168b 100644 --- a/docs/man/generate-completion.html +++ b/docs/man/generate-completion.html @@ -487,8 +487,8 @@

Options

diff --git a/docs/man/index.html b/docs/man/index.html index 806440bd3..6d50a3a71 100644 --- a/docs/man/index.html +++ b/docs/man/index.html @@ -437,88 +437,88 @@ #footer-text{color:rgba(0,0,0,.6);font-size:.9em}} @media amzn-kf8{#header,#content,#footnotes,#footer{padding:0}} - - - + + +
@@ -550,7 +550,7 @@

Picocli Built-In Tools

diff --git a/docs/man/picocli.AutoComplete.html b/docs/man/picocli.AutoComplete.html index 60da6f00a..48e72c34e 100644 --- a/docs/man/picocli.AutoComplete.html +++ b/docs/man/picocli.AutoComplete.html @@ -574,7 +574,7 @@

Example

-
java -cp "myapp.jar;picocli-4.6.1.jar" \
+
java -cp "myapp.jar;picocli-4.6.2.jar" \
             picocli.AutoComplete my.pkg.MyClass
@@ -583,8 +583,8 @@

Example

diff --git a/docs/migrating-from-commons-cli.html b/docs/migrating-from-commons-cli.html index c2afadab6..1a4b29c58 100644 --- a/docs/migrating-from-commons-cli.html +++ b/docs/migrating-from-commons-cli.html @@ -528,81 +528,81 @@ .CodeRay .change .change{color:#66f} .CodeRay .head .head{color:#f4f} - - - + + + @@ -610,7 +610,7 @@

Migrating from Commons CLI to picocli

Remko Popma
-version 4.6.1, +version 4.6.2, 2018-11-19
@@ -1050,7 +1050,7 @@

Conclusion

diff --git a/docs/picocli-2.0-do-more-with-less.html b/docs/picocli-2.0-do-more-with-less.html index 12c9c158b..007cc40f8 100644 --- a/docs/picocli-2.0-do-more-with-less.html +++ b/docs/picocli-2.0-do-more-with-less.html @@ -527,88 +527,88 @@ .CodeRay .change .change{color:#66f} .CodeRay .head .head{color:#f4f} - - - + + +
@@ -997,7 +997,7 @@

Conclusion

diff --git a/docs/picocli-2.0-groovy-scripts-on-steroids.html b/docs/picocli-2.0-groovy-scripts-on-steroids.html index c06af78eb..6ed41b031 100644 --- a/docs/picocli-2.0-groovy-scripts-on-steroids.html +++ b/docs/picocli-2.0-groovy-scripts-on-steroids.html @@ -527,88 +527,88 @@ .CodeRay .change .change{color:#66f} .CodeRay .head .head{color:#f4f} - - - + + +
@@ -887,7 +887,7 @@

Conclusion

diff --git a/docs/picocli-on-graalvm.html b/docs/picocli-on-graalvm.html index a6686355a..0b4053eaf 100644 --- a/docs/picocli-on-graalvm.html +++ b/docs/picocli-on-graalvm.html @@ -438,88 +438,88 @@ @media amzn-kf8{#header,#content,#footnotes,#footer{padding:0}} - - - + + +
@@ -735,7 +735,7 @@

Conclusion

diff --git a/docs/picocli-programmatic-api.adoc b/docs/picocli-programmatic-api.adoc index 91c2944da..1660e906c 100644 --- a/docs/picocli-programmatic-api.adoc +++ b/docs/picocli-programmatic-api.adoc @@ -1,8 +1,8 @@ = Programmatic API //:author: Remko Popma //:email: rpopma@apache.org -:revnumber: 4.6.2-SNAPSHOT -:revdate: 2021-01-03 +:revnumber: 4.6.2 +:revdate: 2021-11-05 :toc: left :numbered: :toclevels: 2 diff --git a/docs/picocli-programmatic-api.html b/docs/picocli-programmatic-api.html index f9f0ca863..28d707501 100644 --- a/docs/picocli-programmatic-api.html +++ b/docs/picocli-programmatic-api.html @@ -438,89 +438,89 @@ @media amzn-kf8{#header,#content,#footnotes,#footer{padding:0}} - - - + + +