diff --git a/build.gradle b/build.gradle
index 92e709391..d6250a90e 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,300 +1,300 @@
-group 'info.picocli'
-description 'Java command line parser with both an annotations API and a programmatic API. Usage help with ANSI styles and colors. Autocomplete. Nested subcommands. Easily included as source to avoid adding a dependency.'
-version '3.3.1-SNAPSHOT'
-
-// for bumpVersion task
-def oldVersion = '3\\.3\\.0'
-def oldRevdate = '2018\\-07\\-14'
-def revDate = '2018-07-14'
-
-// for bumpReadmeVersion task
-def previousReleaseVersion = '3.3.0'
-
-buildscript {
- repositories {
- jcenter()
- }
-
- dependencies {
- classpath 'org.asciidoctor:asciidoctor-gradle-plugin:1.5.3'
- }
-}
-
-allprojects {
- apply plugin: 'groovy'
- apply plugin: 'java'
- sourceCompatibility = 1.5
- targetCompatibility = 1.5
-
- repositories {
- jcenter()
- }
-
- configurations {
- ivy
- }
- dependencies {
- compileOnly 'org.codehaus.groovy:groovy-all:2.4.10'
- ivy 'org.apache.ivy:ivy:2.4.0' // for Gradle
- testCompile 'junit:junit:4.12',
- 'org.hamcrest:hamcrest-core:1.3',
- 'org.fusesource.jansi:jansi:1.15',
- 'org.codehaus.groovy:groovy-all:2.4.10',
- 'com.github.stefanbirkner:system-rules:1.17.1'
-
- }
- tasks.withType(GroovyCompile) {
- // this, and the `configurations {ivy}` section, are a workaround for the dreaded
- // java.lang.NoClassDefFoundError: org/apache/ivy/core/report/ResolveReport
- // that occurs when trying to compile a groovy script containing a @Grab annotation in gradle.
- // see https://stackoverflow.com/questions/18173908/error-compiling-a-groovy-project-using-grab-annotation
- groovyClasspath += configurations.ivy
- }
-}
-project('examples') {
- dependencies {
- compile rootProject
- compile 'org.apache.ivy:ivy:2.4.0', // for Intelli/J
- 'org.codehaus.groovy:groovy-all:2.4.10'
- }
- def generatedResources = "$buildDir/generated-resources/main"
- sourceSets {
- main {
- //register an output folder on the main SourceSet:
- output.dir(generatedResources, builtBy: 'generateVersionTxt')
- //it is now a part of the 'main' classpath and will be a part of the jar
- }
- }
-
- //a task that generates the resources for the example VersionProviderDemo1:
- task generateVersionTxt {
- description 'Creates a version.txt file with build info that is added to the root of the examples jar'
- doLast {
- new File(generatedResources).mkdirs()
- def generated = new File(generatedResources, "version.txt")
- generated.text = """
-Version: $rootProject.version
-Buildtime: ${new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())}
-Application-name: $rootProject.name $project.name
-"""
- }
- }
-}
-apply plugin: 'org.asciidoctor.convert'
-apply plugin: 'jacoco'
-apply plugin: 'distribution'
-apply plugin: 'maven-publish'
-
-
-jar {
- manifest {
- attributes 'Specification-Title' : 'picocli',
- 'Specification-Vendor' : 'Remko Popma',
- 'Specification-Version' : version,
- 'Implementation-Title' : 'picocli',
- 'Implementation-Vendor' : 'Remko Popma',
- 'Implementation-Version': version,
- 'Main-Class' : 'picocli.AutoComplete',
- 'Automatic-Module-Name' : 'info.picocli'
- }
-}
-javadoc {
- options.overview = "src/main/java/overview.html"
- destinationDir = file("build/docs/apidocs")
-}
-javadoc.dependsOn('asciidoctor')
-
-jacocoTestReport {
- reports {
- xml.enabled true
- html.enabled false
- }
-}
-task testJar(type: Jar, dependsOn: compileTestJava) {
- from sourceSets.test.output
- classifier = 'tests'
-}
-task sourcesJar(type: Jar) {
- from sourceSets.main.java.srcDirs
- classifier = 'sources'
-}
-task testSourcesJar(type: Jar) {
- from sourceSets.test.java.srcDirs
- classifier = 'test-sources'
-}
-task javadocJar(type: Jar, dependsOn: javadoc) {
- classifier = 'javadoc'
- from javadoc.destinationDir
-}
-asciidoctor {
- sourceDir = file('docs')
- outputDir = file('build/docs')
- logDocuments = true
-}
-artifacts {
- archives javadocJar
- archives sourcesJar
- archives testSourcesJar
- archives testJar
- archives jar
-}
-task bumpReadmeVersion {
- doLast {
- // README.md
- ant.replaceregexp(match: "$previousReleaseVersion", replace: "$version", flags: 'g', byline: true, encoding: 'UTF8') {
- fileset(dir: '.', includes: 'README.md')
- }
- }
-}
-task bumpVersion {
- doLast {
- ant.replaceregexp(match: "\"$oldVersion\"", replace: "\"$version\"", flags: 'g', byline: true, encoding: 'UTF8') {
- fileset(dir: 'src/main/java/picocli', includes: 'CommandLine.java')
- fileset(dir: 'src/test/java/picocli', includes: 'CommandLineTest.java')
- }
- ant.replaceregexp(match: "version $oldVersion", replace: "version $version", flags: 'g', byline: true, encoding: 'UTF8') {
- fileset(dir: 'src/test/java/picocli', includes: 'AutoCompleteTest.java')
- }
- // Doc header
- ant.replaceregexp(match: ":revnumber: $oldVersion", replace: ":revnumber: $version", flags: 'g', byline: true, encoding: 'UTF8') {
- fileset(dir: 'docs', includes: 'index.adoc')
- fileset(dir: 'docs', includes: 'autocomplete.adoc')
- fileset(dir: 'docs', includes: 'picocli-3.0-programmatic-api.adoc')
- }
- // Downloads section, Gradle
- ant.replaceregexp(match: ":picocli:$oldVersion", replace: ":picocli:$version", flags: 'g', byline: true, encoding: 'UTF8') {
- fileset(dir: 'docs', includes: 'index.adoc')
- }
- // Downloads section, Maven
- ant.replaceregexp(match: "$oldVersion", replace: "$version", flags: 'g', byline: true, encoding: 'UTF8') {
- fileset(dir: 'docs', includes: 'index.adoc')
- }
- // Downloads section, SBT
- ant.replaceregexp(match: "\"picocli\" % \"$oldVersion\"", replace: "\\\"picocli\\\" % \\\"$version\\\"", flags: 'g', byline: true, encoding: 'UTF8') {
- fileset(dir: 'docs', includes: 'index.adoc')
- }
- // Downloads section, Ivy
- ant.replaceregexp(match: "rev=\"$oldVersion\"", replace: "rev=\\\"$version\\\"", flags: 'g', byline: true, encoding: 'UTF8') {
- fileset(dir: 'docs', includes: 'index.adoc')
- }
- ant.replaceregexp(match: oldRevdate, replace: revDate, flags: 'g', byline: true, encoding: 'UTF8') {
- fileset(dir: 'docs', includes: 'index.adoc')
- fileset(dir: 'docs', includes: 'autocomplete.adoc')
- fileset(dir: 'docs', includes: 'picocli-3.0-programmatic-api.adoc')
- }
- }
-}
-task copyDocs(type: Copy) {
- from('build/docs/html5/') { include '*.html' }
- from('build/docs/') { exclude 'html5'}
- into 'docs'
-}
-
-distributions {
- main {
- baseName = "$archivesBaseName-all"
- contents {
- from jar
- from sourcesJar
- from testJar
- from testSourcesJar
- from javadocJar
- from ('LICENSE')
- from ('RELEASE-NOTES.md')
- }
- }
-}
-ext {
- bintrayBaseUrl = 'https://api.bintray.com/maven'
- bintrayRepository = 'picocli'
- bintrayPackage = 'picocli'
- bintrayUsername = System.getenv('BINTRAY_USER')
- bintrayApiKey = System.getenv('BINTRAY_KEY')
-}
-publishing {
- publications {
- plugin(MavenPublication) {
- from components.java
- artifact sourcesJar
- artifact testJar
- artifact testSourcesJar
- artifact javadocJar
- pom.withXml {
- def root = asNode()
- root.appendNode('packaging', 'jar')
- root.appendNode('name', 'picocli - a mighty tiny Command Line Interface')
- root.appendNode('description', description)
- root.appendNode('url', 'http://picocli.info')
- root.appendNode('inceptionYear', '2017')
-
- def license = root.appendNode('licenses').appendNode('license')
- license.appendNode('name', 'The Apache Software License, version 2.0')
- license.appendNode('url', 'http://www.apache.org/licenses/LICENSE-2.0.txt')
- license.appendNode('distribution', 'repo')
-
- def developer = root.appendNode('developers').appendNode('developer')
- developer.appendNode('id', 'rpopma')
- developer.appendNode('name', 'Remko Popma')
- developer.appendNode('email', 'rpopma@apache.org')
-
- def scm = root.appendNode('scm')
- scm.appendNode('connection', 'scm:git:https://github.com/remkop/picocli.git')
- scm.appendNode('developerConnection', 'scm:git:ssh://github.com:remkop/picocli.git')
- scm.appendNode('url', 'https://github.com/remkop/picocli/tree/master')
- }
- }
- }
- repositories {
- maven {
- name 'myLocal'
- url "file://$projectDir/../repo/$bintrayUsername"
- }
- maven {
- name 'Bintray'
- url "$bintrayBaseUrl/$bintrayUsername/$bintrayRepository/$bintrayPackage"
- credentials {
- username = bintrayUsername
- password = bintrayApiKey
- }
- }
- }
-}
-/*
-Release procedure:
-1. edit version numbers: remove -SNAPSHOT classifier
-2. gradlew bumpVersion
-3. check modified files
-4. gradlew clean build
-5. gradlew copyDocs
-6. update RELEASE-NOTES.md
-7. gradlew bumpReadmeVersion
-7a update README.md (latest version, release notes)
-8. commit -m "Release picocli version ..."
-9. tag v$version
-10. gradlew publishPluginPublicationToBintrayRepository
-
-11. edit version numbers: increase minor version and add -SNAPSHOT classifier
-12. gradlew bumpVersion
-13. check modified files
-14. commit -m "Prepare for next development cycle"
-15. push (make sure that Push Tags is checked)
-
-16. Log in to GitHub, go to https://github.com/remkop/picocli/releases
-17. Click the new tag, click Edit button, update title and release notes (copy from RELEASE-NOTES.md)
-18. Upload picocli-$version.jar and picocli-all$version.zip to GitHub
-
-19. Log in to Bintray
-20. Navigate to the page for the new version
-21. Edit version: Publication Date, Description, VCS tag, GitHub release notes file (RELEASE-NOTES.md)
-22. On the version page, Release Notes tab, select GitHub File
-23. Publish artifacts to JCenter
-24. On the version page, Maven Central tab, sync to Maven (takes several minutes)
-
-(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 `previousReleaseVersion` in build.gradle
-29. gradlew copyDocs
-30. commit -m "Update master for release x.x (from branch x.x)"
-*/
+group 'info.picocli'
+description 'Java command line parser with both an annotations API and a programmatic API. Usage help with ANSI styles and colors. Autocomplete. Nested subcommands. Easily included as source to avoid adding a dependency.'
+version '3.3.1-SNAPSHOT'
+
+// for bumpVersion task
+def oldVersion = '3\\.3\\.0'
+def oldRevdate = '2018\\-07\\-14'
+def revDate = '2018-07-14'
+
+// for bumpReadmeVersion task
+def previousReleaseVersion = '3.3.0'
+
+buildscript {
+ repositories {
+ jcenter()
+ }
+
+ dependencies {
+ classpath 'org.asciidoctor:asciidoctor-gradle-plugin:1.5.3'
+ }
+}
+
+allprojects {
+ apply plugin: 'groovy'
+ apply plugin: 'java'
+ sourceCompatibility = 1.5
+ targetCompatibility = 1.5
+
+ repositories {
+ jcenter()
+ }
+
+ configurations {
+ ivy
+ }
+ dependencies {
+ compileOnly 'org.codehaus.groovy:groovy-all:2.4.10'
+ ivy 'org.apache.ivy:ivy:2.4.0' // for Gradle
+ testCompile 'junit:junit:4.12',
+ 'org.hamcrest:hamcrest-core:1.3',
+ 'org.fusesource.jansi:jansi:1.15',
+ 'org.codehaus.groovy:groovy-all:2.4.10',
+ 'com.github.stefanbirkner:system-rules:1.17.1'
+
+ }
+ tasks.withType(GroovyCompile) {
+ // this, and the `configurations {ivy}` section, are a workaround for the dreaded
+ // java.lang.NoClassDefFoundError: org/apache/ivy/core/report/ResolveReport
+ // that occurs when trying to compile a groovy script containing a @Grab annotation in gradle.
+ // see https://stackoverflow.com/questions/18173908/error-compiling-a-groovy-project-using-grab-annotation
+ groovyClasspath += configurations.ivy
+ }
+}
+project('examples') {
+ dependencies {
+ compile rootProject
+ compile 'org.apache.ivy:ivy:2.4.0', // for Intelli/J
+ 'org.codehaus.groovy:groovy-all:2.4.10'
+ }
+ def generatedResources = "$buildDir/generated-resources/main"
+ sourceSets {
+ main {
+ //register an output folder on the main SourceSet:
+ output.dir(generatedResources, builtBy: 'generateVersionTxt')
+ //it is now a part of the 'main' classpath and will be a part of the jar
+ }
+ }
+
+ //a task that generates the resources for the example VersionProviderDemo1:
+ task generateVersionTxt {
+ description 'Creates a version.txt file with build info that is added to the root of the examples jar'
+ doLast {
+ new File(generatedResources).mkdirs()
+ def generated = new File(generatedResources, "version.txt")
+ generated.text = """
+Version: $rootProject.version
+Buildtime: ${new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())}
+Application-name: $rootProject.name $project.name
+"""
+ }
+ }
+}
+apply plugin: 'org.asciidoctor.convert'
+apply plugin: 'jacoco'
+apply plugin: 'distribution'
+apply plugin: 'maven-publish'
+
+
+jar {
+ manifest {
+ attributes 'Specification-Title' : 'picocli',
+ 'Specification-Vendor' : 'Remko Popma',
+ 'Specification-Version' : version,
+ 'Implementation-Title' : 'picocli',
+ 'Implementation-Vendor' : 'Remko Popma',
+ 'Implementation-Version': version,
+ 'Main-Class' : 'picocli.AutoComplete',
+ 'Automatic-Module-Name' : 'info.picocli'
+ }
+}
+javadoc {
+ options.overview = "src/main/java/overview.html"
+ destinationDir = file("build/docs/apidocs")
+}
+javadoc.dependsOn('asciidoctor')
+
+jacocoTestReport {
+ reports {
+ xml.enabled true
+ html.enabled false
+ }
+}
+task testJar(type: Jar, dependsOn: compileTestJava) {
+ from sourceSets.test.output
+ classifier = 'tests'
+}
+task sourcesJar(type: Jar) {
+ from sourceSets.main.java.srcDirs
+ classifier = 'sources'
+}
+task testSourcesJar(type: Jar) {
+ from sourceSets.test.java.srcDirs
+ classifier = 'test-sources'
+}
+task javadocJar(type: Jar, dependsOn: javadoc) {
+ classifier = 'javadoc'
+ from javadoc.destinationDir
+}
+asciidoctor {
+ sourceDir = file('docs')
+ outputDir = file('build/docs')
+ logDocuments = true
+}
+artifacts {
+ archives javadocJar
+ archives sourcesJar
+ archives testSourcesJar
+ archives testJar
+ archives jar
+}
+task bumpReadmeVersion {
+ doLast {
+ // README.md
+ ant.replaceregexp(match: "$previousReleaseVersion", replace: "$version", flags: 'g', byline: true, encoding: 'UTF8') {
+ fileset(dir: '.', includes: 'README.md')
+ }
+ }
+}
+task bumpVersion {
+ doLast {
+ ant.replaceregexp(match: "\"$oldVersion\"", replace: "\"$version\"", flags: 'g', byline: true, encoding: 'UTF8') {
+ fileset(dir: 'src/main/java/picocli', includes: 'CommandLine.java')
+ fileset(dir: 'src/test/java/picocli', includes: 'CommandLineTest.java')
+ }
+ ant.replaceregexp(match: "version $oldVersion", replace: "version $version", flags: 'g', byline: true, encoding: 'UTF8') {
+ fileset(dir: 'src/test/java/picocli', includes: 'AutoCompleteTest.java')
+ }
+ // Doc header
+ ant.replaceregexp(match: ":revnumber: $oldVersion", replace: ":revnumber: $version", flags: 'g', byline: true, encoding: 'UTF8') {
+ fileset(dir: 'docs', includes: 'index.adoc')
+ fileset(dir: 'docs', includes: 'autocomplete.adoc')
+ fileset(dir: 'docs', includes: 'picocli-3.0-programmatic-api.adoc')
+ }
+ // Downloads section, Gradle
+ ant.replaceregexp(match: ":picocli:$oldVersion", replace: ":picocli:$version", flags: 'g', byline: true, encoding: 'UTF8') {
+ fileset(dir: 'docs', includes: 'index.adoc')
+ }
+ // Downloads section, Maven
+ ant.replaceregexp(match: "$oldVersion", replace: "$version", flags: 'g', byline: true, encoding: 'UTF8') {
+ fileset(dir: 'docs', includes: 'index.adoc')
+ }
+ // Downloads section, SBT
+ ant.replaceregexp(match: "\"picocli\" % \"$oldVersion\"", replace: "\\\"picocli\\\" % \\\"$version\\\"", flags: 'g', byline: true, encoding: 'UTF8') {
+ fileset(dir: 'docs', includes: 'index.adoc')
+ }
+ // Downloads section, Ivy
+ ant.replaceregexp(match: "rev=\"$oldVersion\"", replace: "rev=\\\"$version\\\"", flags: 'g', byline: true, encoding: 'UTF8') {
+ fileset(dir: 'docs', includes: 'index.adoc')
+ }
+ ant.replaceregexp(match: oldRevdate, replace: revDate, flags: 'g', byline: true, encoding: 'UTF8') {
+ fileset(dir: 'docs', includes: 'index.adoc')
+ fileset(dir: 'docs', includes: 'autocomplete.adoc')
+ fileset(dir: 'docs', includes: 'picocli-3.0-programmatic-api.adoc')
+ }
+ }
+}
+task copyDocs(type: Copy) {
+ from('build/docs/html5/') { include '*.html' }
+ from('build/docs/') { exclude 'html5'}
+ into 'docs'
+}
+
+distributions {
+ main {
+ baseName = "$archivesBaseName-all"
+ contents {
+ from jar
+ from sourcesJar
+ from testJar
+ from testSourcesJar
+ from javadocJar
+ from ('LICENSE')
+ from ('RELEASE-NOTES.md')
+ }
+ }
+}
+ext {
+ bintrayBaseUrl = 'https://api.bintray.com/maven'
+ bintrayRepository = 'picocli'
+ bintrayPackage = 'picocli'
+ bintrayUsername = System.getenv('BINTRAY_USER')
+ bintrayApiKey = System.getenv('BINTRAY_KEY')
+}
+publishing {
+ publications {
+ plugin(MavenPublication) {
+ from components.java
+ artifact sourcesJar
+ artifact testJar
+ artifact testSourcesJar
+ artifact javadocJar
+ pom.withXml {
+ def root = asNode()
+ root.appendNode('packaging', 'jar')
+ root.appendNode('name', 'picocli - a mighty tiny Command Line Interface')
+ root.appendNode('description', description)
+ root.appendNode('url', 'http://picocli.info')
+ root.appendNode('inceptionYear', '2017')
+
+ def license = root.appendNode('licenses').appendNode('license')
+ license.appendNode('name', 'The Apache Software License, version 2.0')
+ license.appendNode('url', 'http://www.apache.org/licenses/LICENSE-2.0.txt')
+ license.appendNode('distribution', 'repo')
+
+ def developer = root.appendNode('developers').appendNode('developer')
+ developer.appendNode('id', 'rpopma')
+ developer.appendNode('name', 'Remko Popma')
+ developer.appendNode('email', 'rpopma@apache.org')
+
+ def scm = root.appendNode('scm')
+ scm.appendNode('connection', 'scm:git:https://github.com/remkop/picocli.git')
+ scm.appendNode('developerConnection', 'scm:git:ssh://github.com:remkop/picocli.git')
+ scm.appendNode('url', 'https://github.com/remkop/picocli/tree/master')
+ }
+ }
+ }
+ repositories {
+ maven {
+ name 'myLocal'
+ url "file://$projectDir/../repo/$bintrayUsername"
+ }
+ maven {
+ name 'Bintray'
+ url "$bintrayBaseUrl/$bintrayUsername/$bintrayRepository/$bintrayPackage"
+ credentials {
+ username = bintrayUsername
+ password = bintrayApiKey
+ }
+ }
+ }
+}
+/*
+Release procedure:
+1. edit version numbers: remove -SNAPSHOT classifier
+2. gradlew bumpVersion
+3. check modified files
+4. gradlew clean build
+5. gradlew copyDocs
+6. update RELEASE-NOTES.md
+7. gradlew bumpReadmeVersion
+7a update README.md (latest version, release notes)
+8. commit -m "Release picocli version ..."
+9. tag v$version
+10. gradlew publishPluginPublicationToBintrayRepository
+
+11. edit version numbers: increase minor version and add -SNAPSHOT classifier
+12. gradlew bumpVersion
+13. check modified files
+14. commit -m "Prepare for next development cycle"
+15. push (make sure that Push Tags is checked)
+
+16. Log in to GitHub, go to https://github.com/remkop/picocli/releases
+17. Click the new tag, click Edit button, update title and release notes (copy from RELEASE-NOTES.md)
+18. Upload picocli-$version.jar and picocli-all$version.zip to GitHub
+
+19. Log in to Bintray
+20. Navigate to the page for the new version
+21. Edit version: Publication Date, Description, VCS tag, GitHub release notes file (RELEASE-NOTES.md)
+22. On the version page, Release Notes tab, select GitHub File
+23. Publish artifacts to JCenter
+24. On the version page, Maven Central tab, sync to Maven (takes several minutes)
+
+(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 `previousReleaseVersion` in build.gradle
+29. gradlew copyDocs
+30. commit -m "Update master for release x.x (from branch x.x)"
+*/
diff --git a/docs/autocomplete.adoc b/docs/autocomplete.adoc
index 00ff2a806..318a70aa9 100644
--- a/docs/autocomplete.adoc
+++ b/docs/autocomplete.adoc
@@ -1,349 +1,349 @@
-= Autocomplete for Java Command Line Applications
-//:author: Remko Popma
-//:email: rpopma@apache.org
-:revnumber: 3.3.1-SNAPSHOT
-:revdate: 2018-07-14
-:toc: left
-:numbered:
-:toclevels: 3
-:toc-title: Table of Contents
-:source-highlighter: coderay
-:icons: font
-:imagesdir: images
-
-[link=https://github.com/remkop/picocli]
-image::https://s3.amazonaws.com/github/ribbons/forkme_right_red_aa0000.png[Fork me on GitHub,float="right"]
-[quote]
-Every main method deserves picocli!
-
-== Command Line Completion
-Starting from version 1.0.0, picocli-based applications can have command line completion in Bash or ZSH Unix shells.
-Picocli can generate an autocompletion script tailored to your application.
-
-With this script installed, users can type the first few letters of a subcommand or an option,
-then press the TAB key, and the Unix shell will complete the subcommand or option.
-
-In the case of multiple possible completions, the Unix shell will display all subcommands or options beginning
-with those few characters. The user can type more characters and press TAB again to see a new, narrowed-down
-list if the typed characters are still ambiguous, or else complete the subcommand or option.
-
-image:picocli-autocompletion-demo.gif[Autocompletion demo animation]
-
-== Quick Start Tutorial
-This tutorial uses the link:index.html#CheckSum-application[CheckSum example application] from the picocli user manual. We created a class `com.myproject.CheckSum` and put it in a jar file, `myproject.jar`.
-
-Follow these steps to give this application command line autocompletion.
-
-=== Create Command
-First, create an executable command that runs the main application class. For this tutorial, the command name is `jchecksum`.
-
-We use an https://en.wikipedia.org/wiki/Alias_(command)[alias] here to create the command (see <>):
-
-[source,bash]
-----
-alias jchecksum='java -cp "picocli-1.0.0.jar;myproject.jar" com.myproject.CheckSum'
-----
-
-Let's test that the command works:
-
-[source,bash]
-----
-$ jchecksum --help
-Usage: jchecksum [-h] [-a=]
-Prints the checksum (MD5 by default) of a file to STDOUT.
- file The file whose checksum to calculate.
- -a, --algorithm= MD5, SHA-1, SHA-256, ...
- -h, --help Show this help message and exit.
-----
-
-=== Generate Completion Script
-To generate the completion script, run the `picocli.AutoComplete` class as a java application. Pass it the command name and the fully qualified class name of the annotated command class. (See also <> for using `AutoComplete`.)
-
-[source,bash]
-----
-java -cp "picocli-1.0.0.jar;myproject.jar" picocli.AutoComplete -n jchecksum com.myproject.CheckSum
-----
-
-This generated a `jchecksum_completion` script in the current directory. To verify:
-
-[source,bash]
-----
-$ ls
-jchecksum_completion myproject.jar picocli-1.0.0.jar
-----
-
-=== Install Completion Script
-Finally, http://tldp.org/HOWTO/Bash-Prompt-HOWTO/x237.html[source] the completion script:
-
-.Bash
-[source,bash]
-----
-. jchecksum_completion
-----
-
-.ZSH
-[source,bash]
-----
-autoload -U +X compinit && compinit
-autoload -U +X bashcompinit && bashcompinit
-. ./jchecksum_completion
-----
-
-...and you are done. The `jchecksum` command now has autocompletion:
-
-[source,bash]
-----
-$ jchecksum
--a --algorithm -h --help
-----
-
-=== Permanent Installation
-The above will last for the duration of your shell session. If you want to make this permanent you need to modify your ~/.bashrc or ~/.zshrc file to add a line that defines the command alias and a line that sources the completion script:
-
-.Bash
-[source,bash]
-----
-echo "alias jchecksum='java -cp \"picocli-1.0.0.jar;myproject.jar\" com.myproject.CheckSum'" >> ~/.bashrc
-echo ". jchecksum_completion" >> ~/.bashrc
-----
-Make sure to use `>>` (append), using a single `>` would overwrite the file.
-
-`~/.bashrc` indicates `.bashrc` is in your home directory.
-
-(See <>, <>.)
-
-== Designing for Completion
-
-When writing a link:index.html[picocli]-based command line application there are a few things to consider to facilitate autocompletion.
-
-=== Register Subcommands Declaratively
-
-Register subcommands link:index.html#_registering_subcommands_declaratively[declaratively] in your application with `@Command(subcommands = { ... })` annotations where possible.
-
-This way, you can generate a completion script by passing a single command class name to `picocli.AutoComplete`, and picocli will be able to infer the full hierarchy of command and subcommands from that top-level command class.
-
-If your application registers subcommands programmatically, you can still generate a completion script, it is just <>.
-
-=== Use Strong Typing
-When generating the completion script, picocli inspects the type of the fields annotated with `@Option`. For some types,
-tab completion can also generate possible option _values_.
-
-Picocli can generate completion matches for the following types:
-
-* `java.io.File`
-* `java.nio.file.Path`
-* `java.net.InetAddress`
-* any java `enum`
-
-==== Files and Directories
-Generating autocomplete matches for `@Option` fields of type `java.io.File` or `java.nio.file.Path` will display a list of all files and directories in the current directory.
-
-[source,bash]
-----
-$ demo --file
-basic.bash hierarchy nestedSubcommands.bash
-----
-
-==== Host Names
-Generating autocomplete matches for `@Option` fields of type `java.net.InetAddress` will display a list of known hosts (from your `/etc/hosts` file).
-
-[source,bash]
-----
-$ demo --host
-cluster-p-1 openvpn-client.myvpn.picocli.com
-cluster-p-2 picop1
-cluster-p-3 picop2
-cluster-p-4 picop3
-cluster-scm-1 picop4
-client.openvpn.net picoscm1
-----
-
-==== Java `enum` Values
-Generating autocomplete matches for `@Option` fields of any Java `enum` type will display the list of enum values.
-
-For example:
-
-[source,bash]
-----
-$ demo --timeUnit
-DAYS HOURS MICROSECONDS MILLISECONDS MINUTES NANOSECONDS SECONDS
-----
-
-
-=== Other Completion Candidates
-Picocli 3.2 introduces a `completionCandidates` API that can be used to generate completion candidates
-regardless of the type of the option or positional parameter.
-
-Picocli calls this iterator when the completion script is generated.
-
-== Alternative Ways to Define Commands
-This section describes creating commands in more depth than the <>.
-
-In Bash and ZSH, there are multiple ways to create an executable command for a java class.
-
-=== Alias
-One way is to define an alias:
-
-[source,bash]
-----
-alias jchecksum='java -cp "picocli-1.0.0.jar;myproject.jar" com.myproject.CheckSum'
-----
-
-Be aware that the alias only lasts as long as the current shell session.
-To make it permanent, add it to your `~/.bashrc` or `~/.zshrc` file.
-
-You may also want to specify the full path to the jar files in the classpath so that the command can be executed anywhere.
-
-=== Function
-Another way is to define a function:
-
-[source,bash]
-----
-jchecksum() {
- java -cp "picocli-1.0.0.jar;myproject.jar" com.myproject.CheckSum "$@"
-}
-----
-
-To make it permanent, add it to your `~/.bashrc` or `~/.zshrc` file.
-
-
-=== Script
-Yet another way is to create a script:
-
-[source,bash]
-----
-$ echo '#!/usr/bin/env bash' > jchecksum
-$ echo 'java -cp "picocli-1.0.0.jar;myproject.jar" com.myproject.CheckSum $@' >> jchecksum
-$ chmod 755 jchecksum
-
-$ cat jchecksum
-#!/usr/bin/env bash
-java -cp "picocli-1.0.0.jar;myproject.jar" com.myproject.CheckSum $@
-----
-
-== Completion Script Generation Details
-This section describes generating completion scripts in more depth than the <>.
-
-=== Running AutoComplete
-
-To generate the completion script, run the `picocli.AutoComplete` class as a java application, passing it
-the fully qualified class name of the annotated command object.
-
-[source,bash]
-----
-$ java -cp "picocli-1.0.0.jar;myproject.jar" picocli.AutoComplete com.myproject.CheckSum
-----
-
-This will instantiate your command, and inspect it for http://picocli.info/apidocs/picocli/CommandLine.Option.html[`@Option`]
-and http://picocli.info/apidocs/picocli/CommandLine.Command.html[`@Command`] annotations.
-Based on these annotations it will generate a completion script in the current directory.
-
-Because of this, the command class needs to be on the classpath when running the `picocli.AutoComplete` class.
-
-=== Command Name
-The name of the generated completion script is based on the `@Command(name ="")` link:index.html#_command_name[annotation], or, if that is missing, the command class name.
-Use the `-n` or `--name` option to control the name of the command that the completion script is for.
-
-[source,bash]
-----
-$ java -cp "picocli-1.0.0.jar;myproject.jar" picocli.AutoComplete -n jchecksum com.myproject.CheckSum
-----
-
-This will generate a `jchecksum_completion` script in the current directory.
-
-Other options are:
-
-* Use `-o` or `--completionScript` to specify the full path to the completion script to generate.
-* Use the `-f` or `--force` option to overwrite existing files.
-* Use the `-w`, `--writeCommandScript` option to generate a sample command script.
-
-=== Subcommands
-For commands with subcommands, bear in mind that the class that generates the completion script (`picocli.AutoComplete`)
-needs the full hierarchy of command and subcommands to generate a completion script that also works for the subcommands.
-
-The above will work when subcommands are registered declaratively with annotations like `@Command(subcommands = { ... })`.
-
-=== Programmatically Registered Subcommands
-When subcommands are not registered declaratively, you need to do a bit more work. You need to create a small program that does the following:
-
-* Create a `CommandLine` instance with the full hierarchy of nested subcommands.
-
-[source,java]
-----
-// programmatically (see above for declarative example)
-CommandLine hierarchy = new CommandLine(new TopLevel())
- .addSubcommand("sub1", new Subcommand1())
- .addSubcommand("sub2", new Subcommand2());
-----
-
-* Pass this `CommandLine` instance and the name of the script to the `picocli.AutoComplete::bash` method. The method will return the source code of a completion script. Save the source code to a file and install it.
-
-
-== Installing Completion Scripts Permanently in Bash
-This section describes installing completion scripts in more depth than the <>.
-
-Make sure bash completion is installed.
-
-http://tldp.org/HOWTO/Bash-Prompt-HOWTO/x237.html[Source] the generated completion script to install it in your current bash session.
-
-To install it more permanently, place the completion script file in `/etc/bash_completion.d` (or `/usr/local/etc/bash_completion.d` on a Mac). If `bash-completion` is installed, placing the completion script in either of these directories should be sufficient. (Source your `~/.bash_profile` or launch a new terminal to start using this completion script.)
-
-Alternatively, make a directory `mkdir ~/bash_completion.d`, and place the completion script in this directory. Edit your `~/.bashrc` file and add the following:
-
-[source,bash]
-----
-for bcfile in ~/bash_completion.d/* ; do
- . $bcfile
-done
-----
-
-All completion scripts in the `~/bash_completion.d` directory will now be available every time you launch a new shell.
-
-Source your `~/.bash_profile` or launch a new terminal to start using this completion script.
-
-
-== Installing Completion Scripts Permanently in ZSH
-This section describes installing completion scripts in more depth than the <>.
-
-Zsh can handle bash completions functions. The latest development version of zsh has a function bashcompinit, that when run will allow zsh to read bash completion specifications and functions. The zshcompsys man page has details. To use it, run bashcompinit at any time after compinit. It will define complete and compgen functions corresponding to the bash builtins.
-
-http://tldp.org/HOWTO/Bash-Prompt-HOWTO/x237.html[Source] the generated completion script to install it in your current shell session.
-
-To install it more permanently, make a directory `mkdir ~/bash_completion.d`, and place the completion script in this directory. Edit your `~/.zshrc` file and add the following:
-
-[source,bash]
-----
-autoload -U +X compinit && compinit
-autoload -U +X bashcompinit && bashcompinit
-for bcfile in ~/bash_completion.d/* ; do
- . $bcfile
-done
-----
-
-All completion scripts in the `~/bash_completion.d` directory will now be available every time you launch a new shell.
-
-Then reload your shell:
-
-[source,bash]
-----
-exec $SHELL -l
-----
-
-
-== Picocli User Manual
-The link:index.html[picocli user manual] explains how to build Java command line applications with picocli.
-
-== GitHub Project
-The https://github.com/remkop/picocli[GitHub project] has the source code, tests, build scripts, etc.
-
-Star icon:star-o[] or fork icon:code-fork[] this project on GitHub if you like it!
-(Projects with many icon:code-fork[] forks are easier to find on GitHub Search.)
-
-== Issue Tracker
-Please use the https://github.com/remkop/picocli/issues[Issue Tracker] to report bugs or request features.
-
-== License
-Picocli is licensed under the https://github.com/remkop/picocli/blob/master/LICENSE[Apache License 2.0].
-
-== Releases
-Previous versions are available from the GitHub project https://github.com/remkop/picocli/releases[Releases].
+= Autocomplete for Java Command Line Applications
+//:author: Remko Popma
+//:email: rpopma@apache.org
+:revnumber: 3.3.1-SNAPSHOT
+:revdate: 2018-07-14
+:toc: left
+:numbered:
+:toclevels: 3
+:toc-title: Table of Contents
+:source-highlighter: coderay
+:icons: font
+:imagesdir: images
+
+[link=https://github.com/remkop/picocli]
+image::https://s3.amazonaws.com/github/ribbons/forkme_right_red_aa0000.png[Fork me on GitHub,float="right"]
+[quote]
+Every main method deserves picocli!
+
+== Command Line Completion
+Starting from version 1.0.0, picocli-based applications can have command line completion in Bash or ZSH Unix shells.
+Picocli can generate an autocompletion script tailored to your application.
+
+With this script installed, users can type the first few letters of a subcommand or an option,
+then press the TAB key, and the Unix shell will complete the subcommand or option.
+
+In the case of multiple possible completions, the Unix shell will display all subcommands or options beginning
+with those few characters. The user can type more characters and press TAB again to see a new, narrowed-down
+list if the typed characters are still ambiguous, or else complete the subcommand or option.
+
+image:picocli-autocompletion-demo.gif[Autocompletion demo animation]
+
+== Quick Start Tutorial
+This tutorial uses the link:index.html#CheckSum-application[CheckSum example application] from the picocli user manual. We created a class `com.myproject.CheckSum` and put it in a jar file, `myproject.jar`.
+
+Follow these steps to give this application command line autocompletion.
+
+=== Create Command
+First, create an executable command that runs the main application class. For this tutorial, the command name is `jchecksum`.
+
+We use an https://en.wikipedia.org/wiki/Alias_(command)[alias] here to create the command (see <>):
+
+[source,bash]
+----
+alias jchecksum='java -cp "picocli-1.0.0.jar;myproject.jar" com.myproject.CheckSum'
+----
+
+Let's test that the command works:
+
+[source,bash]
+----
+$ jchecksum --help
+Usage: jchecksum [-h] [-a=]
+Prints the checksum (MD5 by default) of a file to STDOUT.
+ file The file whose checksum to calculate.
+ -a, --algorithm= MD5, SHA-1, SHA-256, ...
+ -h, --help Show this help message and exit.
+----
+
+=== Generate Completion Script
+To generate the completion script, run the `picocli.AutoComplete` class as a java application. Pass it the command name and the fully qualified class name of the annotated command class. (See also <> for using `AutoComplete`.)
+
+[source,bash]
+----
+java -cp "picocli-1.0.0.jar;myproject.jar" picocli.AutoComplete -n jchecksum com.myproject.CheckSum
+----
+
+This generated a `jchecksum_completion` script in the current directory. To verify:
+
+[source,bash]
+----
+$ ls
+jchecksum_completion myproject.jar picocli-1.0.0.jar
+----
+
+=== Install Completion Script
+Finally, http://tldp.org/HOWTO/Bash-Prompt-HOWTO/x237.html[source] the completion script:
+
+.Bash
+[source,bash]
+----
+. jchecksum_completion
+----
+
+.ZSH
+[source,bash]
+----
+autoload -U +X compinit && compinit
+autoload -U +X bashcompinit && bashcompinit
+. ./jchecksum_completion
+----
+
+...and you are done. The `jchecksum` command now has autocompletion:
+
+[source,bash]
+----
+$ jchecksum
+-a --algorithm -h --help
+----
+
+=== Permanent Installation
+The above will last for the duration of your shell session. If you want to make this permanent you need to modify your ~/.bashrc or ~/.zshrc file to add a line that defines the command alias and a line that sources the completion script:
+
+.Bash
+[source,bash]
+----
+echo "alias jchecksum='java -cp \"picocli-1.0.0.jar;myproject.jar\" com.myproject.CheckSum'" >> ~/.bashrc
+echo ". jchecksum_completion" >> ~/.bashrc
+----
+Make sure to use `>>` (append), using a single `>` would overwrite the file.
+
+`~/.bashrc` indicates `.bashrc` is in your home directory.
+
+(See <>, <>.)
+
+== Designing for Completion
+
+When writing a link:index.html[picocli]-based command line application there are a few things to consider to facilitate autocompletion.
+
+=== Register Subcommands Declaratively
+
+Register subcommands link:index.html#_registering_subcommands_declaratively[declaratively] in your application with `@Command(subcommands = { ... })` annotations where possible.
+
+This way, you can generate a completion script by passing a single command class name to `picocli.AutoComplete`, and picocli will be able to infer the full hierarchy of command and subcommands from that top-level command class.
+
+If your application registers subcommands programmatically, you can still generate a completion script, it is just <>.
+
+=== Use Strong Typing
+When generating the completion script, picocli inspects the type of the fields annotated with `@Option`. For some types,
+tab completion can also generate possible option _values_.
+
+Picocli can generate completion matches for the following types:
+
+* `java.io.File`
+* `java.nio.file.Path`
+* `java.net.InetAddress`
+* any java `enum`
+
+==== Files and Directories
+Generating autocomplete matches for `@Option` fields of type `java.io.File` or `java.nio.file.Path` will display a list of all files and directories in the current directory.
+
+[source,bash]
+----
+$ demo --file
+basic.bash hierarchy nestedSubcommands.bash
+----
+
+==== Host Names
+Generating autocomplete matches for `@Option` fields of type `java.net.InetAddress` will display a list of known hosts (from your `/etc/hosts` file).
+
+[source,bash]
+----
+$ demo --host
+cluster-p-1 openvpn-client.myvpn.picocli.com
+cluster-p-2 picop1
+cluster-p-3 picop2
+cluster-p-4 picop3
+cluster-scm-1 picop4
+client.openvpn.net picoscm1
+----
+
+==== Java `enum` Values
+Generating autocomplete matches for `@Option` fields of any Java `enum` type will display the list of enum values.
+
+For example:
+
+[source,bash]
+----
+$ demo --timeUnit
+DAYS HOURS MICROSECONDS MILLISECONDS MINUTES NANOSECONDS SECONDS
+----
+
+
+=== Other Completion Candidates
+Picocli 3.2 introduces a `completionCandidates` API that can be used to generate completion candidates
+regardless of the type of the option or positional parameter.
+
+Picocli calls this iterator when the completion script is generated.
+
+== Alternative Ways to Define Commands
+This section describes creating commands in more depth than the <>.
+
+In Bash and ZSH, there are multiple ways to create an executable command for a java class.
+
+=== Alias
+One way is to define an alias:
+
+[source,bash]
+----
+alias jchecksum='java -cp "picocli-1.0.0.jar;myproject.jar" com.myproject.CheckSum'
+----
+
+Be aware that the alias only lasts as long as the current shell session.
+To make it permanent, add it to your `~/.bashrc` or `~/.zshrc` file.
+
+You may also want to specify the full path to the jar files in the classpath so that the command can be executed anywhere.
+
+=== Function
+Another way is to define a function:
+
+[source,bash]
+----
+jchecksum() {
+ java -cp "picocli-1.0.0.jar;myproject.jar" com.myproject.CheckSum "$@"
+}
+----
+
+To make it permanent, add it to your `~/.bashrc` or `~/.zshrc` file.
+
+
+=== Script
+Yet another way is to create a script:
+
+[source,bash]
+----
+$ echo '#!/usr/bin/env bash' > jchecksum
+$ echo 'java -cp "picocli-1.0.0.jar;myproject.jar" com.myproject.CheckSum $@' >> jchecksum
+$ chmod 755 jchecksum
+
+$ cat jchecksum
+#!/usr/bin/env bash
+java -cp "picocli-1.0.0.jar;myproject.jar" com.myproject.CheckSum $@
+----
+
+== Completion Script Generation Details
+This section describes generating completion scripts in more depth than the <>.
+
+=== Running AutoComplete
+
+To generate the completion script, run the `picocli.AutoComplete` class as a java application, passing it
+the fully qualified class name of the annotated command object.
+
+[source,bash]
+----
+$ java -cp "picocli-1.0.0.jar;myproject.jar" picocli.AutoComplete com.myproject.CheckSum
+----
+
+This will instantiate your command, and inspect it for http://picocli.info/apidocs/picocli/CommandLine.Option.html[`@Option`]
+and http://picocli.info/apidocs/picocli/CommandLine.Command.html[`@Command`] annotations.
+Based on these annotations it will generate a completion script in the current directory.
+
+Because of this, the command class needs to be on the classpath when running the `picocli.AutoComplete` class.
+
+=== Command Name
+The name of the generated completion script is based on the `@Command(name ="")` link:index.html#_command_name[annotation], or, if that is missing, the command class name.
+Use the `-n` or `--name` option to control the name of the command that the completion script is for.
+
+[source,bash]
+----
+$ java -cp "picocli-1.0.0.jar;myproject.jar" picocli.AutoComplete -n jchecksum com.myproject.CheckSum
+----
+
+This will generate a `jchecksum_completion` script in the current directory.
+
+Other options are:
+
+* Use `-o` or `--completionScript` to specify the full path to the completion script to generate.
+* Use the `-f` or `--force` option to overwrite existing files.
+* Use the `-w`, `--writeCommandScript` option to generate a sample command script.
+
+=== Subcommands
+For commands with subcommands, bear in mind that the class that generates the completion script (`picocli.AutoComplete`)
+needs the full hierarchy of command and subcommands to generate a completion script that also works for the subcommands.
+
+The above will work when subcommands are registered declaratively with annotations like `@Command(subcommands = { ... })`.
+
+=== Programmatically Registered Subcommands
+When subcommands are not registered declaratively, you need to do a bit more work. You need to create a small program that does the following:
+
+* Create a `CommandLine` instance with the full hierarchy of nested subcommands.
+
+[source,java]
+----
+// programmatically (see above for declarative example)
+CommandLine hierarchy = new CommandLine(new TopLevel())
+ .addSubcommand("sub1", new Subcommand1())
+ .addSubcommand("sub2", new Subcommand2());
+----
+
+* Pass this `CommandLine` instance and the name of the script to the `picocli.AutoComplete::bash` method. The method will return the source code of a completion script. Save the source code to a file and install it.
+
+
+== Installing Completion Scripts Permanently in Bash
+This section describes installing completion scripts in more depth than the <>.
+
+Make sure bash completion is installed.
+
+http://tldp.org/HOWTO/Bash-Prompt-HOWTO/x237.html[Source] the generated completion script to install it in your current bash session.
+
+To install it more permanently, place the completion script file in `/etc/bash_completion.d` (or `/usr/local/etc/bash_completion.d` on a Mac). If `bash-completion` is installed, placing the completion script in either of these directories should be sufficient. (Source your `~/.bash_profile` or launch a new terminal to start using this completion script.)
+
+Alternatively, make a directory `mkdir ~/bash_completion.d`, and place the completion script in this directory. Edit your `~/.bashrc` file and add the following:
+
+[source,bash]
+----
+for bcfile in ~/bash_completion.d/* ; do
+ . $bcfile
+done
+----
+
+All completion scripts in the `~/bash_completion.d` directory will now be available every time you launch a new shell.
+
+Source your `~/.bash_profile` or launch a new terminal to start using this completion script.
+
+
+== Installing Completion Scripts Permanently in ZSH
+This section describes installing completion scripts in more depth than the <>.
+
+Zsh can handle bash completions functions. The latest development version of zsh has a function bashcompinit, that when run will allow zsh to read bash completion specifications and functions. The zshcompsys man page has details. To use it, run bashcompinit at any time after compinit. It will define complete and compgen functions corresponding to the bash builtins.
+
+http://tldp.org/HOWTO/Bash-Prompt-HOWTO/x237.html[Source] the generated completion script to install it in your current shell session.
+
+To install it more permanently, make a directory `mkdir ~/bash_completion.d`, and place the completion script in this directory. Edit your `~/.zshrc` file and add the following:
+
+[source,bash]
+----
+autoload -U +X compinit && compinit
+autoload -U +X bashcompinit && bashcompinit
+for bcfile in ~/bash_completion.d/* ; do
+ . $bcfile
+done
+----
+
+All completion scripts in the `~/bash_completion.d` directory will now be available every time you launch a new shell.
+
+Then reload your shell:
+
+[source,bash]
+----
+exec $SHELL -l
+----
+
+
+== Picocli User Manual
+The link:index.html[picocli user manual] explains how to build Java command line applications with picocli.
+
+== GitHub Project
+The https://github.com/remkop/picocli[GitHub project] has the source code, tests, build scripts, etc.
+
+Star icon:star-o[] or fork icon:code-fork[] this project on GitHub if you like it!
+(Projects with many icon:code-fork[] forks are easier to find on GitHub Search.)
+
+== Issue Tracker
+Please use the https://github.com/remkop/picocli/issues[Issue Tracker] to report bugs or request features.
+
+== License
+Picocli is licensed under the https://github.com/remkop/picocli/blob/master/LICENSE[Apache License 2.0].
+
+== Releases
+Previous versions are available from the GitHub project https://github.com/remkop/picocli/releases[Releases].
diff --git a/docs/index.adoc b/docs/index.adoc
index 77e11f6dd..7463e852d 100644
--- a/docs/index.adoc
+++ b/docs/index.adoc
@@ -1,2849 +1,2849 @@
-= picocli - a mighty tiny command line interface
-//:author: Remko Popma
-//:email: rpopma@apache.org
-:revnumber: 3.3.1-SNAPSHOT
-:revdate: 2018-07-14
-:toc: left
-:numbered:
-:toclevels: 2
-:toc-title: Features
-:source-highlighter: coderay
-:icons: font
-:imagesdir: images
-
-[link=https://github.com/remkop/picocli]
-image::https://s3.amazonaws.com/github/ribbons/forkme_right_red_aa0000.png[Fork me on GitHub,float="right"]
-
-[quote]
-Every main method deserves picocli!
-
-image:logo/horizontal.png[picocli the Mighty Tiny Command Line Interface,width=800]
-
-The user manual for the latest release is at http://picocli.info.
-
-== Introduction
-Picocli is a one-file framework for creating Java command line applications with almost zero code.
-Supports a variety of command line syntax styles including POSIX, GNU, MS-DOS and more.
-Generates highly customizable usage help messages with <>.
-Picocli-based applications can have link:autocomplete.html[command line TAB completion] showing available options, option parameters and subcommands, for any level of nested subcommands.
-
-image:ExampleUsageANSI.png[Screenshot of usage help with Ansi codes enabled]
-
-link:autocomplete.html[Command line autocompletion] is in BETA. Comments, bug reports, pull requests welcome!
-
-
-A distinguishing feature of picocli is how it aims
-to let users run picocli-based applications without requiring picocli as an external dependency:
-all the source code lives in a single file, to encourage application authors to include it _in source form_.
-
-How it works: annotate your class and picocli initializes it from the command line arguments,
-converting the input to strongly typed values in the fields of your class.
-
-[source,java]
-----
-import picocli.CommandLine.Option;
-import picocli.CommandLine.Parameters;
-import java.io.File;
-
-public class Example {
- @Option(names = { "-v", "--verbose" }, description = "Be verbose.")
- private boolean verbose = false;
-
- @Parameters(arity = "1..*", paramLabel = "FILE", description = "File(s) to process.")
- private File[] inputFiles;
- ...
-}
-----
-
-Then invoke `CommandLine.parse` or `CommandLine.populateCommand` with the command line parameters and an object you want to initialize.
-
-[source,java]
-----
-String[] args = { "-v", "inputFile1", "inputFile2" };
-Example app = CommandLine.populateCommand(new Example(), args);
-assert app.verbose;
-assert app.inputFiles != null && app.inputFiles.length == 2;
-----
-
-Here is a small example application that uses the `CommandLine.call` <>
-to do parsing and error handling in one line of code. The <> attribute is all
-that is needed to give your application usage help and version help.
-
-[[CheckSum-application]]
-[source,java]
-----
-@Command(description = "Prints the checksum (MD5 by default) of a file to STDOUT.",
- name = "checksum", mixinStandardHelpOptions = true, version = "checksum 3.0")
-class CheckSum implements Callable {
-
- @Parameters(index = "0", description = "The file whose checksum to calculate.")
- private File file;
-
- @Option(names = {"-a", "--algorithm"}, description = "MD5, SHA-1, SHA-256, ...")
- private String algorithm = "MD5";
-
- public static void main(String[] args) throws Exception {
- // 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);
- }
-
- @Override
- public Void call() throws Exception {
- // your business logic goes here...
- byte[] fileContents = Files.readAllBytes(file.toPath());
- byte[] digest = MessageDigest.getInstance(algorithm).digest(fileContents);
- System.out.println(javax.xml.bind.DatatypeConverter.printHexBinary(digest));
- return null;
- }
-}
-----
-
-
-== Options and Parameters
-Command line arguments can be separated into _options_ and _positional parameters_.
-Options have a name, positional parameters are usually the values that follow the options,
-but they may be mixed.
-
-image:OptionsAndParameters2.png[Example command with annotated @Option and @Parameters]
-
-Picocli has separate annotations for options and positional parameters.
-
-=== Options
-An option must have one or more `names`.
-Picocli lets you use any option name you want.
-
-TIP: You may be interested in this http://catb.org/~esr/writings/taoup/html/ch10s05.html#id2948149[list of common option names]. Following these conventions may make your application more intuitive to use for experienced users.
-
-The below example shows options with one or more names, options that take an option parameter, and a <> option.
-[source,java]
-----
-class Tar {
- @Option(names = "-c", description = "create a new archive")
- boolean create;
-
- @Option(names = { "-f", "--file" }, paramLabel = "ARCHIVE", description = "the archive file")
- File archive;
-
- @Parameters(paramLabel = "FILE", description = "one ore more files to archive")
- File[] files;
-
- @Option(names = { "-h", "--help" }, usageHelp = true, description = "display a help message")
- private boolean helpRequested = false;
-}
-----
-Picocli matches the option names to set the field values.
-[source,java]
-----
-String[] args = { "-c", "--file", "result.tar", "file1.txt", "file2.txt" };
-Tar tar = new Tar();
-new CommandLine(tar).parse(args);
-
-assert !tar.helpRequested;
-assert tar.create;
-assert tar.archive.equals(new File("result.tar"));
-assert Arrays.equals(tar.files, new File[] {new File("file1.txt"), new File("file2.txt")});
-----
-
-=== Short Options
-Picocli supports http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap12.html#tag_12_02[POSIX clustered short options]:
-one or more single-character options without option-arguments, followed by at most one option with an option-argument, can be grouped behind one '-' delimiter.
-
-
-For example, given this annotated class:
-[source,java]
-----
-class ClusteredShortOptions {
- @Option(names = "-a") boolean aaa;
- @Option(names = "-b") boolean bbb;
- @Option(names = "-c") boolean ccc;
- @Option(names = "-f") String file;
-}
-----
-The following command line arguments are all equivalent and parsing them will give the same result:
-
-[source,java]
-----
- -abcfInputFile.txt
- -abcf=InputFile.txt
- -abc -f=InputFile.txt
- -ab -cf=InputFile.txt
- -a -b -c -fInputFile.txt
- -a -b -c -f InputFile.txt
- -a -b -c -f=InputFile.txt
-...
-----
-
-
-=== Positional Parameters
-Any command line arguments that are not subcommands or options (or option parameters) are interpreted as positional parameters.
-Positional parameters generally follow the options but from picocli v2.0, positional parameters can be mixed with options on the command line.
-
-Use the (zero-based) `index` attribute to specify exactly which parameters to capture.
-Omitting the `index` attribute means the field captures _all_ positional parameters.
-Array or collection fields can capture multiple values.
-
-The `index` attribute accepts _range_ values, so an annotation like `@Parameters(index="2..4")` captures the arguments at index 2, 3 and 4. Range values can be _open-ended_. For example, `@Parameters(index="3..*")` captures all arguments from index 3 and up.
-
-For example:
-
-[source,java]
-----
-class PositionalParameters {
- @Parameters(hidden = true) // "hidden": don't show this parameter in usage help message
- List allParameters; // no "index" attribute: captures _all_ arguments (as Strings)
-
- @Parameters(index = "0") InetAddress host;
- @Parameters(index = "1") int port;
- @Parameters(index = "2..*") File[] files;
-}
-----
-
-Picocli initializes fields with the values at the specified index in the arguments array.
-[source,java]
-----
-String[] args = { "localhost", "12345", "file1.txt", "file2.txt" };
-PositionalParameters params = CommandLine.populateCommand(new PositionalParameters(), args);
-
-assert params.host.getHostName().equals("localhost");
-assert params.port == 12345;
-assert Arrays.equals(params.files, new File[] {new File("file1.txt"), new File("file2.txt")});
-assert params.allParameters.equals(Arrays.asList("localhost", "12345", "file1.txt", "file2.txt"));
-----
-
-See <> for which types are supported out of the box and how to add custom types.
-
-=== Mixing Options and Positional Parameters
-From picocli v2.0, positional parameters can be mixed with options on the command line.
-
-For example:
-
-[source,java]
-----
-class Mixed {
- @Parameters
- List positional;
-
- @Option(names = "-o")
- List options;
-}
-----
-
-Any command line argument that is not an option or subcommand is interpreted as a positional parameter.
-[source,java]
-----
-String[] args = { "param0", "-o", "AAA", "param1", "param2", "-o", "BBB", "param3" };
-Mixed mixed = new Mixed();
-new CommandLine(mixed).parse(args);
-
-assert mixed.positional.equals(Arrays.asList("param0", "param1", "param2", "param3");
-assert mixed.options.equals (Arrays.asList("AAA", "BBB"));
-----
-
-
-=== Double dash (`--`)
-When one of the command line arguments is just two dashes without any characters attached (`--`),
-picocli interprets all following arguments as positional parameters, even arguments that match an option name.
-
-[source,java]
-----
-class DoubleDashDemo {
- @Option(names = "-v") boolean verbose;
- @Option(names = "-files") List files;
- @Parameters List params;
-}
-----
-
-The `--` end-of-options delimiter clarifies which of the arguments are positional parameters:
-[source,java]
-----
-String[] args = { "-v", "--", "-files", "file1", "file2" };
-DoubleDashDemo demo = new DoubleDashDemo();
-new CommandLine(demo).parse(args);
-
-assert demo.verbose;
-assert demo.files == null;
-assert demo.params.equals(Arrays.asList("-files", "file1", "file2"));
-----
-
-[[AtFiles]]
-=== @-files
-Users sometimes run into system limitations on the length of a command line when creating a
-command line with lots of options or with long arguments for options.
-
-Starting from v2.1.0, picocli supports "argument files" or "@-files".
-Argument files are files that themselves contain arguments to the command.
-When picocli encounters an argument beginning with the character `@',
-it expands the contents of that file into the argument list.
-
-An argument file can include options and positional parameters in any combination.
-The arguments within a file can be space-separated or newline-separated.
-If an argument contains embedded whitespace, put the whole argument in double or single quotes
-(`"-f=My Files\Stuff.java"`).
-
-Lines starting with `#` are comments and are ignored.
-The file may itself contain additional @-file arguments; any such arguments will be processed recursively.
-
-If the file does not exist, or cannot be read, then the argument will be treated literally, and not removed.
-Multiple @-files may be specified on the command line. The specified path may be relative (to the current directory) or absolute.
-
-For example, suppose a file with arguments exists at `/home/foo/args`, with these contents:
-
-----
-# This line is a comment and is ignored.
-ABC -option=123
-'X Y Z'
-----
-
-A command may be invoked with the @file argument, like this:
-[source,bash]
-----
-java MyCommand @/home/foo/args
-----
-The above will be expanded to the contents of the file:
-[source,bash]
-----
-java MyCommand ABC -option=123 "X Y Z"
-----
-
-
-@-file expansion can be switched off by calling `CommandLine::setExpandAtFiles` with `false`.
-If turned on, you can still pass a real parameter with an initial '@' character by escaping it
-with an additional '@' symbol, e.g. '@@somearg' will become '@somearg' and not be subject to expansion.
-
-This feature is similar to the 'Command Line Argument File' processing supported by gcc, javadoc and javac.
-The documentation for these tools shows further examples.
-
-== Strongly Typed Everything
-When command line options and positional parameters are mapped to the annotated fields,
-the text value is converted to the type of the annotated field.
-
-=== Built-in Types
-Out of the box, picocli can convert command line argument strings to a number of common data types.
-
-Most of the built-in types work with Java 5, but picocli also has some default converters for Java 7 types like `Path` and Java 8 types like `Duration`, etc. These converters are only available when running on a Java version that supports them. See the below list for details.
-
-* any Java primitive type or their wrapper
-* any `enum`
-* `String`, `StringBuilder`, `CharSequence`
-* `java.math.BigDecimal`, `java.math.BigInteger`
-* `java.nio.Charset`
-* `java.io.File`
-* `java.nio.file.Path` (from picocli 2.2, requires Java 7 or higher)
-* `java.net.InetAddress`
-* `java.util.regex.Pattern`
-* `java.util.Date` (for values in `"yyyy-MM-dd"` format)
-* `java.sql.Time` (for values in any of the `"HH:mm"`, `"HH:mm:ss"`, `"HH:mm:ss.SSS"`, or `"HH:mm:ss,SSS"` formats)
-* `java.sql.Timestamp` (from picocli 2.2, for values in the `"yyyy-MM-dd HH:mm:ss"` or `"yyyy-MM-dd HH:mm:ss.fffffffff"` formats)
-* `java.net.URL`, `java.net.URI`
-* `java.util.UUID`
-* `java.time` value objects: `Duration`, `Instant`, `LocalDate`, `LocalDateTime`, `LocalTime`, `MonthDay`, `OffsetDateTime`, `OffsetTime`, `Period`, `Year`, `YearMonth`, `ZonedDateTime`, `ZoneId`, `ZoneOffset` (from picocli 2.2, requires Java 8 or higher, invokes the `parse` method of these classes)
-* `java.lang.Class` (from picocli 2.2, for the fully qualified class name)
-* `java.nio.ByteOrder` (from picocli 2.2, for the Strings `"BIG_ENDIAN"` or `"LITTLE_ENDIAN"`)
-* `java.util.Currency` (from picocli 2.2, for the ISO 4217 code of the currency)
-* `java.net.NetworkInterface` (from picocli 2.2, for the InetAddress or name of the network interface)
-* `java.util.TimeZoneConverter` (from picocli 2.2, for the ID for a TimeZone)
-* `java.sql.Connection` (from picocli 2.2, for a database url of the form `jdbc:subprotocol:subname`)
-* `java.sql.Driver` (from picocli 2.2, for a database URL of the form `jdbc:subprotocol:subname`)
-
-
-
-=== Custom Type Converters
-Register a custom type converter to handle data types other than the above built-in ones.
-
-Custom converters need to implement the `picocli.CommandLine.ITypeConverter` interface:
-
-[source,java]
-----
-public interface ITypeConverter {
- /**
- * Converts the specified command line argument value to some domain object.
- * @param value the command line argument String value
- * @return the resulting domain object
- * @throws Exception an exception detailing what went wrong during the conversion
- */
- K convert(String value) throws Exception;
-}
-----
-
-Custom type converters can be registered with the `CommandLine.registerConverter(Class cls, ITypeConverter converter)` method. All options and positional parameters with the specified type will be converted by the specified converter.
-
-
-NOTE: Java 8 lambdas make it easy to register custom converters:
-
-[source,java]
-----
-CommandLine cl = new CommandLine(app)
-cl.registerConverter(Locale.class, s -> new Locale.Builder().setLanguageTag(s).build());
-cl.registerConverter(Cipher.class, s -> Cipher.getInstance(s));
-----
-
-After registering custom converters, call the `parse(String...)` method on the `CommandLine` instance where the converters are registered. (The static `populateCommand` method cannot be used.) For example:
-
-[source,java]
-----
-class App {
- @Parameters java.util.Locale locale;
- @Option(names = "-a") javax.crypto.Cipher cipher;
-}
-----
-
-[source,java]
-----
-App app = new App();
-CommandLine commandLine = new CommandLine(app)
- .registerConverter(Locale.class, s -> new Locale.Builder().setLanguageTag(s).build())
- .registerConverter(Cipher.class, s -> Cipher.getInstance(s));
-
-commandLine.parse("-a", "AES/CBC/NoPadding", "en-GB");
-assert app.locale.toLanguageTag().equals("en-GB");
-assert app.cipher.getAlgorithm().equals("AES/CBC/NoPadding"));
-----
-
-CAUTION: _Note on subcommands:_ the specified converter will be registered with the `CommandLine` object
-and all subcommands (and nested sub-subcommands) that were added _before_ the converter was registered.
-Subcommands added later will not have the converter added automatically.
-To ensure a custom type converter is available to all subcommands, register the type converter last, after adding subcommands.
-
-=== Option-specific Type Converters
-Picocli 2.2 added a `converter` attribute to the `@Option` and `@Parameter` annotations. This allows a specific option or positional parameter to use a different converter than would be used by default based on the type of the field.
-
-For example, for a specific field you may want to use a converter that maps the constant names defined in https://docs.oracle.com/javase/9/docs/api/java/sql/Types.html[`java.sql.Types`] to the `int` value of these constants, but any other `int` fields should not be affected by this and should continue to use the standard int converter that parses numeric values.
-
-Example usage:
-
-[source,java]
-----
-class App {
- @Option(names = "--sqlType", converter = SqlTypeConverter.class)
- int sqlType;
-}
-----
-
-Example implementation:
-[source,java]
-----
-class SqlTypeConverter implements ITypeConverter {
- public Integer convert(String value) throws Exception {
- switch (value) {
- case "ARRAY" : return Types.ARRAY;
- case "BIGINT" : return Types.BIGINT;
- case "BINARY" : return Types.BINARY;
- case "BIT" : return Types.BIT;
- case "BLOB" : return Types.BLOB;
- ...
- }
- }
-}
-----
-
-This may also be useful for applications that need a custom type converter but want to use the static convenience methods (`populateCommand`, `run`, `call`). The `converter` annotation does not require a `CommandLine` instance so it can be used with the static convenience methods.
-
-Type converters declared with the `converter` attribute need to have a public no-argument constructor to be instantiated, unless a <> is installed to instantiate classes.
-
-=== Arrays, Collections, Maps
-NOTE: Starting from picocli v2.0, the `type` attribute is no longer necessary for `Collection` and `Map` fields:
-picocli will infer the collection element type from the generic type.
-(The `type` attribute still works as before, it is just optional in most cases.)
-
-==== Arrays and Collections
-
-Multiple parameters can be captured together in a single array or `Collection` field.
-The array or collection elements can be any type for which a <> is registered.
-For example:
-
-[source,java]
-----
-import java.util.regex.Pattern;
-import java.io.File;
-
-class Convert {
- @Option(names = "-patterns", description = "the regex patterns to use");
- Pattern[] patterns;
-
- @Parameters(/* type = File.class, */ description = "the files to convert")
- List files; // picocli infers type from the generic type
-}
-----
-
-[source,java]
-----
-String[] args = { "-patterns", "a*b", "-patterns", "[a-e][i-u]", "file1.txt", "file2.txt" };
-Convert convert = CommandLine.populateCommand(new Convert(), args);
-
-// convert.patterns now has two Pattern objects
-// convert.files now has two File objects
-----
-
-NOTE: If a collection is returned from a type converter, the _contents_ of the collection are added to the field, not the collection itself.
-
-If the field is `null`, picocli will instantiate it when the option or positional parameter is matched.
-If the `Collection` type is not a concrete class, picocli will make a best effort to instantiate it based on the field type:
-`List -> ArrayList`, `OrderedSet -> TreeSet`, `Set -> LinkedHashSet`, `Queue -> LinkedList`, otherwise, `ArrayList`.
-
-==== Maps
-Picocli v1.0 introduced support for `Map` fields similar to Java's system properties `-Dkey=value` or Gradle's project properties `-Pmyprop=myvalue`.
-
-`Map` fields may have any type for their key and value
-as long as a <> is registered for both the key and the value type.
-Key and value types are inferred from the map's generic type parameters.
-For example:
-
-[source,java]
-----
-import java.net.InetAddress;
-import java.net.Proxy.Type;
-import java.util.concurrent.TimeUnit;
-
-class MapDemo {
- @Option(names = {"-p", "--proxyHost"});
- Map proxies;
-
- @Option(names = {"-u", "--timeUnit"});
- Map timeout;
-}
-----
-Map options may be specified multiple times with different key-value pairs. (See <>.)
-
-[source,bash]
-----
- -p HTTP=123.123.123.123 --proxyHost SOCKS=212.212.212.212
- -uDAYS=3 -u HOURS=23 -u=MINUTES=59 --timeUnit=SECONDS=13
-----
-If the field is `null`, picocli will instantiate it when the option or positional parameter is matched.
-If the type is not a concrete class, picocli will instantiate a `LinkedHashMap` to preserve the input ordering.
-
-NOTE: On the command line, the key and the value must be separated by a `=` character.
-
-=== Abstract Field Types
-The field's type can be an interface or an abstract class.
-The `type` attribute can be used to control for each field what concrete class the string value should be converted to.
-For example:
-
-[source,java]
-----
-class App {
- @Option(names = "--big", type = BigDecimal.class) // concrete Number subclass
- Number[] big; // array type with abstract component class
-
- @Option(names = "--small", type = Short.class) // other Number subclass
- Number[] small;
-
- @Parameters(type = StringBuilder.class) // StringBuilder implements CharSequence
- CharSequence address; // interface type
-}
-----
-
-==== Maps and Collections with Abstract Elements
-For raw maps and collections, or when using generics with unbounded wildcards like `Map, ?>`, or when the type parameters are themselves abstract classes like `List` or `Map extends Number, ? super Number>`, there is not enough information to convert to a stronger type. By default, the raw String values are added as is to such collections.
-
-The `type` attribute can be specified to convert to a stronger type than String. For example:
-[source,java]
-----
-class TypeDemo {
- @Option(names = "-x"); // not enough information to convert
- Map, ?> weaklyTyped; // String keys and values are added as is
-
- @Option(names = "-y", type = {Short.class, BigDecimal.class});
- Map extends Number, ? super Number> stronglyTyped;
-
- @Option(names = "-s", type = CharBuffer.class);
- List text;
-}
-----
-
-== Default Values
-It is possible to define a default value for an option or positional parameter, that is assigned when the user did not specify this option or positional parameter on the command line.
-
-For annotated fields, it is simplest to declare the field with a value:
-[source,java]
-----
-@Option(names = "-c", description = "The count (default: ${DEFAULT-VALUE})")
-int count = 123; // default value is 123
-----
-For <>, use the `defaultValue` annotation attribute. For example, for an annotated interface:
-[source,java]
-----
-interface Spec {
- @Option(names = "-c", defaultValue = "123", description = "... ${DEFAULT-VALUE} ...")
- int count();
-}
-----
-Or similarly for an annotated concrete class:
-[source,java]
-----
-class Impl {
- int count;
-
- @Option(names = "-c", defaultValue = "123", description = "... ${DEFAULT-VALUE} ...")
- void setCount(int count) {
- this.count = count;
- }
-}
-----
-
-Note that you can use the `${DEFAULT-VALUE}` variable in the `description` of the option or positional parameter and picocli will <> the actual default value.
-
-== Multiple Values
-Multi-valued options and positional parameters are annotated fields that can capture multiple values from the command line.
-
-=== Multiple Occurrences
-
-==== Repeated Options
-The simplest way to create a multi-valued option is to declare an annotated field whose type is an array, collection or a map.
-
-[source,java]
-----
-@Option(names = "-option")
-int[] values;
-----
-Users may specify the same option multiple times. For example:
-----
- -option 111 -option 222 -option 333
-----
-Each value is appended to the array or collection.
-
-==== Multiple Positional Parameters
-Similarly for multi-valued positional parameters:
-[source,java]
-----
-@Parameters
-List units;
-----
-Users may specify multiple positional parameters. For example:
-----
- SECONDS HOURS DAYS
-----
-Again, each value is appended to the array or collection.
-
-
-==== Repeated Boolean Options
-Boolean options with multiple values are supported from picocli v2.1.0.
-[source,java]
-----
-@Option(names = "-v", description = { "Specify multiple -v options to increase verbosity.",
- "For example, `-v -v -v` or `-vvv`"})
-boolean[] verbosity;
-----
-Users may specify multiple boolean flag options without parameters. For example:
-----
- -v -v -v -vvv
-----
-The above example results in six `true` values being added to the `verbosity` array.
-
-=== Split Regex
-Options and parameters may also specify a `split` regular expression used to split each option parameter into smaller substrings.
-Each of these strings is converted to the type of the collection or array. See <>.
-[source,java]
-----
-@Option(names = "-option", split = ",")
-int[] values;
-----
-A single command line argument like the following will be split up and three `int` values are added to the array:
-----
--option 111,222,333
-----
-
-Similarly for <>:
-[source,java]
-----
-@Option(names = "-fix", split = "\\|")
-Map message;
-----
-With the above option, command line arguments like the following are interpreted as a set of key-value pairs instead of a single string:
-----
--fix 8=FIX.4.4|9=69|35=A|49=MBT|56=TargetCompID|34=9|52=20130625-04:05:32.682|98=0|108=30|10=052
-----
-
-
-=== Arity
-Sometimes you want to define an option that requires more than one option parameter _for each option occurrence_ on the command line.
-
-The `arity` attribute lets you control exactly how many parameters to consume for each option occurrence.
-
-The `arity` attribute can specify an exact number of required parameters, or a _range_ with a minimum and a maximum number of parameters.
-The maximum can be an exact upper bound, or it can be `"*"` to denote _any number_ of parameters. For example:
-[source, java]
-----
-class ArityDemo {
- @Parameters(arity = "1..3", descriptions = "one to three Files")
- File[] files;
-
- @Option(names = "-f", arity = "2", description = "exactly two floating point numbers")
- double[] doubles;
-
- @Option(names = "-s", arity = "1..*", description = "at least one string")
- String[] strings;
-}
-----
-A `MissingParameterException` is thrown when fewer than the miminum number of parameters is specified on the command line.
-
-Once the minimum number of parameters is consumed, picocli will check each subsequent command line argument to see whether it is an additional parameter, or a new option. For example:
-
-----
-ArityDemo -s A B C -f 1.0 2.0 /file1 /file2
-----
-Option `-s` has arity `"1..*"` but instead of consuming all parameters,
-the `-f` argument is recognized as a separate option.
-
-=== Default Arity
-If no `arity` is specified, the number of parameters depends on the field's type.
-
-==== Option Arity
-.Default `arity` for `@Option` fields
-[grid=cols,cols="30,5,65",options="header"]
-|===
-| @Option Field Type | Default Arity | Notes
-| boolean | 0 |Boolean options by default don't require an option parameter. The field is toggled to its logical negative when the option name is recognized. (This can be <>.)
-| Single-valued type (e.g., `int`, `String`, `File`) | 1 | The option name must be followed by a value.
-| Multi-valued type (arrays, collections or maps) | 1 | The option name must be followed by a value.
-|===
-
-
-CAUTION: Prior to picocli v2.0, multi-valued options used to greedily consume as many arguments as possible until
-encountering another option or subcommand.
-If your application relies on the previous behaviour, you need to explicitly specify an option arity of `0..*` when migrating to picocli v2.0.
-
-==== Positional Parameter Arity
-
-.Default `arity` for `@Parameters` fields
-[grid=cols,cols="30,5,65",options="header"]
-|===
-| @Parameters Field Type | Default Arity | Notes
-| boolean | 1 |Positional parameters of type `boolean` or `Boolean` require a value. Only `true` or `false` (case insensitive) are valid values.
-| Single-valued type (e.g., `int`, `String`, `File`) | 1 | One parameter required for each position.
-| Multi-valued type (arrays, collections or maps) | 0..1 | For multi-valued positional parameters (arrays, collections or maps), values are optional, not required.
-|===
-
-
-`@Parameters` fields are applied to a command line argument if their index matches the argument's position.
-The default index is `\*`, meaning all positions.
-A `@Parameters` field with `index = "*"` is applied multiple times: once for each positional parameter on the command line.
-
-When a `@Parameters` field is applied (because its index matches the index of the positional parameter), the field may consume zero, one or more arguments, depending on its arity.
-
-=== Optional Values
-If an option is defined with `arity = "0..1"`, it may or not have a parameter value.
-If such an option is specified without a value on the command line, it is assigned an empty String (starting from picocli 2.3).
-If the option is not specified, it keeps its default value. For example:
-
-[source, java]
-----
-class OptionalValueDemo implements Runnable {
- @Option(names = "-x", arity = "0..1", description = "optional parameter")
- String x;
-
- public void run() { System.out.printf("x = '%s'%n", x); }
-
- public static void main(String... args) {
- CommandLine.run(new OptionalValueDemo(), args);
- }
-}
-----
-Gives the following results:
-[source, bash]
-----
-java OptionalValueDemo -x value
-x = 'value'
-
-java OptionalValueDemo -x
-x = ''
-
-java OptionalValueDemo
-x = 'null'
-----
-From picocli 3.0, options with non-String types can specify a <> to convert the empty String to a strongly typed value when the option is specified without a value.
-
-
-== Required Arguments
-=== Required Options
-Options can be marked `required` to make it mandatory for the user to specify them on the command line. When a required option is not specified, a `MissingParameterException` is thrown from the `parse` method. For example:
-[source, java]
-----
-class MandatoryOption {
- @Option(names = "-n", required = true, description = "mandatory number")
- int number;
-
- @Parameters
- File[] files;
-}
-----
-The following command line arguments would result in an exception complaining that `number` is missing:
-----
-// invalid: missing option -n
- file1 file2 file3
-----
-The following command line arguments would be accepted:
-----
-// valid: required option -n has a value
- -n 123 file1 file2 file3
-----
-
-=== Required Parameters
-Use the `arity` attribute to make `@Parameters` mandatory:
-[source, java]
-----
-class BothOptionAndParametersMandatory {
- @Parameters(arity = "1..*", descriptions = "at least one File")
- File[] files;
-
- @Option(names = "-n", required = true, description = "mandatory number")
- int number;
-}
-----
-The following command line arguments would result in an exception complaining that `files` are missing:
-----
-// invalid: missing file parameters
- -n 123
-----
-The following command line arguments would be accepted:
-----
-// valid: both required fields have a value
- -n 123 file1
-----
-
-
-== Parser Configuration
-
-=== Overwriting Single Options
-
-When a single-value option is specified multiple times on the command line, the default parser behaviour is
-to throw an `OverwrittenOptionException`. For example:
-[source,java]
-----
-@Option(name = "-p") int port;
-----
-The following input results in an `OverwrittenOptionException`:
-----
- -p 80 -p 8080
-----
-Applications can change this by calling `CommandLine.setOverwrittenOptionsAllowed(true)` before parsing the input.
-When overwritten options are allowed, the last specified value takes effect (the above input will set the `port` field to `8080`)
-and a WARN level message is printed to the console. (See <> for how to switch off the warnings.)
-
-=== Stop At Positional
-By default, positional parameters can be mixed with options on the command line, but this is not always desirable.
-From picocli 2.3, applications can call `CommandLine.setStopAtPositional(true)`
-to force the parser to treat all values following the first positional parameter as positional parameters.
-
-When this flag is set, the first positional parameter effectively serves as an "<>" marker.
-
-=== Unmatched Input
-By default, an `UnmatchedArgumentException` is thrown when a command line argument cannot be assigned to
-an option or positional parameter. For example:
-
-[source,java]
-----
-class OnlyThree {
- @Parameters(arity = "3") String[] values;
-}
-----
-The command has only one annotated field, `values`, and it expects exactly three arguments,
-so the following input results in an `UnmatchedArgumentException`:
-----
-java OnlyThree 1 2 3 4 5
-----
-
-Applications can change this by calling `CommandLine.setUnmatchedArgumentsAllowed(true)` before parsing the input.
-When unmatched arguments are allowed, the above input will be accepted and a WARN level message is printed to the console.
-(See <> for how to switch off the warnings.)
-
-The unmatched argument values can be obtained with the `CommandLine.getUnmatchedArguments()` method.
-
-=== `@Unmatched` annotation
-From picocli 3.0, fields annotated with `@Unmatched` will be populated with the unmatched arguments.
-The field must be of type `String[]` or `List`.
-
-If picocli finds a field annotated with `@Unmatched`, it automatically sets `unmatchedArgumentsAllowed` to `true`
-so no `UnmatchedArgumentException` is thrown when a command line argument cannot be assigned to an option or positional parameter.
-
-=== Unknown Options
-A special case of unmatched input are arguments that resemble options but don't match any of the defined options.
-For example:
-
-[source,java]
-----
-@Option(names = "-a") String alpha;
-@Option(names = "-b") String beta;
-@Parameters String[] remainder;
-----
-The above defines options `-a` and `-b`, but what should the parser do with input like this?
-
-----
- -x -a AAA
-----
-The `-x` argument "looks like" an option but there is no `-x` option defined...
-
-One possibility is to silently accept such values as positional parameters but this is often not desirable.
-From version 1.0, picocli determines if the unmatched argument "resembles an option"
-by comparing its leading characters to the prefix characters of the known options.
-
-When the unmatched value is similar to the known options, picocli throws an `UnmatchedArgumentException`
-rather than treating it as a positional parameter.
-
-As usual, `CommandLine.setUnmatchedArgumentsAllowed(true)` will accept unmatched input and
-display a WARN-level message on the console.
-
-
-Arguments that are not considered similar to the known options are interpreted as positional parameters:
-----
- x -a AAA
-----
-The above input is treated by the parser as one positional parameter (`x`) followed by the `-a` option and its value.
-
-Picocli 3.0 introduced a `CommandLine.setUnmatchedOptionsArePositionalParams(boolean)` method that can be used to
-force the parser to treat arguments resembling an option as positional parameters. For example:
-
-----
- -x -a AAA
-----
-When `unmatchedOptionsArePositionalParams` is set to `true`, the unknown option `-x` is treated as a positional parameter.
-The next argument `-a` is recognized and processed as a known option like you would expect.
-
-=== Stop At Unmatched
-From picocli 2.3, applications can call `CommandLine.setStopAtUnmatched(true)` to force the parser to stop interpreting
-options and positional parameters as soon as it encounters an unmatched argument.
-
-When this flag is set, the first unmatched argument and all subsequent command line arguments are added to the
-unmatched arguments list returned by `CommandLine.getUnmatchedArguments()`.
-
-=== Toggle Boolean Flags
-By default, boolean flag options without a parameter are "toggled" when the option is matched on the command line:
-if the previous value was `true` it is set to `false`, and when the value was `false` it is set to `true`.
-From picocli 3.0, applications can call `CommandLine.setToggleBooleanFlags(false)` to switch this behaviour off.
-If toggling is off, flags are simply set to `true` when the option is matched on the command line.
-
-
-=== POSIX Clustered Short Options
-By default, the picocli parser allows POSIX clustered short options, so short options like `-x -v -f SomeFile` can be clustered together like `-xvfSomeFile`.
-From picocli 3.0, applications can call `CommandLine.setPosixClusteredShortOptionsAllowed(false)` to enforce that options must be separated with whitespace on the command line.
-
-=== Lenient Mode (Incubating)
-From picocli 3.2, the parser can be configured to continue parsing invalid input to the end.
-When `collectErrors` is set to `true`, and a problem occurs during parsing, an `Exception` is added to the `ParseResult.errors()` list and parsing continues. The default behaviour (when `collectErrors` is `false`) is to abort parsing by throwing the `Exception`.
-
-This is useful when generating completion candidates on partial input, and is also useful when using picocli in
-languages like Clojure where idiomatic error handling does not involve throwing and catching exceptions.
-
-When using this feature, applications are responsible for actively verifying that no errors occurred before executing the business logic. Use with care!
-
-
-== Help
-
-=== Help Options
-Applications can define help options by setting attribute `versionHelp = true`, `usageHelp = true` or `help = true`.
-If one of the arguments specified on the command line is a "help" option, picocli will not throw a `MissingParameterException` when required options are missing.
-
-For example:
-
-[source,java]
-----
-@Option(names = {"-V", "--version"}, versionHelp = true, description = "display version info")
-boolean versionInfoRequested;
-
-@Option(names = {"-h", "--help"}, usageHelp = true, description = "display this help message")
-boolean usageHelpRequested;
-----
-Use these attributes for options that request the usage help message or version information to be shown on the console.
-
-[source,java]
-----
-App app = CommandLine.populateCommand(new App(), args);
-if (app.usageHelpRequested) {
- CommandLine.usage(new App(), System.out);
- return;
-}
-----
-
-The `CommandLine` class offers two methods that allow external components to detect whether
-usage help or version information was requested (without inspecting the annotated domain object):
-
-* `CommandLine.isUsageHelpRequested()` returns `true` if the parser matched an option annotated with `usageHelp=true`
-* `CommandLine.isVersionHelpRequested()` returns `true` if the parser matched an option annotated with `versionHelp=true`
-
-[source,java]
-----
-CommandLine commandLine = new CommandLine(new App());
-commandLine.parse(args);
-if (commandLine.isUsageHelpRequested()) {
- commandLine.usage(System.out);
- return;
-} else if (commandLine.isVersionHelpRequested()) {
- commandLine.printVersionHelp(System.out);
- return;
-}
-// ... run App's business logic
-----
-See also <>.
-
-=== Mixin Standard Help Options
-Picocli 3.0 introduced the `mixinStandardHelpOptions` command attribute. When this attribute is set to `true`, picocli adds a <> to the
-command that adds <> and <> options to the command. For example:
-
-[source,java]
-----
-@Command(mixinStandardHelpOptions = true, version = "auto help demo - picocli 3.0")
-class AutoHelpDemo implements Runnable {
-
- @Option(names = "--option", description = "Some option.")
- String option;
-
- @Override public void run() { ... }
-}
-----
-
-Commands with `mixinStandardHelpOptions` do not need to explicitly declare fields annotated with `@Option(usageHelp = true)` and `@Option(versionHelp = true)` any more.
-The usage help message for the above example looks like this:
-----
-Usage: [-hV] [--option=