diff --git a/docs/images/WhereIsMyCode.png b/docs/images/WhereIsMyCode.png
new file mode 100644
index 00000000..19077dab
Binary files /dev/null and b/docs/images/WhereIsMyCode.png differ
diff --git a/docs/picocli-v2-groovy-scripts-on-steroids.adoc b/docs/picocli-2.0-groovy-scripts-on-steroids.adoc
similarity index 63%
rename from docs/picocli-v2-groovy-scripts-on-steroids.adoc
rename to docs/picocli-2.0-groovy-scripts-on-steroids.adoc
index aee3e0ed..dd5970eb 100644
--- a/docs/picocli-v2-groovy-scripts-on-steroids.adoc
+++ b/docs/picocli-2.0-groovy-scripts-on-steroids.adoc
@@ -1,13 +1,14 @@
-= Picocli v2: Groovy Scripts on Steroids
+= Picocli 2.0: Groovy Scripts on Steroids
//:author: Remko Popma
//:email: rpopma@apache.org
//:revnumber: 2.1.0-SNAPSHOT
-//:revdate: 2017-11-03
+//:revdate: 2017-11-04
+:prewrap!:
:source-highlighter: coderay
:icons: font
:imagesdir: images
-Picocli v2 adds improved support for other JVM languages, especially Groovy.
+Picocli 2.0 adds improved support for other JVM languages, especially Groovy.
Why use picocli when the Groovy language has built-in CLI support with the http://docs.groovy-lang.org/2.4.7/html/gapi/groovy/util/CliBuilder.html[CliBuilder] class?
You may like picocli's usage help, which shows ANSI http://picocli.info/#_ansi_colors_and_styles[colors and styles]
@@ -33,13 +34,10 @@ but users may specify a different MessageDigest algorithm. Users can request usa
@Grab('info.picocli:picocli:2.0.1')
@picocli.groovy.PicocliScript
import groovy.transform.Field
-
-import java.nio.file.Files
import java.security.MessageDigest
-
import static picocli.CommandLine.*
-@Parameters(arity = "1", paramLabel = "FILE", description= "The file(s) whose checksum to calculate.")
+@Parameters(arity="1", paramLabel="FILE", description="The file(s) whose checksum to calculate.")
@Field File[] files
@Option(names = ["-a", "--algorithm"], description = [
@@ -47,13 +45,11 @@ import static picocli.CommandLine.*
" or any other MessageDigest algorithm."])
@Field String algorithm = "MD5"
-@Option(names = ["-h", "--help"], usageHelp = true, description = "Show this help message and exit.")
+@Option(names= ["-h", "--help"], usageHelp= true, description= "Show this help message and exit.")
@Field boolean helpRequested
files.each {
- byte[] fileContents = Files.readAllBytes(it.toPath())
- byte[] digest = MessageDigest.getInstance(algorithm).digest(fileContents)
- println javax.xml.bind.DatatypeConverter.printHexBinary(digest) + "\t" + it
+ println MessageDigest.getInstance(algorithm).digest(it.bytes).encodeHex().toString() + "\t" + it
}
----
When run in the `$picocli-home/examples/src/main/groovy/picocli/examples` directory,
@@ -62,8 +58,9 @@ this example script gives the following results:
[source,bash]
----
$ groovy checksum.groovy *.*
-4DCE157CA654199494642D49FB67BF11 checksum.groovy
-8C7D823F1C9345213977FF6DA964AA02 checksum-with-banner.groovy
+4995d24bbb3adf67e2120c36dd3027b7 checksum.groovy
+a03c852de017f9303fcc373c7adafac6 checksum-with-banner.groovy
+1ee567193bf41cc835ce76b6ca29ed30 checksum-without-base.groovy
----
Invoking the script with the `-h` or `--help` option shows the usage help message
@@ -71,8 +68,51 @@ with ANSI colors and styles below:
image:GroovyChecksum.png[Usage help with ANSI colors and styles]
-You may have noticed that the script does not contain any logic for parsing the command
-line arguments or for handling requests for usage help. Let's take a look at how this works.
+== Where's the Code?
+
+You may have noticed that the above script does not contain any logic for parsing the command
+line arguments or for handling requests for usage help.
+
+[.text-center]
+image:WhereIsMyCode.png[Dude, where's my code?,width='35%']
+
+Without the `@picocli.groovy.PicocliScript` annotation, the script code would look something like this:
+
+[source,groovy]
+----
+class Checksum {
+ @Parameters(arity = "1", paramLabel = "FILE", description = "...")
+ File[] files
+
+ @Option(names = ["-a", "--algorithm"], description = ["..."])
+ String algorithm = "MD5"
+
+ @Option(names = ["-h", "--help"], usageHelp = true, description = "...")
+ boolean helpRequested
+}
+Checksum checksum = new Checksum()
+CommandLine commandLine = new CommandLine(checksum)
+try {
+ commandLine.parse(args)
+ if (commandLine.usageHelpRequested) {
+ commandLine.usage(System.out)
+ } else {
+ checksum.files.each {
+ byte[] digest = MessageDigest.getInstance(checksum.algorithm).digest(it.bytes)
+ println digest.encodeHex().toString() + "\t" + it
+ }
+ }
+} catch (ParameterException ex) {
+ println ex.message
+ commandLine.usage(System.out)
+}
+----
+
+The above example has explicit code to parse the command line, deal with invalid user input,
+and check for usage help requests.
+The first version of the script did not have any of this boilerplate code.
+
+Let's take a look at how this works.
== Basescript
@@ -81,7 +121,7 @@ Scripts annotated with `@picocli.groovy.PicocliScript` are automatically transfo
This turns a Groovy script into a picocli-based command line application.
[.text-center]
-image:AllYourBase.png[ALL YOUR BASE ARE BELONG TO US]
+image:AllYourBase.png[Alt="ALL YOUR BASE ARE BELONG TO US",width='35%']
When the script is run, Groovy calls the script's `run` method.
The `PicocliBaseScript::run` method takes care of parsing the command line and populating the script
@@ -95,10 +135,11 @@ fields with the results. The run method does the following:
* Otherwise, the script body is executed.
-See the http://picocli.info/apidocs/picocli/groovy/PicocliBaseScript.html#run--[PicocliBaseScript javadoc] for more details.
+This behavior can be customized, see the http://picocli.info/apidocs/picocli/groovy/PicocliBaseScript.html#run--[PicocliBaseScript javadoc] for more details.
In addition to changing the script base class, the `@PicocliScript` annotation also allows Groovy
-scripts to use the `@Command` annotation. The picocli parser will look for this annotation on the
+scripts to use the `@Command` annotation directly, without introducing a helper class.
+The picocli parser will look for this annotation on the
class containing the `@Option` and `@Parameters`-annotated fields. The same custom
http://picocli.info/apidocs/picocli/groovy/PicocliScriptASTTransformation.html[AST transformation]
that changes the script's base class also moves any `@Command` annotation in the script to this
@@ -106,9 +147,10 @@ transformed class so the picocli parser can pick it up.
== Usage Help With Colors
-The `@Command` annotation lets you customize parts of the usage help message like command name, description, headers, footers etc.
+The `@Command` annotation lets you customize parts of the http://picocli.info/#_usage_help[usage help] message like command name, description, headers, footers etc.
-Let's add some bells and whistles to the above script.
+Let's add some bells and whistles to the example script.
+(Credit to http://patorjk.com/software/taag/ for the ASCII Art Generator.)
[source,groovy]
----
@@ -128,13 +170,10 @@ Let's add some bells and whistles to the above script.
)
@picocli.groovy.PicocliScript
import groovy.transform.Field
-
-import java.nio.file.Files
import java.security.MessageDigest
-
import static picocli.CommandLine.*
-@Parameters(arity = "1", paramLabel = "FILE", description= "The file(s) whose checksum to calculate.")
+@Parameters(arity="1", paramLabel="FILE", description="The file(s) whose checksum to calculate.")
@Field private File[] files
@Option(names = ["-a", "--algorithm"], description = [
@@ -142,29 +181,29 @@ import static picocli.CommandLine.*
" any other MessageDigest algorithm. See [1] for more details."])
@Field private String algorithm = "MD5"
-@Option(names = ["-h", "--help"], usageHelp = true, description = "Show this help message and exit.")
+@Option(names= ["-h", "--help"], usageHelp=true, description="Show this help message and exit.")
@Field private boolean helpRequested
-@Option(names = ["-V", "--version"], versionHelp = true, description = "Show version info and exit.")
+@Option(names= ["-V", "--version"], versionHelp=true, description="Show version info and exit.")
@Field private boolean versionInfoRequested
files.each {
- byte[] fileContents = Files.readAllBytes(it.toPath())
- byte[] digest = MessageDigest.getInstance(algorithm).digest(fileContents)
- println javax.xml.bind.DatatypeConverter.printHexBinary(digest) + "\t" + it
+ println MessageDigest.getInstance(algorithm).digest(it.bytes).encodeHex().toString() + "\t" + it
}
----
The new version of the script adds a header and footer, and the ability to print version information.
All text displayed in the usage help message and version information may contain format specifiers
-like the '`%n`' line separator.
+like the `%n` line separator.
The usage help message can also display ANSI colors and styles.
Picocli supports a simple markup syntax where `@|` starts an ANSI styled section and `|@` ends it.
Immediately following the `@|` is a comma-separated list of colors and styles,
-like `@|STYLE1[,STYLE2]… text|@`.
+like `@|STYLE1[,STYLE2]... text|@`.
See the picocli http://picocli.info/#_usage_help_with_styles_and_colors[user manual] for details on what colors and styles are available.
+The usage help message for the new script looks like this:
+
image:GroovyChecksumWithBanner.png[Customized header and footer with styles and colors]
The `@Command` annotation also has a `version = "checksum v1.2.3"` attribute.
@@ -181,8 +220,8 @@ For more details, see the http://picocli.info/#_version_help[Version Help] secti
== Conclusion
-The script above is surprisingly small given all the things it can do.
-Most of the code is actually description text for the usage help message.
+The `@PicocliScript` annotation allows Groovy scripts to omit boilerplate code and while adding powerful common command line application functionality.
+In the final version of our example script, most of the code is actually description text for the usage help message.
There is a lot more to picocli, give it a try!
diff --git a/docs/picocli-2.0-groovy-scripts-on-steroids.html b/docs/picocli-2.0-groovy-scripts-on-steroids.html
new file mode 100644
index 00000000..3244a2ca
--- /dev/null
+++ b/docs/picocli-2.0-groovy-scripts-on-steroids.html
@@ -0,0 +1,796 @@
+
+
+
Picocli 2.0 adds improved support for other JVM languages, especially Groovy.
+Why use picocli when the Groovy language has built-in CLI support with the CliBuilder class?
+
+
+
You may like picocli’s usage help, which shows ANSI colors and styles
+by default. Another feature you may fancy is the command line
+TAB autocompletion. Finally, there is a slew of smaller features,
+like the fact that your script needs zero lines of command line parsing code,
+picocli’s subcommand support,
+type conversion for both options and positional parameters,
+and parser tracing, to name a few.
+
+
+
+
+
+
+
+
Example
+
+
+
Let’s take a look at an example. The checksum.groovy script below takes one or more file parameters,
+and for each file prints out a checksum and the file name. The "checksum" algorithm is MD5 by default,
+but users may specify a different MessageDigest algorithm. Users can request usage help with the
+-h or --help option.
+
+
+
+
@Grab('info.picocli:picocli:2.0.1')
+@picocli.groovy.PicocliScript
+importgroovy.transform.Field
+importjava.security.MessageDigest
+importstaticpicocli.CommandLine.*
+
+@Parameters(arity="1", paramLabel="FILE", description="The file(s) whose checksum to calculate.")
+@FieldFile[] files
+
+@Option(names = ["-a", "--algorithm"], description = [
+ "MD2, MD5, SHA-1, SHA-256, SHA-384, SHA-512,",
+ " or any other MessageDigest algorithm."])
+@FieldString algorithm = "MD5"
+
+@Option(names= ["-h", "--help"], usageHelp= true, description= "Show this help message and exit.")
+@Fieldboolean helpRequested
+
+files.each {
+ println MessageDigest.getInstance(algorithm).digest(it.bytes).encodeHex().toString() + "\t" + it
+}
+
+
+
+
When run in the $picocli-home/examples/src/main/groovy/picocli/examples directory,
+this example script gives the following results:
The above example has explicit code to parse the command line, deal with invalid user input,
+and check for usage help requests.
+The first version of the script did not have any of this boilerplate code.
+
+
+
Let’s take a look at how this works.
+
+
+
+
+
Basescript
+
+
+
Scripts annotated with @picocli.groovy.PicocliScript are automatically transformed to use
+picocli.groovy.PicocliBaseScript as their base class.
+This turns a Groovy script into a picocli-based command line application.
+
+
+
+
+
+
When the script is run, Groovy calls the script’s run method.
+The PicocliBaseScript::run method takes care of parsing the command line and populating the script
+fields with the results. The run method does the following:
+
+
+
+
+
First, @Field variables annotated with @Option or @Parameters are initialized from the command line arguments.
+
+
+
If the user input was invalid, an error message is printed followed by the usage help message.
+
+
+
If the user requested usage help or version information, this is printed to the console and the script exits.
In addition to changing the script base class, the @PicocliScript annotation also allows Groovy
+scripts to use the @Command annotation directly, without introducing a helper class.
+The picocli parser will look for this annotation on the
+class containing the @Option and @Parameters-annotated fields. The same custom
+AST transformation
+that changes the script’s base class also moves any @Command annotation in the script to this
+transformed class so the picocli parser can pick it up.
+
+
+
+
+
Usage Help With Colors
+
+
+
The @Command annotation lets you customize parts of the usage help message like command name, description, headers, footers etc.
+
+
+
Let’s add some bells and whistles to the example script.
+(Credit to http://patorjk.com/software/taag/ for the ASCII Art Generator.)
+
+
+
+
@Grab('info.picocli:picocli:2.0.1')
+@Command(header = [
+ "@|bold,green ___ ___ _ _ |@",
+ "@|bold,green / __|_ _ ___ _____ ___ _ / __| |_ ___ __| |__ ____ _ _ __ |@",
+ "@|bold,green | (_ | '_/ _ \\/ _ \\ V / || | | (__| ' \\/ -_) _| / /(_-< || | ' \\ |@",
+ "@|bold,green \\___|_| \\___/\\___/\\_/ \\_, | \\___|_||_\\___\\__|_\\_\\/__/\\_,_|_|_|_||@",
+ "@|bold,green |__/ |@"
+ ],
+ description = "Print a checksum of each specified FILE.",
+ version = 'checksum v1.2.3', showDefaultValues = true,
+ footerHeading = "%nFor more details, see:%n",
+ footer = ["[1] https://docs.oracle.com/javase/9/docs/specs/security/standard-names.html",
+ "ASCII Art thanks to http://patorjk.com/software/taag/"]
+)
+@picocli.groovy.PicocliScript
+importgroovy.transform.Field
+importjava.security.MessageDigest
+importstaticpicocli.CommandLine.*
+
+@Parameters(arity="1", paramLabel="FILE", description="The file(s) whose checksum to calculate.")
+@FieldprivateFile[] files
+
+@Option(names = ["-a", "--algorithm"], description = [
+ "MD2, MD5, SHA-1, SHA-256, SHA-384, SHA-512, or",
+ " any other MessageDigest algorithm. See [1] for more details."])
+@FieldprivateString algorithm = "MD5"
+
+@Option(names= ["-h", "--help"], usageHelp=true, description="Show this help message and exit.")
+@Fieldprivateboolean helpRequested
+
+@Option(names= ["-V", "--version"], versionHelp=true, description="Show version info and exit.")
+@Fieldprivateboolean versionInfoRequested
+
+files.each {
+ println MessageDigest.getInstance(algorithm).digest(it.bytes).encodeHex().toString() + "\t" + it
+}
+
+
+
+
The new version of the script adds a header and footer, and the ability to print version information.
+All text displayed in the usage help message and version information may contain format specifiers
+like the %n line separator.
+
+
+
The usage help message can also display ANSI colors and styles.
+Picocli supports a simple markup syntax where @| starts an ANSI styled section and |@ ends it.
+Immediately following the @| is a comma-separated list of colors and styles,
+like @|STYLE1[,STYLE2]… text|@.
+See the picocli user manual for details on what colors and styles are available.
+
+
+
The usage help message for the new script looks like this:
+
+
+
+
+
+
The @Command annotation also has a version = "checksum v1.2.3" attribute.
+This version string is printed when the user specifies --version on the command line because
+we declared an @Option with that name with attribute versionHelp = true.
For more details, see the Version Help section of the user manual.
+
+
+
+
+
Conclusion
+
+
+
The @PicocliScript annotation allows Groovy scripts to omit boilerplate code and while adding powerful common command line application functionality.
+In the final version of our example script, most of the code is actually description text for the usage help message.
+
+
+
There is a lot more to picocli, give it a try!
+
+
+
Please star the project on GitHub if you like it and tell your friends!