100 lines
3.3 KiB
Plaintext
100 lines
3.3 KiB
Plaintext
[#appendix-tech-intro-registration]
|
|
= Command Registration
|
|
|
|
ifndef::snippets[:snippets: ../../../../../src/test/java/org/springframework/shell/docs]
|
|
|
|
Defining a command registration is a first step to introducing the structure of a command and its options
|
|
and parameters. This is loosely decoupled from what happens later, such as parsing command-line input and running
|
|
actual target code. Essentially, it is the definition of a command API that is shown to a user.
|
|
|
|
[[commands]]
|
|
== Commands
|
|
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
|
|
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.
|
|
|
|
[[interaction-mode]]
|
|
== Interaction Mode
|
|
Spring Shell has been designed to work on two modes: interactive (which essentially
|
|
is a `REPL` where you have an active shell instance throughout a series of commands) and
|
|
non-interactive (where commands are executed one by one from a command line).
|
|
|
|
Differentation between these modes is mostly around limitations about what can be done
|
|
in each mode. For example, it would not be feasible to show what was a previous stacktrace
|
|
of a command if the shell is no longer active. Generally, whether the shell is still active
|
|
dictates the available information.
|
|
|
|
Also, being on an active `REPL` session may provide more information about what the user has been
|
|
doing within an active session.
|
|
|
|
[[options]]
|
|
== Options
|
|
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
|
|
The target defines the execution target of a command. It can be a method in a POJO,
|
|
a `Consumer`, or a `Function`.
|
|
|
|
[[method]]
|
|
=== Method
|
|
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
|
|
Using a `Function` as a target gives a lot of flexibility to handle what
|
|
happens in a command execution, because you can handle many things manually by using
|
|
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
|
|
Using a `Consumer` is basically the same as using a `Function`, with the difference being
|
|
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]
|
|
----
|