Migrate docs to antora
- This is basically copy from main branch minus all terminal ui things. - Relates #971
This commit is contained in:
137
spring-shell-docs/modules/ROOT/pages/commands/availability.adoc
Normal file
137
spring-shell-docs/modules/ROOT/pages/commands/availability.adoc
Normal file
@@ -0,0 +1,137 @@
|
||||
[[dynamic-command-availability]]
|
||||
= Dynamic Command Availability
|
||||
|
||||
Registered commands do not always make sense, due to the internal state of the application.
|
||||
For example, there may be a `download` command, but it only works once the user has used `connect` on a remote
|
||||
server. Now, if the user tries to use the `download` command, the shell should explain that
|
||||
the command exists but that it is not available at the time.
|
||||
Spring Shell lets you do that, even letting you provide a short explanation of the reason for
|
||||
the command not being available.
|
||||
|
||||
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
|
||||
public class MyCommands {
|
||||
|
||||
private boolean connected;
|
||||
|
||||
@ShellMethod("Connect to the server.")
|
||||
public void connect(String user, String password) {
|
||||
[...]
|
||||
connected = true;
|
||||
}
|
||||
|
||||
@ShellMethod("Download the nuclear codes.")
|
||||
public void download() {
|
||||
[...]
|
||||
}
|
||||
|
||||
public Availability downloadAvailability() {
|
||||
return connected
|
||||
? Availability.available()
|
||||
: Availability.unavailable("you are not connected");
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
The `connect` method is used to connect to the server (details omitted), altering the state
|
||||
of the command through the `connected` boolean when done.
|
||||
The `download` command as marked as unavailable until the user has connected, thanks to the presence
|
||||
of a method named exactly as the `download` command method with the `Availability` suffix in its name.
|
||||
The method returns an instance of `Availability`, constructed with one of the two factory methods.
|
||||
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:commands/builtin/help.adoc[Help].
|
||||
|
||||
[TIP]
|
||||
====
|
||||
The reason provided when the command is not available should read nicely if appended after "`Because`".
|
||||
|
||||
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.")
|
||||
@ShellMethodAvailability("availabilityCheck") // <1>
|
||||
public void download() {
|
||||
[...]
|
||||
}
|
||||
|
||||
public Availability availabilityCheck() { // <1>
|
||||
return connected
|
||||
? Availability.available()
|
||||
: Availability.unavailable("you are not connected");
|
||||
}
|
||||
----
|
||||
<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.")
|
||||
public void download() {
|
||||
[...]
|
||||
}
|
||||
|
||||
@ShellMethod("Disconnect from the server.")
|
||||
public void disconnect() {
|
||||
[...]
|
||||
}
|
||||
|
||||
@ShellMethodAvailability({"download", "disconnect"})
|
||||
public Availability availabilityCheck() {
|
||||
return connected
|
||||
? Availability.available()
|
||||
: Availability.unavailable("you are not connected");
|
||||
}
|
||||
----
|
||||
|
||||
[TIP]
|
||||
=====
|
||||
The default value for the `@ShellMethodAvailability.value()` attribute is `*`. This special
|
||||
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
|
||||
public class Toggles {
|
||||
@ShellMethodAvailability
|
||||
public Availability availabilityOnWeekdays() {
|
||||
return Calendar.getInstance().get(DAY_OF_WEEK) == SUNDAY
|
||||
? Availability.available()
|
||||
: Availability.unavailable("today is not Sunday");
|
||||
}
|
||||
|
||||
@ShellMethod
|
||||
public void foo() {}
|
||||
|
||||
@ShellMethod
|
||||
public void bar() {}
|
||||
}
|
||||
----
|
||||
=====
|
||||
|
||||
TIP: Spring Shell does not impose many constraints on how to write commands and how to organize classes.
|
||||
However, it is often good practice to put related commands in the same class, and the availability indicators
|
||||
can benefit from that.
|
||||
@@ -0,0 +1,6 @@
|
||||
[[built-in-commands-clear]]
|
||||
= Clear
|
||||
:page-section-summary-toc: 1
|
||||
|
||||
The `clear` command does what you would expect and clears the screen, resetting the prompt
|
||||
in the top left corner.
|
||||
@@ -0,0 +1,9 @@
|
||||
[[built-in-commands-completion]]
|
||||
= Completion
|
||||
:page-section-summary-toc: 1
|
||||
|
||||
The `completion` command set lets you create script files that can be used
|
||||
with am OS shell implementations to provide completion. This is very useful when
|
||||
working with non-interactive mode.
|
||||
|
||||
Currently, the only implementation is for bash, which works with `bash` sub-command.
|
||||
@@ -0,0 +1,7 @@
|
||||
[[built-in-commands-exit]]
|
||||
= Exit
|
||||
:page-section-summary-toc: 1
|
||||
|
||||
The `quit` command (also aliased as `exit`) requests the shell to quit, gracefully
|
||||
closing the Spring application context. If not overridden, a JLine `History` bean writes a history of all
|
||||
commands to disk, so that they are available again on the next launch.
|
||||
172
spring-shell-docs/modules/ROOT/pages/commands/builtin/help.adoc
Normal file
172
spring-shell-docs/modules/ROOT/pages/commands/builtin/help.adoc
Normal file
@@ -0,0 +1,172 @@
|
||||
[[built-in-commands-help]]
|
||||
= Help
|
||||
|
||||
Running a shell application often implies that the user is in a graphically limited
|
||||
environment. Also, while we are nearly always connected in the era of mobile phones,
|
||||
accessing a web browser or any other rich UI application (such as a PDF viewer) may not always
|
||||
be possible. This is why it is important that the shell commands are correctly self-documented, and this is where the `help`
|
||||
command comes in.
|
||||
|
||||
Typing `help` + `ENTER` lists all the commands known to the shell (including xref:commands/availability.adoc[unavailable] commands)
|
||||
and a short description of what they do, similar to the following:
|
||||
|
||||
[source, bash]
|
||||
----
|
||||
my-shell:>help
|
||||
AVAILABLE COMMANDS
|
||||
|
||||
Built-In Commands
|
||||
exit: Exit the shell.
|
||||
help: Display help about available commands
|
||||
stacktrace: Display the full stacktrace of the last error.
|
||||
clear: Clear the shell screen.
|
||||
quit: Exit the shell.
|
||||
history: Display or save the history of previously run commands
|
||||
completion bash: Generate bash completion script
|
||||
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
|
||||
NAME
|
||||
help - Display help about available commands
|
||||
|
||||
SYNOPSIS
|
||||
help --command String
|
||||
|
||||
OPTIONS
|
||||
--command or -C String
|
||||
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
|
||||
a structure, `command-template` to define your template for output of a command help, `commands-template` to define
|
||||
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
|
||||
AVAILABLE COMMANDS
|
||||
|
||||
exit: Exit the shell.
|
||||
help: Display help about available commands
|
||||
stacktrace: Display the full stacktrace of the last error.
|
||||
clear: Clear the shell screen.
|
||||
quit: Exit the shell.
|
||||
history: Display or save the history of previously run commands
|
||||
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.
|
||||
|
||||
Option `spring.shell.command.help.commands-template` defaults to
|
||||
`classpath:template/help-commands-default.stg` and is passed `GroupsInfoModel`
|
||||
as a model.
|
||||
|
||||
Option `spring.shell.command.help.command-template` defaults to
|
||||
`classpath:template/help-command-default.stg` and is passed `CommandInfoModel`
|
||||
as a model.
|
||||
|
||||
[[groupsinfomodel-variables]]
|
||||
.GroupsInfoModel Variables
|
||||
|===
|
||||
|Key |Description
|
||||
|
||||
|`showGroups`
|
||||
|`true` if showing groups is enabled. Otherwise, false.
|
||||
|
||||
|`groups`
|
||||
|The commands variables (see xref:commands/builtin/help.adoc#groupcommandinfomodel-variables[GroupCommandInfoModel Variables]).
|
||||
|
||||
|`commands`
|
||||
|The commands variables (see xref:commands/builtin/help.adoc#commandinfomodel-variables[CommandInfoModel Variables]).
|
||||
|
||||
|`hasUnavailableCommands`
|
||||
|`true` if there is unavailable commands. Otherwise, false.
|
||||
|===
|
||||
|
||||
[[groupcommandinfomodel-variables]]
|
||||
.GroupCommandInfoModel Variables
|
||||
|===
|
||||
|Key |Description
|
||||
|
||||
|`group`
|
||||
|The name of a group, if set. Otherwise, empty.
|
||||
|
||||
|`commands`
|
||||
|The commands, if set. Otherwise, empty. Type is a multi value, see xref:commands/builtin/help.adoc#commandinfomodel-variables[CommandInfoModel Variables].
|
||||
|===
|
||||
|
||||
[[commandinfomodel-variables]]
|
||||
.CommandInfoModel Variables
|
||||
|===
|
||||
|Key |Description
|
||||
|
||||
|`name`
|
||||
|The name of a command, if set. Otherwise, null. Type is string and contains full command.
|
||||
|
||||
|`names`
|
||||
|The names of a command, if set. Otherwise, null. Type is multi value essentially `name` splitted.
|
||||
|
||||
|`aliases`
|
||||
|The possible aliases, if set. Type is multi value with strings.
|
||||
|
||||
|`description`
|
||||
|The description of a command, if set. Otherwise, null.
|
||||
|
||||
|`parameters`
|
||||
|The parameters variables, if set. Otherwise empty. Type is a multi value, see xref:commands/builtin/help.adoc#commandparameterinfomodel-variables[CommandParameterInfoModel Variables].
|
||||
|
||||
|`availability`
|
||||
|The availability variables (see xref:commands/builtin/help.adoc#commandavailabilityinfomodel-variables[CommandAvailabilityInfoModel Variables]).
|
||||
|===
|
||||
|
||||
[[commandparameterinfomodel-variables]]
|
||||
.CommandParameterInfoModel Variables
|
||||
|===
|
||||
|Key |Description
|
||||
|
||||
|`type`
|
||||
|The type of a parameter if set. Otherwise, null.
|
||||
|
||||
|`arguments`
|
||||
|The arguments, if set. Otherwise, null. Type is multi value with strings.
|
||||
|
||||
|`required`
|
||||
|`true` if required. Otherwise, false.
|
||||
|
||||
|`description`
|
||||
|The description of a parameter, if set. Otherwise, null.
|
||||
|
||||
|`defaultValue`
|
||||
|The default value of a parameter, if set. Otherwise, null.
|
||||
|
||||
|`hasDefaultValue`
|
||||
|`true` if defaultValue exists. Otherwise, false.
|
||||
|===
|
||||
|
||||
[[commandavailabilityinfomodel-variables]]
|
||||
.CommandAvailabilityInfoModel Variables
|
||||
|===
|
||||
|Key |Description
|
||||
|
||||
|`available`
|
||||
|`true` if available. Otherwise, false.
|
||||
|
||||
|`reason`
|
||||
|The reason if not available if set. Otherwise, null.
|
||||
|===
|
||||
@@ -0,0 +1,17 @@
|
||||
[[built-in-commands-history]]
|
||||
= History
|
||||
:page-section-summary-toc: 1
|
||||
|
||||
The `history` command shows the history of commands that has been executed.
|
||||
|
||||
There are a few configuration options that you can use to configure behavior
|
||||
of a history. History is kept in a log file, which is enabled by default and can
|
||||
be turned off by setting `spring.shell.history.enabled`. The name of a log file
|
||||
is resolved from `spring.application.name` and defaults to `spring-shell.log`,
|
||||
which you can change by setting `spring.shell.history.name`.
|
||||
|
||||
By default, a log file is generated to a current working directory, which you can dictate
|
||||
by setting `spring.shell.config.location`. This property can contain
|
||||
a placeholder (`+{userconfig}+`), which resolves to a common shared config directory.
|
||||
|
||||
TIP: Run the Spring Shell application to see how the sample application works as it uses these options.
|
||||
@@ -0,0 +1,11 @@
|
||||
[[built-in-commands]]
|
||||
= Built-In Commands
|
||||
:page-section-summary-toc: 1
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
[[built-in-commands-script]]
|
||||
= Script
|
||||
:page-section-summary-toc: 1
|
||||
|
||||
The `script` command accepts a local file as an argument and replays commands found there, one at a time.
|
||||
|
||||
Reading from the file behaves exactly like inside the interactive shell, so lines starting with `//` are considered
|
||||
to be comments and are ignored, while lines ending with `\` trigger line continuation.
|
||||
@@ -0,0 +1,10 @@
|
||||
[[built-in-commands-stacktrace]]
|
||||
= Stacktrace
|
||||
:page-section-summary-toc: 1
|
||||
|
||||
When an exception occurs inside command code, it is caught by the shell and a simple, one-line message is displayed
|
||||
so as not to overflow the user with too much information.
|
||||
There are cases, though, when understanding what exactly happened is important (especially if the exception has a nested cause).
|
||||
|
||||
To this end, Spring Shell remembers the last exception that occurred, and the user can later use the `stacktrace`
|
||||
command to print all the details on the console.
|
||||
@@ -0,0 +1,33 @@
|
||||
[[built-in-commands-version]]
|
||||
= Version
|
||||
|
||||
The `version` command shows existing build and git info by integrating into
|
||||
Boot's `BuildProperties` and `GitProperties` if those exist in the shell application.
|
||||
By default, only version information is shown, and you can enable other information through configuration
|
||||
options.
|
||||
|
||||
The relevant settings are under `spring.shell.command.version`, where you can use `enabled` to
|
||||
disable a command and, optionally, define your own template with `template`. You can use the
|
||||
`show-build-artifact`, `show-build-group`, `show-build-name`, `show-build-time`,
|
||||
`show-build-version`, `show-git-branch`, `show-git-commit-id`,
|
||||
`show-git-short-commit-id` and `show-git-commit-time` commands to control
|
||||
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`,
|
||||
`gitBranch`, and `gitCommitTime`.
|
||||
@@ -0,0 +1,82 @@
|
||||
[[dynamic-command-exitcode-annotation]]
|
||||
= @ExceptionResolver
|
||||
|
||||
ifndef::snippets[:snippets: ../../test/java/org/springframework/shell/docs]
|
||||
|
||||
`@ShellComponent` classes can have `@ExceptionResolver` methods to handle exceptions from component
|
||||
methods. These are meant for annotated methods.
|
||||
|
||||
The exception may match against a top-level exception being propagated (e.g. a direct IOException
|
||||
being thrown) or against a nested cause within a wrapper exception (e.g. an IOException wrapped
|
||||
inside an IllegalStateException). This can match at arbitrary cause levels.
|
||||
|
||||
For matching exception types, preferably declare the target exception as a method argument, as
|
||||
the preceding example(s) shows. When multiple exception methods match, a root exception match is
|
||||
generally preferred to a cause exception match. More specifically, the ExceptionDepthComparator
|
||||
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
|
||||
`@ExceptionResolver` methods support the following arguments:
|
||||
|
||||
[Attributes]
|
||||
|===
|
||||
|Method argument |Description
|
||||
|
||||
|Exception type
|
||||
|For access to the raised exception. This is any type of `Exception` or `Throwable`.
|
||||
|
||||
|Terminal
|
||||
|For access to underlying `JLine` terminal to i.e. get its terminal writer.
|
||||
|
||||
|===
|
||||
|
||||
[[return-values]]
|
||||
== Return Values
|
||||
`@ExceptionResolver` methods support the following return values:
|
||||
|
||||
[Attributes]
|
||||
|===
|
||||
|Return value |Description
|
||||
|
||||
|String
|
||||
|Plain text to return to a shell. Exit code 1 is used in this case.
|
||||
|
||||
|CommandHandlingResult
|
||||
|Plain `CommandHandlingResult` having message and exit code.
|
||||
|
||||
|void
|
||||
|A method with a void return type is considered to have fully handled the exception. Usually
|
||||
you would define `Terminal` as a method argument and write response using _terminal writer_
|
||||
from it. As exception is fully handled, Exit code 0 is used in this case.
|
||||
|===
|
||||
@@ -0,0 +1,18 @@
|
||||
[[dynamic-command-exitcode]]
|
||||
= Exception Handling
|
||||
:page-section-summary-toc: 1
|
||||
|
||||
ifndef::snippets[:snippets: ../../test/java/org/springframework/shell/docs]
|
||||
|
||||
Exceptions happen from a user code wether it is intentional or not. This section describes
|
||||
how `spring-shell` handles exceptions and gives instructions and best practices how to
|
||||
work with it.
|
||||
|
||||
Many command line applications when applicable return an _exit code_ which running environment
|
||||
can use to differentiate if command has been executed successfully or not. In a `spring-shell`
|
||||
this mostly relates when a command is run on a non-interactive mode meaning one command
|
||||
is always executed once with an instance of a `spring-shell`. Take a note that _exit code_
|
||||
always relates to non-interactive shell.
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
[[dynamic-command-exitcode-mappings]]
|
||||
= Exit Code Mappings
|
||||
|
||||
ifndef::snippets[:snippets: ../../test/java/org/springframework/shell/docs]
|
||||
|
||||
Default behaviour of an exit codes is as:
|
||||
|
||||
- Errors from a command option parsing will result code of `2`
|
||||
- Any generic error will result result code of `1`
|
||||
- Obviously in any other case result code is `0`
|
||||
|
||||
Every `CommandRegistration` can define its own mappings between _Exception_ and _exit code_.
|
||||
Essentially we're bound to functionality in `Spring Boot` regarding _exit code_ and simply
|
||||
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
|
||||
@@ -0,0 +1,48 @@
|
||||
[[dynamic-command-exitcode-resolving]]
|
||||
= Exception Resolving
|
||||
|
||||
ifndef::snippets[:snippets: ../../test/java/org/springframework/shell/docs]
|
||||
|
||||
Unhandled exceptions will bubble up into shell's `ResultHandlerService` and then eventually
|
||||
handled by some instance of `ResultHandler`. Chain of `ExceptionResolver` implementations
|
||||
can be used to resolve exceptions and gives you flexibility to return message to get written
|
||||
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.
|
||||
|
||||
|
||||
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_
|
||||
presedence defined in `CommandExceptionResolver.DEFAULT_PRECEDENCE`.
|
||||
As these beans are used in a given order, `@Order` annotation or `Ordered`
|
||||
interface from can be used just like in any other spring app. This
|
||||
is generally useful if you need to control your own beans to get used
|
||||
either before or after a defaults.
|
||||
@@ -0,0 +1,38 @@
|
||||
[[commands-helpoptions]]
|
||||
= Help Options
|
||||
|
||||
ifndef::snippets[:snippets: ../../test/java/org/springframework/shell/docs]
|
||||
|
||||
_Spring Shell_ has a build-in `help` command but not all favour getting command help
|
||||
from it as you always need to call it with arguments for target command. It's
|
||||
common in many cli frameworks for every command having options _--help_ and _-h_
|
||||
to print out command help.
|
||||
|
||||
Default functionality is that every command will get modified to have options
|
||||
_--help_ and _-h_, which if present in a given command will automatically
|
||||
short circuit command execution into a existing `help` command regardless
|
||||
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:
|
||||
shell:
|
||||
help:
|
||||
enabled: true
|
||||
long-names: help
|
||||
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
|
||||
model gives option to modify settings per command.
|
||||
26
spring-shell-docs/modules/ROOT/pages/commands/hidden.adoc
Normal file
26
spring-shell-docs/modules/ROOT/pages/commands/hidden.adoc
Normal file
@@ -0,0 +1,26 @@
|
||||
[[commands-hidden]]
|
||||
= Hidden Command
|
||||
|
||||
ifndef::snippets[:snippets: ../../test/java/org/springframework/shell/docs]
|
||||
|
||||
It is possible to _hide_ a command which is convenient in cases where it is not yet ready for
|
||||
prime time, is meant for debugging purposes or you have any other reason you dont want to
|
||||
advertise its presense.
|
||||
|
||||
Hidden command can be executed if you know it and its options. It is effectively removed
|
||||
from:
|
||||
|
||||
* Help listing
|
||||
* Help page for command return "unknown command"
|
||||
* Command completion in interactive mode
|
||||
* Bash completion
|
||||
|
||||
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
|
||||
18
spring-shell-docs/modules/ROOT/pages/commands/index.adoc
Normal file
18
spring-shell-docs/modules/ROOT/pages/commands/index.adoc
Normal file
@@ -0,0 +1,18 @@
|
||||
[[commands]]
|
||||
= Commands
|
||||
:page-section-summary-toc: 1
|
||||
|
||||
ifndef::snippets[:snippets: ../../test/java/org/springframework/shell/docs]
|
||||
|
||||
In this section, we go through an actual command registration and leave command options
|
||||
and execution for later in a documentation. You can find more detailed info in
|
||||
xref:appendices/techintro/registration.adoc[Command Registration].
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
[[commands-interactionmode]]
|
||||
= Interaction Mode
|
||||
:page-section-summary-toc: 1
|
||||
|
||||
ifndef::snippets[:snippets: ../../../../src/test/java/org/springframework/shell/docs]
|
||||
|
||||
Command registration can define `InteractionMode` which is used to hide commands
|
||||
depending which mode shell is executing. More about that in xref:execution.adoc#using-shell-execution-interactionmode[Interaction Mode].
|
||||
|
||||
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]
|
||||
----
|
||||
52
spring-shell-docs/modules/ROOT/pages/commands/organize.adoc
Normal file
52
spring-shell-docs/modules/ROOT/pages/commands/organize.adoc
Normal file
@@ -0,0 +1,52 @@
|
||||
[[organizing-commands]]
|
||||
= Organizing Commands
|
||||
|
||||
When your shell starts to provide a lot of functionality, you may end up
|
||||
with a lot of commands, which could be confusing for your users. By typing `help`,
|
||||
they would see a daunting list of commands, organized in alphabetical order,
|
||||
which may not always be the best way to show the available commands.
|
||||
|
||||
To alleviate this possible confusion, Spring Shell provides the ability to group commands together,
|
||||
with reasonable defaults. Related commands would then end up in the same group (for example, `User Management Commands`)
|
||||
and be displayed together in the help screen and other places.
|
||||
|
||||
By default, commands are grouped according to the class they are implemented in,
|
||||
turning the camelCase class name into separate words (so `URLRelatedCommands` becomes `URL Related Commands`).
|
||||
This is a sensible default, as related commands are often already in the class anyway,
|
||||
because they need to use the same collaborating objects.
|
||||
|
||||
If, however, this behavior does not suit you, you can override the group for a
|
||||
command in the following ways, in order of priority:
|
||||
|
||||
. Specify a `group()` in the `@ShellMethod` annotation.
|
||||
. Place a `@ShellCommandGroup` on the class in which the command is defined. This applies
|
||||
the group for all commands defined in that class (unless overridden, as explained earlier).
|
||||
. Place a `@ShellCommandGroup` on the package (through `package-info.java`)
|
||||
in which the command is defined. This applies to all the commands defined in the
|
||||
package (unless overridden at the method or class level, as explained earlier).
|
||||
|
||||
The following listing shows an example:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
public class UserCommands {
|
||||
@ShellMethod(value = "This command ends up in the 'User Commands' group")
|
||||
public void foo() {}
|
||||
|
||||
@ShellMethod(value = "This command ends up in the 'Other Commands' group",
|
||||
group = "Other Commands")
|
||||
public void bar() {}
|
||||
}
|
||||
|
||||
...
|
||||
|
||||
@ShellCommandGroup("Other Commands")
|
||||
public class SomeCommands {
|
||||
@ShellMethod(value = "This one is in 'Other Commands'")
|
||||
public void wizz() {}
|
||||
|
||||
@ShellMethod(value = "And this one is 'Yet Another Group'",
|
||||
group = "Yet Another Group")
|
||||
public void last() {}
|
||||
}
|
||||
----
|
||||
@@ -0,0 +1,45 @@
|
||||
[[commands-registration-annotation]]
|
||||
= Annotation
|
||||
|
||||
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
|
||||
of Spring umbrella and provides better flexibility for a user being inclusive rather than exclusive
|
||||
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.
|
||||
|
||||
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]
|
||||
----
|
||||
@@ -0,0 +1,21 @@
|
||||
[[registration]]
|
||||
= Registration
|
||||
:page-section-summary-toc: 1
|
||||
|
||||
ifndef::snippets[:snippets: ../../test/java/org/springframework/shell/docs]
|
||||
|
||||
There are two different ways to define a command: through an annotation model and
|
||||
through a programmatic model. In the annotation model, you define your methods
|
||||
in a class and annotate the class and the methods with specific annotations.
|
||||
In the programmatic model, you use a more low level approach, defining command
|
||||
registrations (either as beans or by dynamically registering with a command catalog).
|
||||
|
||||
Starting from _3.1.x_ a better support for defining commands using
|
||||
xref:commands/registration/annotation.adoc[annotations] were added. Firstly because eventually standard
|
||||
package providing xref:commands/registration/legacyannotation.adoc[legacy annotations] will get deprecated
|
||||
and removed. Secondly so that we're able to provide same set of features than using underlying
|
||||
`CommandRegistration`. Creating new a annotation model allows us to rethink and modernise that
|
||||
part without breaking existing applications.
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
[[commands-registration-legacyannotation]]
|
||||
= Legacy Annotation
|
||||
|
||||
ifndef::snippets[:snippets: ../../test/java/org/springframework/shell/docs]
|
||||
|
||||
When you use the standard API, methods on beans are turned into executable commands, provided that:
|
||||
|
||||
* The bean class bears the `@ShellComponent` annotation. (This is used to restrict the set of beans
|
||||
that are considered.)
|
||||
* The method bears the `@ShellMethod` annotation.
|
||||
|
||||
[TIP]
|
||||
====
|
||||
The `@ShellComponent` is a stereotype annotation that is itself meta-annotated with `@Component`. As a result,
|
||||
you can use it in addition to the filtering mechanism to declare beans (for example, by using `@ComponentScan`).
|
||||
|
||||
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
|
||||
get consistent help about your commands without having to leave the shell (see xref:commands/builtin/help.adoc[Help]).
|
||||
|
||||
NOTE: The description of your command should be short -- no more than one or two sentences. For better
|
||||
consistency, it should start with a capital letter and end with a period.
|
||||
|
||||
By default, you need not specify the key for your command (that is, the word(s) that should be used
|
||||
to invoke it in the shell). The name of the method is used as the command key, turning camelCase names into
|
||||
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.
|
||||
|
||||
TIP: The command key can contain pretty much any character, including spaces. When coming up with names though,
|
||||
keep in mind that consistency is often appreciated by users. That is, you should avoid mixing dashed-names with
|
||||
spaced names and other inconsistencies.
|
||||
@@ -0,0 +1,36 @@
|
||||
[[commands-registration-programmatic]]
|
||||
= Programmatic
|
||||
|
||||
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
|
||||
be autowired. Default implementation of this supplier returns
|
||||
a new builder so you don't need to worry about its internal state.
|
||||
|
||||
IMPORTANT: Commands registered programmatically automatically
|
||||
add _help options_ mentioned in xref:commands/helpoptions.adoc[Help Options].
|
||||
|
||||
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]
|
||||
----
|
||||
25
spring-shell-docs/modules/ROOT/pages/commands/writing.adoc
Normal file
25
spring-shell-docs/modules/ROOT/pages/commands/writing.adoc
Normal file
@@ -0,0 +1,25 @@
|
||||
[[writing]]
|
||||
= Writing
|
||||
|
||||
ifndef::snippets[:snippets: ../../test/java/org/springframework/shell/docs]
|
||||
|
||||
When something needs to get written into your console you can always
|
||||
use JDK's `System.out` which then goes directly into JDK's own streams.
|
||||
Other recommended way is to use JLine's `Terminal` and get _writer_
|
||||
instance from there.
|
||||
|
||||
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]
|
||||
----
|
||||
Reference in New Issue
Block a user