[#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]
----
