Migrate to Asciidoctor Tabs
This commit is contained in:
@@ -10,9 +10,6 @@ antora:
|
||||
- '@antora/atlas-extension'
|
||||
- require: '@springio/antora-extensions/root-component-extension'
|
||||
root_component_name: 'shell'
|
||||
- require: '@springio/antora-extensions/tabs-migration-extension'
|
||||
unwrap_example_block: always
|
||||
save_result: true
|
||||
site:
|
||||
title: Spring Shell
|
||||
url: https://docs.spring.io/spring-shell/reference/
|
||||
|
||||
@@ -6,12 +6,10 @@ a shell application. It is possible to dynamically register and de-register
|
||||
commands, which gives flexibility for use cases where possible commands
|
||||
come and go, depending on a shell's state. Consider the following example:
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/CommandCatalogSnippets.java[tag=snippet1]
|
||||
----
|
||||
====
|
||||
|
||||
[[command-resolver]]
|
||||
== Command Resolver
|
||||
@@ -19,12 +17,10 @@ You can implement the `CommandResolver` interface and define a bean to dynamical
|
||||
resolve mappings from a command's name to its `CommandRegistration` instances. Consider
|
||||
the following example:
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/CommandCatalogSnippets.java[tag=snippet2]
|
||||
----
|
||||
====
|
||||
|
||||
IMPORTANT: A current limitation of a `CommandResolver` is that it is used every time commands are resolved.
|
||||
Thus, we advise not using it if a command resolution call takes a long time, as it would
|
||||
@@ -37,11 +33,9 @@ Its main use is to modify a catalog. Also, within `spring-shell` auto-configurat
|
||||
interface is used to register existing `CommandRegistration` beans into a catalog.
|
||||
Consider the following example:
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/CommandCatalogSnippets.java[tag=snippet3]
|
||||
----
|
||||
====
|
||||
|
||||
You can create a `CommandCatalogCustomizer` as a bean, and Spring Shell handles the rest.
|
||||
|
||||
@@ -5,19 +5,15 @@
|
||||
The `CommandContext` interface gives access to a currently running
|
||||
context. You can use it to get access to options:
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/CommandContextSnippets.java[tag=snippet1]
|
||||
----
|
||||
====
|
||||
|
||||
If you need to print something into a shell, you can get a `Terminal`
|
||||
and use its writer to print something:
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/CommandContextSnippets.java[tag=snippet2]
|
||||
----
|
||||
====
|
||||
|
||||
@@ -12,7 +12,6 @@ actual target code. Essentially, it is the definition of a command API that is s
|
||||
A command in a `spring-shell` structure is defined as an array of commands. This yields a
|
||||
structure similar to the following example:
|
||||
|
||||
====
|
||||
[source, bash]
|
||||
----
|
||||
command1 sub1
|
||||
@@ -20,7 +19,6 @@ command2 sub1 subsub1
|
||||
command2 sub2 subsub1
|
||||
command2 sub2 subsub2
|
||||
----
|
||||
====
|
||||
|
||||
NOTE: We do not currently support mapping commands to an explicit parent if sub-commands are defined.
|
||||
For example, `command1 sub1` and `command1 sub1 subsub1` cannot both be registered.
|
||||
@@ -44,19 +42,15 @@ doing within an active session.
|
||||
Options can be defined as long and short, where the prefixing is `--` and `-`, respectively.
|
||||
The following examples show long and short options:
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/CommandRegistrationSnippets.java[tag=snippet1]
|
||||
----
|
||||
====
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/CommandRegistrationSnippets.java[tag=snippet2]
|
||||
----
|
||||
====
|
||||
|
||||
[[target]]
|
||||
== Target
|
||||
@@ -68,21 +62,17 @@ a `Consumer`, or a `Function`.
|
||||
Using a `Method` in an existing POJO is one way to define a target.
|
||||
Consider the following class:
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/CommandTargetSnippets.java[tag=snippet11]
|
||||
----
|
||||
====
|
||||
|
||||
Given the existing class shown in the preceding listing, you can then register its method:
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/CommandTargetSnippets.java[tag=snippet12]
|
||||
----
|
||||
====
|
||||
|
||||
[[function]]
|
||||
=== Function
|
||||
@@ -91,12 +81,10 @@ happens in a command execution, because you can handle many things manually by u
|
||||
a `CommandContext` given to a `Function`. The return type from a `Function` is
|
||||
then what gets printed into the shell as a result. Consider the following example:
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/CommandTargetSnippets.java[tag=snippet2]
|
||||
----
|
||||
====
|
||||
|
||||
[[consumer]]
|
||||
=== Consumer
|
||||
@@ -105,9 +93,7 @@ that there is no return type. If you need to print something into a shell,
|
||||
you can get a reference to a `Terminal` from a context and print something
|
||||
through it. Consider the following example:
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/CommandTargetSnippets.java[tag=snippet3]
|
||||
----
|
||||
====
|
||||
|
||||
@@ -30,12 +30,10 @@ as we don't want to fully open these until we know API's are good to go
|
||||
for longer support. You need to construct `SearchMatch` via its
|
||||
build-in builder.
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/SearchAlgorithmsSnippets.java[tag=builder]
|
||||
----
|
||||
====
|
||||
|
||||
It's possible to configure _case sensitivity_, on what _direction_ search
|
||||
happens or if text should be _normilized_ before search happens. Normalization
|
||||
@@ -61,9 +59,7 @@ below table.
|
||||
[[examples]]
|
||||
== Examples
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/SearchAlgorithmsSnippets.java[tag=simple]
|
||||
----
|
||||
====
|
||||
|
||||
@@ -23,7 +23,6 @@ applied. Prefixing with `~` will resolve from JLine internal bsd color table.
|
||||
If rgb format is expected and prefixed with either `x` or `#` a normal
|
||||
hex format is used.
|
||||
|
||||
====
|
||||
[source, text]
|
||||
----
|
||||
fg-red
|
||||
@@ -32,30 +31,25 @@ fg-rgb:red
|
||||
fg-rgb:xff3333
|
||||
fg-rgb:#ff3333
|
||||
----
|
||||
====
|
||||
|
||||
If spec contains special names `default`, `bold`, `faint`, `italic`, `underline`, `blink`,
|
||||
`inverse`, `inverse-neg`, `inverseneg`, `conceal`, `crossed-out`, `crossedout` or `hidden`
|
||||
a style is changed accordingly with an existing color.
|
||||
|
||||
====
|
||||
[source, text]
|
||||
----
|
||||
bold
|
||||
bold,fg:red
|
||||
----
|
||||
====
|
||||
|
||||
If spec is a number or numbers separated with semicolon, format is a plain part of an ansi
|
||||
ascii codes.
|
||||
|
||||
====
|
||||
[source, text]
|
||||
----
|
||||
31
|
||||
31;1
|
||||
----
|
||||
====
|
||||
|
||||
NOTE: JLine special mapping format which would resolve spec starting with dot can't be
|
||||
used as we don't yet map those into Spring Shell styling names.
|
||||
|
||||
@@ -19,7 +19,6 @@ NOTE: _Spring Shell_ version on `start.spring.io` is usually latest release.
|
||||
|
||||
With _maven_ you're expected to have something like:
|
||||
|
||||
====
|
||||
[source, xml, subs=attributes+]
|
||||
----
|
||||
<properties>
|
||||
@@ -49,11 +48,9 @@ With _maven_ you're expected to have something like:
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
----
|
||||
====
|
||||
|
||||
With _gradle_ you're expected to have something like:
|
||||
|
||||
====
|
||||
[source, groovy, subs=attributes+]
|
||||
----
|
||||
dependencies {
|
||||
@@ -68,7 +65,6 @@ dependencyManagement {
|
||||
}
|
||||
}
|
||||
----
|
||||
====
|
||||
|
||||
CAUTION: Given that Spring Shell starts the REPL (Read-Eval-Print-Loop) because this
|
||||
dependency is present, you need to either skip tests when you build (`-DskipTests`)
|
||||
@@ -79,19 +75,15 @@ the eval loop or crashes with a NPE.
|
||||
|
||||
Once compiled it can be run either in interactive mode:
|
||||
|
||||
====
|
||||
[source, text, subs=attributes+]
|
||||
----
|
||||
----
|
||||
====
|
||||
|
||||
Or in non-interactive mode:
|
||||
|
||||
====
|
||||
[source, text, subs=attributes+]
|
||||
----
|
||||
----
|
||||
====
|
||||
|
||||
TIP: Check out xref:using-shell-customization-logging.adoc[Logging] making logging to work
|
||||
better with shell apps.
|
||||
@@ -108,7 +100,6 @@ returns it with "Hello world". Add `@ShellMethod` and optionally change command
|
||||
using `key` parameter. You can use `@ShellOption` to define argument default value
|
||||
if it's not given when running a command.
|
||||
|
||||
====
|
||||
[source, java]
|
||||
----
|
||||
package com.example.demo;
|
||||
@@ -128,21 +119,17 @@ public class MyCommands {
|
||||
}
|
||||
}
|
||||
----
|
||||
====
|
||||
|
||||
New _hello-world_ command becomes visible to _help_:
|
||||
|
||||
====
|
||||
[source, text]
|
||||
----
|
||||
My Commands
|
||||
hello-world:
|
||||
----
|
||||
====
|
||||
|
||||
And you can run it:
|
||||
|
||||
====
|
||||
[source, text]
|
||||
----
|
||||
shell:>hello-world
|
||||
@@ -151,6 +138,5 @@ Hello world spring
|
||||
shell:>hello-world --arg boot
|
||||
Hello world boot
|
||||
----
|
||||
====
|
||||
|
||||
The rest of this document delves deeper into the whole Spring Shell programming model.
|
||||
|
||||
@@ -23,7 +23,6 @@ _GraalVM_ installed and `JAVA_HOME` pointing to that.
|
||||
|
||||
For _gradle_ add graalvm's native plugin and configure metadata repository.
|
||||
|
||||
====
|
||||
[source, groovy, subs=attributes+]
|
||||
----
|
||||
plugins {
|
||||
@@ -36,7 +35,6 @@ graalvmNative {
|
||||
}
|
||||
}
|
||||
----
|
||||
====
|
||||
|
||||
When gradle build is run with `./gradlew nativeCompile` you should get binary
|
||||
under `build/native/nativeCompile` directory.
|
||||
@@ -44,7 +42,6 @@ under `build/native/nativeCompile` directory.
|
||||
For `maven` use `spring-boot-starter-parent` as parent and you'll get `native`
|
||||
profile which can be used to do a compilation. You need to configure metadata repository
|
||||
|
||||
====
|
||||
[source, xml, subs=attributes+]
|
||||
----
|
||||
<build>
|
||||
@@ -63,7 +60,6 @@ profile which can be used to do a compilation. You need to configure metadata re
|
||||
</pluginManagement>
|
||||
</build>
|
||||
----
|
||||
====
|
||||
|
||||
NOTE: If you rely on `spring-boot-starter-parent` it manages `native-maven-plugin`
|
||||
version which is kept up to date.
|
||||
|
||||
@@ -12,7 +12,6 @@ There are three possible ways for a command to indicate availability.
|
||||
They all use a no-arg method that returns an instance of `Availability`.
|
||||
Consider the following example:
|
||||
|
||||
====
|
||||
[source, java]
|
||||
----
|
||||
@ShellComponent
|
||||
@@ -38,7 +37,6 @@ public class MyCommands {
|
||||
}
|
||||
}
|
||||
----
|
||||
====
|
||||
|
||||
The `connect` method is used to connect to the server (details omitted), altering the state
|
||||
of the command through the `connected` boolean when done.
|
||||
@@ -48,14 +46,12 @@ The method returns an instance of `Availability`, constructed with one of the tw
|
||||
If the command is not available, an explanation has to be provided.
|
||||
Now, if the user tries to invoke the command while not being connected, here is what happens:
|
||||
|
||||
====
|
||||
[source]
|
||||
----
|
||||
shell:>download
|
||||
Command 'download' exists but is not currently available because you are not connected.
|
||||
Details of the error have been omitted. You can use the stacktrace command to print the full stacktrace.
|
||||
----
|
||||
====
|
||||
|
||||
Information about currently unavailable commands is also used in the integrated help. See xref:using-shell-commands-builtin-help.adoc[Help].
|
||||
|
||||
@@ -69,7 +65,6 @@ You should not start the sentence with a capital or add a final period
|
||||
If naming the availability method after the name of the command method does not suit you, you
|
||||
can provide an explicit name by using the `@ShellMethodAvailability` annotation:
|
||||
|
||||
====
|
||||
[source, java]
|
||||
----
|
||||
@ShellMethod("Download the nuclear codes.")
|
||||
@@ -85,14 +80,12 @@ can provide an explicit name by using the `@ShellMethodAvailability` annotation:
|
||||
}
|
||||
----
|
||||
<1> the names have to match
|
||||
====
|
||||
|
||||
Finally, it is often the case that several commands in the same class share the same internal state and, thus,
|
||||
should all be available or unavailable as a group. Instead of having to stick the `@ShellMethodAvailability`
|
||||
on all command methods, Spring Shell lets you flip things around and put the `@ShellMethodAvailabilty`
|
||||
annotation on the availability method, specifying the names of the commands that it controls:
|
||||
|
||||
====
|
||||
[source, java]
|
||||
----
|
||||
@ShellMethod("Download the nuclear codes.")
|
||||
@@ -112,7 +105,6 @@ annotation on the availability method, specifying the names of the commands that
|
||||
: Availability.unavailable("you are not connected");
|
||||
}
|
||||
----
|
||||
====
|
||||
|
||||
[TIP]
|
||||
=====
|
||||
@@ -120,7 +112,6 @@ The default value for the `@ShellMethodAvailability.value()` attribute is `*`. T
|
||||
wildcard matches all command names. This makes it easy to turn all commands of a single class on or off
|
||||
with a single availability method:
|
||||
|
||||
====
|
||||
[source,java]
|
||||
----
|
||||
@ShellComponent
|
||||
@@ -139,7 +130,6 @@ public class Toggles {
|
||||
public void bar() {}
|
||||
}
|
||||
----
|
||||
====
|
||||
=====
|
||||
|
||||
TIP: Spring Shell does not impose many constraints on how to write commands and how to organize classes.
|
||||
|
||||
@@ -10,7 +10,6 @@ command comes in.
|
||||
Typing `help` + `ENTER` lists all the commands known to the shell (including xref:using-shell-commands-availability.adoc[unavailable] commands)
|
||||
and a short description of what they do, similar to the following:
|
||||
|
||||
====
|
||||
[source, bash]
|
||||
----
|
||||
my-shell:>help
|
||||
@@ -27,14 +26,12 @@ Built-In Commands
|
||||
version: Show version info
|
||||
script: Read and execute commands from a file.
|
||||
----
|
||||
====
|
||||
|
||||
Typing `help <command>` shows more detailed information about a command, including the available parameters, their
|
||||
type, whether they are mandatory or not, and other details.
|
||||
|
||||
The following listing shows the `help` command applied to itself:
|
||||
|
||||
====
|
||||
[source, bash]
|
||||
----
|
||||
my-shell:>help help
|
||||
@@ -49,7 +46,6 @@ OPTIONS
|
||||
The command to obtain help for.
|
||||
[Optional]
|
||||
----
|
||||
====
|
||||
|
||||
Help is templated and can be customized if needed. Settings are under `spring.shell.command.help` where you can use
|
||||
`enabled` to disable command, `grouping-mode` taking `group` or `flat` if you want to hide groups by flattening
|
||||
@@ -58,7 +54,6 @@ output of a command list.
|
||||
|
||||
If `spring.shell.command.help.grouping-mode=flat` is set, then help would show:
|
||||
|
||||
====
|
||||
[source, bash]
|
||||
----
|
||||
my-shell:>help help
|
||||
@@ -74,7 +69,6 @@ completion bash: Generate bash completion script
|
||||
version: Show version info
|
||||
script: Read and execute commands from a file.
|
||||
----
|
||||
====
|
||||
|
||||
Output from `help` and `help <commmand>` are both templated with a default implementation
|
||||
which can be changed.
|
||||
|
||||
@@ -16,21 +16,17 @@ fields in a default template.
|
||||
The template defaults to `classpath:template/version-default.st`, and you can define
|
||||
your own, as the following example shows:
|
||||
|
||||
====
|
||||
[source]
|
||||
----
|
||||
<buildVersion>
|
||||
----
|
||||
====
|
||||
|
||||
This setting would output something like the following:
|
||||
|
||||
====
|
||||
[source]
|
||||
----
|
||||
X.X.X
|
||||
----
|
||||
====
|
||||
|
||||
You can add the following attributes to the default template rendering: `buildVersion`, `buildGroup`,
|
||||
`buildGroup`, `buildName`, `buildTime`, `gitShortCommitId`, `gitCommitId`,
|
||||
|
||||
@@ -18,40 +18,32 @@ is used to sort exceptions based on their depth from the thrown exception type.
|
||||
Alternatively, the annotation declaration may narrow the exception types to match, as the
|
||||
following example shows:
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/ErrorHandlingSnippets.java[tag=exception-resolver-with-type-in-annotation]
|
||||
----
|
||||
====
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/ErrorHandlingSnippets.java[tag=exception-resolver-with-type-in-method]
|
||||
----
|
||||
====
|
||||
|
||||
`@ExceptionResolver` can also return `String` which is used as an output to console. You can
|
||||
use `@ExitCode` annotation to define return code.
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/ErrorHandlingSnippets.java[tag=exception-resolver-with-exitcode-annotation]
|
||||
----
|
||||
====
|
||||
|
||||
`@ExceptionResolver` with `void` return type is automatically handled as handled exception.
|
||||
You can then also define `@ExitCode` and use `Terminal` if you need to write something
|
||||
into console.
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/ErrorHandlingSnippets.java[tag=exception-resolver-with-void]
|
||||
----
|
||||
====
|
||||
|
||||
[[method-arguments]]
|
||||
== Method Arguments
|
||||
|
||||
@@ -15,21 +15,17 @@ integrate into that.
|
||||
|
||||
Assuming there is an exception show below which would be thrown from a command:
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/ExitCodeSnippets.java[tag=my-exception-class]
|
||||
----
|
||||
====
|
||||
|
||||
It is possible to define a mapping function between `Throwable` and exit code. You can also
|
||||
just configure a _class_ to _exit code_ which is just a syntactic sugar within configurations.
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/ExitCodeSnippets.java[tag=example1]
|
||||
----
|
||||
====
|
||||
|
||||
NOTE: Exit codes cannot be customized with annotation based configuration
|
||||
|
||||
@@ -9,30 +9,24 @@ can be used to resolve exceptions and gives you flexibility to return message to
|
||||
into console together with exit code which are wrapped within `CommandHandlingResult`.
|
||||
`CommandHandlingResult` may contain a _message_ and/or _exit code_.
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/ErrorHandlingSnippets.java[tag=my-exception-resolver-class]
|
||||
----
|
||||
====
|
||||
|
||||
`CommandExceptionResolver` implementations can be defined globally as bean.
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/ErrorHandlingSnippets.java[tag=my-exception-resolver-class-as-bean]
|
||||
----
|
||||
====
|
||||
|
||||
or defined per `CommandRegistration` if it's applicable only for a particular command itself.
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/ErrorHandlingSnippets.java[tag=example1]
|
||||
----
|
||||
====
|
||||
|
||||
NOTE: Resolvers defined with a command are handled before global resolvers.
|
||||
|
||||
@@ -40,12 +34,10 @@ NOTE: Resolvers defined with a command are handled before global resolvers.
|
||||
Use you own exception types which can also be an instance of boot's `ExitCodeGenerator` if
|
||||
you want to define exit code there.
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/ErrorHandlingSnippets.java[tag=my-exception-class]
|
||||
----
|
||||
====
|
||||
|
||||
Some build in `CommandExceptionResolver` beans are registered to handle common
|
||||
exceptions thrown from command parsing. These are registered with _order_
|
||||
|
||||
@@ -15,16 +15,13 @@ what other command-line options is typed.
|
||||
|
||||
Below example shows its default settings.
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/CommandRegistrationHelpOptionsSnippets.java[tag=defaults]
|
||||
----
|
||||
====
|
||||
|
||||
It is possible to change default behaviour via configuration options.
|
||||
|
||||
====
|
||||
[source, yaml]
|
||||
----
|
||||
spring:
|
||||
@@ -35,7 +32,6 @@ spring:
|
||||
short-names: h
|
||||
command: help
|
||||
----
|
||||
====
|
||||
|
||||
NOTE: Commands defined programmationally or via annotations will automatically add
|
||||
help options. With annotation model you can only turn things off globally, programmatic
|
||||
|
||||
@@ -18,11 +18,9 @@ from:
|
||||
Below is an example how to define command as _hidden_. It shows available builder methods
|
||||
to define _hidden_ state.
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/CommandRegistrationHiddenSnippets.java[tag=snippet1]
|
||||
----
|
||||
====
|
||||
|
||||
NOTE: Defining hidden commands is not supported with annotation based configuration
|
||||
|
||||
@@ -9,18 +9,14 @@ depending which mode shell is executing. More about that in xref:using-shell-exe
|
||||
|
||||
You can define it with `CommandRegisration`.
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/CommandRegistrationInteractionModeSnippets.java[tag=snippet1]
|
||||
----
|
||||
====
|
||||
|
||||
Or with `@ShellMethod`.
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/CommandRegistrationInteractionModeSnippets.java[tag=snippet2]
|
||||
----
|
||||
====
|
||||
|
||||
@@ -27,7 +27,6 @@ package (unless overridden at the method or class level, as explained earlier).
|
||||
|
||||
The following listing shows an example:
|
||||
|
||||
====
|
||||
[source,java]
|
||||
----
|
||||
public class UserCommands {
|
||||
@@ -51,4 +50,3 @@ public class SomeCommands {
|
||||
public void last() {}
|
||||
}
|
||||
----
|
||||
====
|
||||
|
||||
@@ -6,23 +6,19 @@ ifndef::snippets[:snippets: ../../test/java/org/springframework/shell/docs]
|
||||
`@Command` annotation when used on a method marks it as a candidate for command registration.
|
||||
In below example a command `example` is defined.
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/CommandAnnotationSnippets.java[tag=command-anno-in-method]
|
||||
----
|
||||
====
|
||||
|
||||
`@Command` annotation can be placed on a class which either defines defaults or shared settings
|
||||
for `@Command` methods defined in a same class. In below example a command `parent example` is
|
||||
defined.
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/CommandAnnotationSnippets.java[tag=command-anno-in-class]
|
||||
----
|
||||
====
|
||||
|
||||
Using a `@Command` will not automatically register command targets, instead it is required to use
|
||||
`@EnableCommand` and/or `@CommandScan` annotations. This model is familiar from other parts
|
||||
@@ -32,12 +28,10 @@ for command targets.
|
||||
You can define target classes using `@EnableCommand`. It will get picked from all _Configuration_
|
||||
classes.
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/CommandAnnotationSnippets.java[tag=enablecommand-with-class]
|
||||
----
|
||||
====
|
||||
|
||||
You can define target classes using `@CommandScan`. It will get picked from all _Configuration_
|
||||
classes.
|
||||
@@ -45,9 +39,7 @@ classes.
|
||||
TIP: Define `@CommandScan` in Spring Boot `App` class on a top level and it will automatically
|
||||
scan all command targets from all packages and classes under `App`.
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/CommandAnnotationSnippets.java[tag=commandscan-no-args]
|
||||
----
|
||||
====
|
||||
|
||||
@@ -17,12 +17,10 @@ you can use it in addition to the filtering mechanism to declare beans (for exam
|
||||
You can customize the name of the created bean by using the `value` attribute of the annotation.
|
||||
====
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/AnnotationRegistrationSnippets.java[tag=snippet1]
|
||||
----
|
||||
====
|
||||
|
||||
The only required attribute of the `@ShellMethod` annotation is its `value` attribute, which should have
|
||||
a short, one-sentence, description of what the command does. This lets your users
|
||||
@@ -37,12 +35,10 @@ dashed, gnu-style, names (for example, `sayHello()` becomes `say-hello`).
|
||||
|
||||
You can, however, explicitly set the command key, by using the `key` attribute of the annotation:
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/AnnotationRegistrationSnippets.java[tag=snippet2]
|
||||
----
|
||||
====
|
||||
|
||||
NOTE: The `key` attribute accepts multiple values.
|
||||
If you set multiple keys for a single method, the command is registered with those different aliases.
|
||||
|
||||
@@ -6,12 +6,10 @@ ifndef::snippets[:snippets: ../../test/java/org/springframework/shell/docs]
|
||||
In the programmatic model, `CommandRegistration` can be defined as a `@Bean`
|
||||
and it will be automatically registered.
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/CommandRegistrationBeanSnippets.java[tag=plain]
|
||||
----
|
||||
====
|
||||
|
||||
If all your commands have something in common, an instance of
|
||||
a _CommandRegistration.BuilderSupplier_ is created which can
|
||||
@@ -24,19 +22,15 @@ add _help options_ mentioned in xref:using-shell-commands-helpoptions.adoc[Help
|
||||
If bean of this supplier type is defined then auto-configuration
|
||||
will back off giving you an option to redefine default functionality.
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/CommandRegistrationBeanSnippets.java[tag=fromsupplier]
|
||||
----
|
||||
====
|
||||
|
||||
`CommandRegistrationCustomizer` beans can be defined if you want to centrally
|
||||
modify builder instance given you by supplier mentioned above.
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/CommandRegistrationBeanSnippets.java[tag=customizer]
|
||||
----
|
||||
====
|
||||
|
||||
@@ -12,18 +12,14 @@ If using target endpoints, i.e. _consumer_ which is not expected
|
||||
to return anything given `CommandContext` contains reference to
|
||||
`Terminal` and writer can be accessed from there.
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/WritingSnippets.java[tag=reg-terminal-writer]
|
||||
----
|
||||
====
|
||||
|
||||
It's possible to autowire `Terminal` to get access to its writer.
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/WritingSnippets.java[tag=anno-terminal-writer]
|
||||
----
|
||||
====
|
||||
|
||||
@@ -23,43 +23,35 @@ for all commands and scenarious. For example existing completion
|
||||
implementation `RegistrationOptionsCompletionResolver` handles completions
|
||||
for a option names.
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/CompletionSnippets.java[tag=resolver-1]
|
||||
----
|
||||
====
|
||||
|
||||
Option values with builder based command registration can be
|
||||
defined per option.
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/CompletionSnippets.java[tag=builder-1]
|
||||
----
|
||||
====
|
||||
|
||||
Option values with annotation based command registration are handled
|
||||
via `ValueProvider` interface which can be defined with `@ShellOption`
|
||||
annotation.
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/CompletionSnippets.java[tag=provider-1]
|
||||
----
|
||||
====
|
||||
|
||||
Actual `ValueProvider` with annotation based command needs to be
|
||||
registered as a _Bean_.
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/CompletionSnippets.java[tag=anno-method]
|
||||
----
|
||||
====
|
||||
|
||||
[[command-line]]
|
||||
== Command-Line
|
||||
|
||||
@@ -11,12 +11,10 @@ as a "`flow`".
|
||||
|
||||
The following listings show examples of flows and their output in a shell:
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/FlowComponentSnippets.java[tag=snippet1]
|
||||
----
|
||||
====
|
||||
|
||||
image::component-flow-showcase-1.svg[text input]
|
||||
|
||||
@@ -25,12 +23,10 @@ possible to conditionally choose where to jump in a flow by using a `next`
|
||||
function and returning target _component id_. If this returned id is aither _null_
|
||||
or doesn't exist flow is essentially stopped right there.
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/FlowComponentSnippets.java[tag=snippet2]
|
||||
----
|
||||
====
|
||||
|
||||
image::component-flow-conditional-1.svg[text input]
|
||||
|
||||
|
||||
@@ -6,12 +6,10 @@ ifndef::snippets[:snippets: ../../test/java/org/springframework/shell/docs]
|
||||
The confirmation component asks a user for a simple confirmation. It is essentially a
|
||||
yes-or-no question.
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/UiComponentSnippets.java[tag=snippet5]
|
||||
----
|
||||
====
|
||||
|
||||
The following image shows the typical output from a confirmation component:
|
||||
|
||||
|
||||
@@ -6,12 +6,10 @@ ifndef::snippets[:snippets: ../../test/java/org/springframework/shell/docs]
|
||||
The multi select component asks a user to select multiple items from a list.
|
||||
The following listing shows an example:
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/UiComponentSnippets.java[tag=snippet7]
|
||||
----
|
||||
====
|
||||
|
||||
The following image shows a typical multi-select component:
|
||||
|
||||
|
||||
@@ -5,12 +5,10 @@ ifndef::snippets[:snippets: ../../test/java/org/springframework/shell/docs]
|
||||
|
||||
The path input component asks a user for a `Path` and gives additional information about a path itself.
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/UiComponentSnippets.java[tag=snippet4]
|
||||
----
|
||||
====
|
||||
|
||||
The following image shows typical output from a path input component:
|
||||
|
||||
|
||||
@@ -7,12 +7,10 @@ The path search component asks base directory for scan and optional search expre
|
||||
Results are shown in a single select list where user can pick a path.
|
||||
`PathSearchConfig` can be used to customise component behaviour.
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/UiComponentSnippets.java[tag=snippet9]
|
||||
----
|
||||
====
|
||||
|
||||
NOTE: Logic for search is passed as is into algorithms documented
|
||||
in xref:appendices-techical-intro-searchalgorithm.adoc[Search Algorithms].
|
||||
|
||||
@@ -15,21 +15,17 @@ through code then gives you flexibility to do whatever you need.
|
||||
|
||||
The programmatic way to render is to create a `Function`:
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/UiComponentSnippets.java[tag=snippet1]
|
||||
----
|
||||
====
|
||||
|
||||
Then you can hook it to a component:
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/UiComponentSnippets.java[tag=snippet2]
|
||||
----
|
||||
====
|
||||
|
||||
Components have their own context but usually share some functionality
|
||||
from a parent component types. The following tables show those context variables:
|
||||
|
||||
@@ -6,12 +6,10 @@ ifndef::snippets[:snippets: ../../test/java/org/springframework/shell/docs]
|
||||
A single select component asks a user to choose one item from a list. It is similar to a simple
|
||||
dropbox implementation. The following listing shows an example:
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/UiComponentSnippets.java[tag=snippet6]
|
||||
----
|
||||
====
|
||||
|
||||
The following image shows typical output for a single select component:
|
||||
|
||||
@@ -38,9 +36,7 @@ You can pre-select an item by defining it to get exposed. This is
|
||||
useful if you know the default and lets the user merely press `Enter` to make a choice.
|
||||
The following listing sets a default:
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/UiComponentSnippets.java[tag=snippet8]
|
||||
----
|
||||
====
|
||||
|
||||
@@ -6,12 +6,10 @@ ifndef::snippets[:snippets: ../../test/java/org/springframework/shell/docs]
|
||||
The string input component asks a user for simple text input, optionally masking values
|
||||
if the content contains something sensitive. The following listing shows an example:
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/UiComponentSnippets.java[tag=snippet3]
|
||||
----
|
||||
====
|
||||
|
||||
The following image shows typical output from a string input component:
|
||||
|
||||
|
||||
@@ -6,40 +6,32 @@ ifndef::snippets[:snippets: ../../test/java/org/springframework/shell/docs]
|
||||
On default a missing command is handled via `CommandNotFoundResultHandler`
|
||||
and outputs a simple message:
|
||||
|
||||
====
|
||||
[source, text]
|
||||
----
|
||||
shell:>missing
|
||||
No command found for 'missing'
|
||||
----
|
||||
====
|
||||
|
||||
Internally `CommandNotFoundResultHandler` is using `CommandNotFoundMessageProvider`
|
||||
which is a simple function taking a `ProviderContext` and returning a text
|
||||
message. Below is an example what a custom message provider might look like.
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/CommandNotFoundSnippets.java[tag=custom-provider]
|
||||
----
|
||||
====
|
||||
|
||||
It's possible to change this implementation by defining it as a bean.
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/CommandNotFoundSnippets.java[tag=provider-bean-1]
|
||||
----
|
||||
====
|
||||
|
||||
`CommandNotFoundResultHandler` is a functional interface so it can
|
||||
be writter as a lambda.
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/CommandNotFoundSnippets.java[tag=provider-bean-2]
|
||||
----
|
||||
====
|
||||
|
||||
@@ -7,29 +7,24 @@ Fortunately there is a simple way to instruct logging changes via boot propertie
|
||||
|
||||
Completely silence console logging by defining its pattern as an empty value.
|
||||
|
||||
====
|
||||
[source, yaml]
|
||||
----
|
||||
logging:
|
||||
pattern:
|
||||
console:
|
||||
----
|
||||
====
|
||||
|
||||
If you need log from a shell then write those into a file.
|
||||
|
||||
====
|
||||
[source, yaml]
|
||||
----
|
||||
logging:
|
||||
file:
|
||||
name: shell.log
|
||||
----
|
||||
====
|
||||
|
||||
If you need different log levels.
|
||||
|
||||
====
|
||||
[source, yaml]
|
||||
----
|
||||
logging:
|
||||
@@ -38,18 +33,15 @@ logging:
|
||||
springframework:
|
||||
shell: debug
|
||||
----
|
||||
====
|
||||
|
||||
Passing contiguration properties as command line options is not supported but
|
||||
you can use any other ways supported by boot, for example.
|
||||
|
||||
====
|
||||
[source, bash]
|
||||
----
|
||||
$ java -Dlogging.level.root=debug -jar demo.jar
|
||||
$ LOGGING_LEVEL_ROOT=debug java -jar demo.jar
|
||||
----
|
||||
====
|
||||
|
||||
NOTE: In a GraalVM image settings are locked during compilation which means
|
||||
you can't change log levels at runtime.
|
||||
|
||||
@@ -10,7 +10,6 @@ command it may be beneficial to configure it for this. Property
|
||||
runners than `NonInteractiveShellRunner` and configures it to use
|
||||
defined _Primary Command_.
|
||||
|
||||
====
|
||||
[source, yaml]
|
||||
----
|
||||
spring:
|
||||
@@ -18,7 +17,6 @@ spring:
|
||||
noninteractive:
|
||||
primary-command: mycommand
|
||||
----
|
||||
====
|
||||
|
||||
For example if you have a command `mycommand` with option `arg`
|
||||
it had to be executed with `<shellapp> mycommand --arg hi`, but with above
|
||||
|
||||
@@ -21,49 +21,39 @@ no styling for colors and tries to not use any special figures.
|
||||
|
||||
Modify existing style by overriding settings.
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/ThemingSnippets.java[tag=custom-style-class]
|
||||
----
|
||||
====
|
||||
|
||||
Modify existing figures by overriding settings.
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/ThemingSnippets.java[tag=custom-figure-class]
|
||||
----
|
||||
====
|
||||
|
||||
To create a new theme, create a `ThemeSettings` and provide your own _style_
|
||||
and _figure_ implementations.
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/ThemingSnippets.java[tag=custom-theme-class]
|
||||
----
|
||||
====
|
||||
|
||||
Register a new bean `Theme` where you can return your custom `ThemeSettings`
|
||||
and a _theme_ name.
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/ThemingSnippets.java[tag=custom-theme-config]
|
||||
----
|
||||
====
|
||||
|
||||
You can use `ThemeResolver` to resolve _styles_ if you want to create
|
||||
JLine-styled strings programmatically and _figures_ if you want to
|
||||
theme characters for being more pretty.
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/ThemingSnippets.java[tag=using-theme-resolver]
|
||||
----
|
||||
====
|
||||
|
||||
@@ -9,23 +9,29 @@ NOTE: There are limitations in a `legacy annotation` compared to `annotation`
|
||||
and `programmatic` use of arity settings. These are mentioned in notes in
|
||||
below samples.
|
||||
|
||||
[tabs]
|
||||
======
|
||||
Programmatic::
|
||||
+
|
||||
[source,java,indent=0,role="primary"]
|
||||
.Programmatic
|
||||
----
|
||||
include::{snippets}/OptionSnippets.java[tag=option-registration-zeroorone-programmatic]
|
||||
----
|
||||
|
||||
Annotation::
|
||||
+
|
||||
[source,java,indent=0,role="secondary"]
|
||||
.Annotation
|
||||
----
|
||||
include::{snippets}/OptionSnippets.java[tag=option-registration-zeroorone-annotation]
|
||||
----
|
||||
|
||||
Legacy Annotation::
|
||||
+
|
||||
[source,java,indent=0,role="secondary"]
|
||||
.Legacy Annotation
|
||||
----
|
||||
include::{snippets}/OptionSnippets.java[tag=option-registration-zeroorone-legacyannotation]
|
||||
----
|
||||
======
|
||||
|
||||
[[using-shell-options-arity-optionarity-table]]
|
||||
.OptionArity
|
||||
@@ -51,30 +57,35 @@ include::{snippets}/OptionSnippets.java[tag=option-registration-zeroorone-legacy
|
||||
|
||||
NOTE: `legacy annotation` doesn't support defining minimum arity.
|
||||
|
||||
[tabs]
|
||||
======
|
||||
Programmatic::
|
||||
+
|
||||
[source,java,indent=0,role="primary"]
|
||||
.Programmatic
|
||||
----
|
||||
include::{snippets}/OptionSnippets.java[tag=option-registration-zerooronewithminmax-programmatic]
|
||||
----
|
||||
|
||||
Annotation::
|
||||
+
|
||||
[source,java,indent=0,role="secondary"]
|
||||
.Annotation
|
||||
----
|
||||
include::{snippets}/OptionSnippets.java[tag=option-registration-zerooronewithminmax-annotation]
|
||||
----
|
||||
|
||||
Legacy Annotation::
|
||||
+
|
||||
[source,java,indent=0,role="secondary"]
|
||||
.Legacy Annotation
|
||||
----
|
||||
include::{snippets}/OptionSnippets.java[tag=option-registration-zerooronewithminmax-legacyannotation]
|
||||
----
|
||||
======
|
||||
|
||||
In below example we have option _arg1_ and it's defined as type _String[]_. Arity
|
||||
defines that it needs at least 1 parameter and not more that 2. As seen in below
|
||||
spesific exceptions _TooManyArgumentsOptionException_ and
|
||||
_NotEnoughArgumentsOptionException_ are thrown to indicate arity mismatch.
|
||||
|
||||
====
|
||||
[source, bash]
|
||||
----
|
||||
shell:>e2e reg arity-errors --arg1
|
||||
@@ -89,4 +100,3 @@ Hello [one, two]
|
||||
shell:>e2e reg arity-errors --arg1 one two three
|
||||
Too many arguments --arg1 requires at most 2.
|
||||
----
|
||||
====
|
||||
|
||||
@@ -7,9 +7,7 @@ ifndef::snippets[:snippets: ../../test/java/org/springframework/shell/docs]
|
||||
`Option` annotation can be used to define an option name if you
|
||||
don't want it to be same as argument name.
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/OptionSnippets.java[tag=option-with-option-annotation]
|
||||
----
|
||||
====
|
||||
|
||||
@@ -6,29 +6,23 @@ ifndef::snippets[:snippets: ../../test/java/org/springframework/shell/docs]
|
||||
Having a target method with argument is automatically registered with a matching
|
||||
argument name.
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/OptionSnippets.java[tag=option-without-annotation]
|
||||
----
|
||||
====
|
||||
|
||||
`@ShellOption` annotation can be used to define an option name if you
|
||||
don't want it to be same as argument name.
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/OptionSnippets.java[tag=option-with-annotation]
|
||||
----
|
||||
====
|
||||
|
||||
If option name is defined without prefix, either `-` or `--`, it is discovered
|
||||
from _ShellMethod#prefix_.
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/OptionSnippets.java[tag=option-with-annotation-without-prefix]
|
||||
----
|
||||
====
|
||||
|
||||
@@ -8,12 +8,10 @@ ifndef::snippets[:snippets: ../../test/java/org/springframework/shell/docs]
|
||||
Programmatic way with `CommandRegistration` is to use `withOption` to define
|
||||
an option.
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/OptionSnippets.java[tag=option-registration-longarg]
|
||||
----
|
||||
====
|
||||
|
||||
`CommandRegistration` can be defined as a bean or manually registered
|
||||
with a `CommandCatalog`.
|
||||
|
||||
@@ -8,20 +8,26 @@ xref:using-shell-options-optional.adoc[Optional Value], as there are cases where
|
||||
may want to know if the user defined an option and change behavior
|
||||
based on a default value:
|
||||
|
||||
[tabs]
|
||||
======
|
||||
Programmatic::
|
||||
+
|
||||
[source,java,indent=0,role="primary"]
|
||||
.Programmatic
|
||||
----
|
||||
include::{snippets}/OptionSnippets.java[tag=option-default-programmatic]
|
||||
----
|
||||
|
||||
Annotation::
|
||||
+
|
||||
[source,java,indent=0,role="secondary"]
|
||||
.Annotation
|
||||
----
|
||||
include::{snippets}/OptionSnippets.java[tag=option-default-annotation]
|
||||
----
|
||||
|
||||
Legacy Annotation::
|
||||
+
|
||||
[source,java,indent=0,role="secondary"]
|
||||
.Legacy Annotation
|
||||
----
|
||||
include::{snippets}/OptionSnippets.java[tag=option-default-legacyannotation]
|
||||
----
|
||||
======
|
||||
|
||||
@@ -10,20 +10,24 @@ you may want to give better descriptive word for an option.
|
||||
|
||||
NOTE: Label is not supported with `legacy annotation`.
|
||||
|
||||
[tabs]
|
||||
======
|
||||
Programmatic::
|
||||
+
|
||||
[source,java,indent=0,role="primary"]
|
||||
.Programmatic
|
||||
----
|
||||
include::{snippets}/OptionSnippets.java[tag=option-label-programmatic]
|
||||
----
|
||||
|
||||
Annotation::
|
||||
+
|
||||
[source,java,indent=0,role="secondary"]
|
||||
.Annotation
|
||||
----
|
||||
include::{snippets}/OptionSnippets.java[tag=option-label-annotation]
|
||||
----
|
||||
======
|
||||
|
||||
Defining label is then shown in `help`.
|
||||
====
|
||||
[source, bash]
|
||||
----
|
||||
my-shell:>help labelOption
|
||||
@@ -38,4 +42,3 @@ OPTIONS
|
||||
[Optional]
|
||||
|
||||
----
|
||||
====
|
||||
|
||||
@@ -16,22 +16,18 @@ on default.
|
||||
|
||||
You can define one with an option in `CommandRegistration`.
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/OptionSnippets.java[tag=option-registration-naming-case-req]
|
||||
----
|
||||
====
|
||||
|
||||
Add one _singleton bean_ as type `OptionNameModifier` and that becomes
|
||||
a global default.
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/OptionSnippets.java[tag=option-registration-naming-case-bean]
|
||||
----
|
||||
====
|
||||
|
||||
It's also possible to just add configuration property with
|
||||
`spring.shell.option.naming.case-type` which auto-configures
|
||||
@@ -46,7 +42,6 @@ default via configuration properies only work if using
|
||||
pre-configured `Builder` instance. See more
|
||||
<<using-shell-commands-programmaticmodel>>.
|
||||
|
||||
====
|
||||
[source, yaml]
|
||||
----
|
||||
spring:
|
||||
@@ -59,21 +54,17 @@ spring:
|
||||
# case-type: kebab
|
||||
# case-type: pascal
|
||||
----
|
||||
====
|
||||
|
||||
For example options defined in an annotated method like this.
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/OptionSnippets.java[tag=option-registration-naming-case-sample1]
|
||||
----
|
||||
====
|
||||
|
||||
On default `help` for that command shows names coming
|
||||
directly from `@ShellOption`.
|
||||
|
||||
====
|
||||
[source, bash]
|
||||
----
|
||||
OPTIONS
|
||||
@@ -89,12 +80,10 @@ OPTIONS
|
||||
--FromPascal String
|
||||
[Mandatory]
|
||||
----
|
||||
====
|
||||
|
||||
Define `spring.shell.option.naming.case-type=kebab` and default
|
||||
modifier is added and option names then look like.
|
||||
|
||||
====
|
||||
[source, bash]
|
||||
----
|
||||
OPTIONS
|
||||
@@ -111,4 +100,3 @@ OPTIONS
|
||||
[Mandatory]
|
||||
|
||||
----
|
||||
====
|
||||
|
||||
@@ -8,40 +8,52 @@ a command target.
|
||||
|
||||
Making option optional.
|
||||
|
||||
[tabs]
|
||||
======
|
||||
Programmatic::
|
||||
+
|
||||
[source,java,indent=0,role="primary"]
|
||||
.Programmatic
|
||||
----
|
||||
include::{snippets}/OptionSnippets.java[tag=option-optional-programmatic]
|
||||
----
|
||||
|
||||
Annotation::
|
||||
+
|
||||
[source,java,indent=0,role="secondary"]
|
||||
.Annotation
|
||||
----
|
||||
include::{snippets}/OptionSnippets.java[tag=option-optional-annotation]
|
||||
----
|
||||
|
||||
Legacy Annotation::
|
||||
+
|
||||
[source,java,indent=0,role="secondary"]
|
||||
.Legacy Annotation
|
||||
----
|
||||
include::{snippets}/OptionSnippets.java[tag=option-optional-legacyannotation]
|
||||
----
|
||||
======
|
||||
|
||||
Making option mandatory.
|
||||
|
||||
[tabs]
|
||||
======
|
||||
Programmatic::
|
||||
+
|
||||
[source,java,indent=0,role="primary"]
|
||||
.Programmatic
|
||||
----
|
||||
include::{snippets}/OptionSnippets.java[tag=option-mandatory-programmatic]
|
||||
----
|
||||
|
||||
Annotation::
|
||||
+
|
||||
[source,java,indent=0,role="secondary"]
|
||||
.Annotation
|
||||
----
|
||||
include::{snippets}/OptionSnippets.java[tag=option-mandatory-annotation]
|
||||
----
|
||||
|
||||
Legacy Annotation::
|
||||
+
|
||||
[source,java,indent=0,role="secondary"]
|
||||
.Legacy Annotation
|
||||
----
|
||||
include::{snippets}/OptionSnippets.java[tag=option-mandatory-legacyannotation]
|
||||
----
|
||||
======
|
||||
|
||||
@@ -5,12 +5,10 @@ ifndef::snippets[:snippets: ../../test/java/org/springframework/shell/docs]
|
||||
|
||||
Positional information is mostly related to a command target method:
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/OptionSnippets.java[tag=option-registration-positional]
|
||||
----
|
||||
====
|
||||
|
||||
NOTE: Be careful with positional parameters as it may soon
|
||||
become confusing which options those are mapped to.
|
||||
@@ -27,36 +25,29 @@ ambiguous arguments.
|
||||
|
||||
Let's look what happens when we don't define a position.
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/OptionSnippets.java[tag=option-registration-aritystrings-noposition]
|
||||
----
|
||||
====
|
||||
|
||||
Option _arg1_ is required and there is no info what to do with argument
|
||||
`one` resulting error for missing option.
|
||||
|
||||
====
|
||||
[source, bash]
|
||||
----
|
||||
shell:>arity-strings-1 one
|
||||
Missing mandatory option --arg1.
|
||||
----
|
||||
====
|
||||
|
||||
Now let's define a position `0`.
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/OptionSnippets.java[tag=option-registration-aritystrings-position]
|
||||
----
|
||||
====
|
||||
|
||||
Arguments are processed until we get up to 2 arguments.
|
||||
|
||||
====
|
||||
[source, bash]
|
||||
----
|
||||
shell:>arity-strings-2 one
|
||||
@@ -68,4 +59,3 @@ Hello [one, two]
|
||||
shell:>arity-strings-2 one two three
|
||||
Hello [one, two]
|
||||
----
|
||||
====
|
||||
|
||||
@@ -6,42 +6,54 @@ ifndef::snippets[:snippets: ../../test/java/org/springframework/shell/docs]
|
||||
Short style _POSIX_ option is usually just a synonym to long format. As
|
||||
shown below option `--arg` is equal to `-a`.
|
||||
|
||||
[tabs]
|
||||
======
|
||||
Programmatic::
|
||||
+
|
||||
[source,java,indent=0,role="primary"]
|
||||
.Programmatic
|
||||
----
|
||||
include::{snippets}/ShortOptionSnippets.java[tag=option-type-string-programmatic]
|
||||
----
|
||||
|
||||
Annotation::
|
||||
+
|
||||
[source,java,indent=0,role="secondary"]
|
||||
.Annotation
|
||||
----
|
||||
include::{snippets}/ShortOptionSnippets.java[tag=option-type-string-annotation]
|
||||
----
|
||||
|
||||
Legacy Annotation::
|
||||
+
|
||||
[source,java,indent=0,role="secondary"]
|
||||
.Legacy Annotation
|
||||
----
|
||||
include::{snippets}/ShortOptionSnippets.java[tag=option-type-string-legacyannotation]
|
||||
----
|
||||
======
|
||||
|
||||
Short option with combined format is powerful if type is defined as a flag
|
||||
which means type is a _boolean_. That way you can define a presence of a flags
|
||||
as `-abc`, `-abc true` or `-abc false`.
|
||||
|
||||
[tabs]
|
||||
======
|
||||
Programmatic::
|
||||
+
|
||||
[source,java,indent=0,role="primary"]
|
||||
.Programmatic
|
||||
----
|
||||
include::{snippets}/ShortOptionSnippets.java[tag=option-type-multiple-booleans-programmatic]
|
||||
----
|
||||
|
||||
Annotation::
|
||||
+
|
||||
[source,java,indent=0,role="secondary"]
|
||||
.Annotation
|
||||
----
|
||||
include::{snippets}/ShortOptionSnippets.java[tag=option-type-multiple-booleans-annotation]
|
||||
----
|
||||
|
||||
Legacy Annotation::
|
||||
+
|
||||
[source,java,indent=0,role="secondary"]
|
||||
.Legacy Annotation
|
||||
----
|
||||
include::{snippets}/ShortOptionSnippets.java[tag=option-type-multiple-booleans-legacyannotation]
|
||||
----
|
||||
======
|
||||
|
||||
@@ -11,22 +11,18 @@ This section talks about how particular data type is used as an option value.
|
||||
`String` is a most simplest type as there's no conversion involved as what's
|
||||
coming in from a user is always a string.
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/OptionTypesSnippets.java[tag=option-type-string-anno]
|
||||
----
|
||||
====
|
||||
|
||||
While it's not strictly required to define type as a `String` it's always
|
||||
adviced to do so.
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/OptionTypesSnippets.java[tag=option-type-string-reg]
|
||||
----
|
||||
====
|
||||
|
||||
[[boolean]]
|
||||
== Boolean
|
||||
@@ -35,14 +31,11 @@ Using boolean types is a bit more involved as there are `boolean` and
|
||||
`Boolean` where latter can be _null_. Boolean types are usually used as
|
||||
flags meaning argument value may not be needed.
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/OptionTypesSnippets.java[tag=option-type-boolean-anno]
|
||||
----
|
||||
====
|
||||
|
||||
====
|
||||
[source, bash]
|
||||
----
|
||||
shell:>example
|
||||
@@ -54,16 +47,12 @@ arg1=false arg2=true arg3=false arg4=true arg5=true arg6=false
|
||||
shell:>example --arg4 false
|
||||
arg1=false arg2=true arg3=false arg4=false arg5=true arg6=false
|
||||
----
|
||||
====
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/OptionTypesSnippets.java[tag=option-type-boolean-reg]
|
||||
----
|
||||
====
|
||||
|
||||
====
|
||||
[source, bash]
|
||||
----
|
||||
shell:>example
|
||||
@@ -75,26 +64,21 @@ arg1=false arg2=true arg3=false arg4=true arg5=true arg6=false
|
||||
shell:>example --arg4 false
|
||||
arg1=false arg2=true arg3=false arg4=false arg5=true arg6=false
|
||||
----
|
||||
====
|
||||
|
||||
[[number]]
|
||||
== Number
|
||||
|
||||
Numbers are converted as is.
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/OptionTypesSnippets.java[tag=option-type-integer-anno]
|
||||
----
|
||||
====
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/OptionTypesSnippets.java[tag=option-type-integer-reg]
|
||||
----
|
||||
====
|
||||
|
||||
[[enum]]
|
||||
== Enum
|
||||
@@ -102,42 +86,32 @@ include::{snippets}/OptionTypesSnippets.java[tag=option-type-integer-reg]
|
||||
Conversion to enums is possible if given value is exactly matching enum itself.
|
||||
Currently you can convert assuming case insensitivity.
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/OptionTypesSnippets.java[tag=option-type-enum-class]
|
||||
----
|
||||
====
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/OptionTypesSnippets.java[tag=option-type-enum-anno]
|
||||
----
|
||||
====
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/OptionTypesSnippets.java[tag=option-type-enum-reg]
|
||||
----
|
||||
====
|
||||
|
||||
[[array]]
|
||||
== Array
|
||||
|
||||
Arrays can be used as is with strings and primitive types.
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/OptionTypesSnippets.java[tag=option-type-string-array-anno]
|
||||
----
|
||||
====
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/OptionTypesSnippets.java[tag=option-type-string-array-reg]
|
||||
----
|
||||
====
|
||||
|
||||
@@ -7,7 +7,6 @@ automatic and self-documenting constraints on command parameters.
|
||||
Annotations found on command parameters and annotations at the method level are
|
||||
honored and trigger validation prior to the command executing. Consider the following command:
|
||||
|
||||
====
|
||||
[source, java]
|
||||
----
|
||||
@ShellMethod("Change password.")
|
||||
@@ -15,14 +14,11 @@ honored and trigger validation prior to the command executing. Consider the foll
|
||||
return "Password successfully set to " + password;
|
||||
}
|
||||
----
|
||||
====
|
||||
|
||||
From the preceding example, you get the following behavior for free:
|
||||
|
||||
====
|
||||
----
|
||||
shell:>change-password hello
|
||||
The following constraints were not met:
|
||||
--password string : size must be between 8 and 40 (You passed 'hello')
|
||||
----
|
||||
====
|
||||
|
||||
@@ -9,18 +9,14 @@ Test support is provided by two modules: `spring-shell-test` contains core items
|
||||
|
||||
To test _interactive_ commands.
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/TestingSnippets.java[tag=testing-shelltest-interactive]
|
||||
----
|
||||
====
|
||||
|
||||
To test _non-interactive_ commands.
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/TestingSnippets.java[tag=testing-shelltest-noninteractive]
|
||||
----
|
||||
====
|
||||
|
||||
@@ -10,19 +10,15 @@ lines and you don't want to handle those cases in a tests.
|
||||
These can be changed using properties `spring.shell.test.terminal-width`
|
||||
or `spring.shell.test.terminal-height`.
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/TestingSnippets.java[tag=testing-shelltest-dimensions-props]
|
||||
----
|
||||
====
|
||||
|
||||
`ShellTest` annotation have fields `terminalWidth` and `terminalHeight`
|
||||
which can also be used to change dimensions.
|
||||
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/TestingSnippets.java[tag=testing-shelltest-dimensions-field]
|
||||
----
|
||||
====
|
||||
|
||||
@@ -5,12 +5,10 @@
|
||||
ifndef::snippets[:snippets: ../../test/java/org/springframework/shell/docs]
|
||||
|
||||
Lets start with a simple app which prints "hello world" in a view.
|
||||
====
|
||||
[source, java, indent=0]
|
||||
----
|
||||
include::{snippets}/TerminalUiSnippets.java[tag=snippet1]
|
||||
----
|
||||
====
|
||||
|
||||
There is not much to see here other than `TerminalUI` is a class handling
|
||||
all logic aroung views and uses `View` as it's root view.
|
||||
|
||||
Reference in New Issue
Block a user