--A framework that makes it easy to create REPL tools --Can be used when you don't need a rich UI like a web app and only an interactive CUI is enough. --JLine is used as the base (library also used by jshell)
OS Windows 10
Java 1.8.0_162
Hello World
build.gradle
buildscript {
ext {
springBootVersion = '2.0.0.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: 'java'
apply plugin: 'org.springframework.boot'
repositories {
mavenCentral()
}
dependencies {
compile('org.springframework.shell:spring-shell-starter:2.0.0.RELEASE')
}
bootJar {
baseName = 'sample'
}
SampleApplication.java
package sample.spring.shell;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SampleApplication {
public static void main(String[] args) {
SpringApplication.run(SampleApplication.class, args);
}
}
SampleCommands.java
package sample.spring.shell;
import org.springframework.shell.standard.ShellComponent;
import org.springframework.shell.standard.ShellMethod;
@ShellComponent
public class SampleCommands {
@ShellMethod("Hello World")
public void hello() {
System.out.println("Hello Spring Shell!!");
}
}
> gradle build
> java -jar build\libs\sample.jar
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v1.5.8.RELEASE)
(Omitted)
shell:>【hello】
Hello Spring Shell!!
shell:>【exit】
(Omitted)
>
[]
after starting Spring Shell (hello
, ʻexit`) indicates that the key is being entered.--About Spring Boot dependency --Spring Shell, latest as of March 2018 is 2.0.0 --I don't know about ver 1, but it seems that integration with Spring Boot is progressing from ver 2, and the official document also explains how to create using Spring Boot. ――It seems that Spring Boot is not essential, but I couldn't find a way to not use Spring Boot, so I will make a note of how to build using Spring Boot here as well. --Running the created jar launches an interactive shell --You can use your own commands or commands provided by Spring Shell by default. --You can exit the shell with ʻexit`
command | Description |
---|---|
clear |
Erase what is currently displayed in the shell |
exit , quit |
Exit the shell |
help |
Get help |
script |
Read and execute commands from a file |
stacktrace |
View the stack trace of the last error that occurred |
What it looks like when you run help
shell:>help
AVAILABLE COMMANDS
Built-In Commands
clear: Clear the shell screen.
exit, quit: Exit the shell.
help: Display help about available commands.
script: Read and execute commands from a file.
stacktrace: Display the full stacktrace of the last error.
Sample Commands
hello: Hello World
--You can use shortcuts similar to bash
Shortcut | Operation details |
---|---|
Ctrl + u |
Delete left from cursor |
Ctrl + k |
Remove right from cursor |
Ctrl + a |
Move the cursor to the beginning of the line |
Ctrl + e |
Move cursor to end of line |
Ctrl + w |
Delete up to the previous word |
Ctrl + d |
Delete the character at the cursor position |
Ctrl + f |
Advance the cursor by one |
Ctrl + b |
Move the cursor back one |
Alt + f |
Move the cursor one word |
Alt + b |
Move the cursor back one word |
package sample.spring.shell;
import org.springframework.shell.standard.ShellComponent;
import org.springframework.shell.standard.ShellMethod;
@ShellComponent
public class GreetingCommands {
@ShellMethod("Hello World")
public void hello(String text) {
System.out.println(text);
}
}
Execution result
shell:>【hello "foo bar"】
foo bar
shell:>【hello 'foo bar'】
foo bar
shell:>【hello "foo 'bar'"】
foo 'bar'
shell:>【hello 'foo "bar"'】
foo "bar"
shell:>【hello "foo \"bar\""】
foo "bar"
shell:>【hello 'foo \'bar\''】
foo 'bar'
--If you want to pass a string containing blank spaces as an argument, enclose the string in single quotes ('
) or double quotes ("
).
--Double quotes can be used as they are in single quotes, and single quotes can be used as they are in double quotes.
--If you want to use single quotes in single quotes and double quotes in double quotes, escape with a backslash (\
)
Escape blank spaces
shell:>【hello foo\ bar】
foo bar
--There is also a way to escape the blank space itself without quoting it.
Execution result
shell:>【hello "abc】
dquote> 【defg】
dquote> 【hijk"】
abc defg hijk
--If you insert a line break while quoting is started, you will continue to be prompted to enter characters. --Until you close the quotes, the input including the line break is treated as one input (the line break itself is finally replaced with a blank space).
--When you enter Tab
, input completion works in various places.
--When the candidates are displayed, continue to enter Tab
to move the cursor to the options in order.
--You can select candidates with ʻEnter`
--Not only command completion but also argument completion is supported.
package sample.spring.shell;
import org.springframework.shell.standard.ShellComponent;
import org.springframework.shell.standard.ShellMethod;
@ShellComponent
public class GreetingCommands {
@ShellMethod("Hello World")
public void hello(int a, int b, int c) {
System.out.println("a=" + a + ", b=" + b + ", c=" + c);
}
}
Execution result
shell:>【hello \】
> 【--a 10 \】
> 【--b 20 \】
> 【--c 30】
a=10, b=20, c=30
--By separating with a backslash (\
), you can describe the input of one command on multiple lines.
SampleCommands.java
package sample.spring.shell;
import org.springframework.shell.standard.ShellComponent;
import org.springframework.shell.standard.ShellMethod;
@ShellComponent
public class SampleCommands {
@ShellMethod("Hello World")
public void hello() {
System.out.println("Hello Spring Shell!!");
}
}
--To define a command, first create an arbitrary class and annotate the class with @ ShellComponent
.
--Next, create a method and annotate it with @ ShellMethod
--It is necessary to set the wording that explains the command in value
of @ ShellMethod
(otherwise an error will occur at startup).
--The wording of the explanation should be written so as to satisfy the following conditions in order to be consistent with other commands.
helloWorld
, it will be a hyphen-separated command name like hello-world
.
--When you execute the command, the corresponding method will be executed.SampleCommands.java
package sample.spring.shell;
import org.springframework.shell.standard.ShellComponent;
import org.springframework.shell.standard.ShellMethod;
@ShellComponent
public class SampleCommands {
@ShellMethod(value="Hello World", key="hoge")
public void hello() {
System.out.println("Hello Spring Shell!!");
}
}
Execution result
shell:>【hoge】
Hello Spring Shell!!
shell:>【hello】
No command found for 'hello'
Details of the error have been omitted. You can use the stacktrace command to print the full stacktrace.
--You can specify any name for the command name with key
of @ ShellMethod
.
SampleCommands.java
package sample.spring.shell;
import org.springframework.shell.standard.ShellComponent;
import org.springframework.shell.standard.ShellMethod;
@ShellComponent
public class SampleCommands {
@ShellMethod(value="Hello World", key={"hoge", "fuga"})
public void hello() {
System.out.println("Hello Spring Shell!!");
}
}
Execution result
shell:>【hoge】
Hello Spring Shell!!
shell:>【fuga】
Hello Spring Shell!!
shell:>【help】
AVAILABLE COMMANDS
Built-In Commands
...
Sample Commands
fuga, hoge: Hello World
--Since multiple names can be set for key
, multiple names can be assigned to one command as aliases.
python
package sample.spring.shell;
import org.springframework.shell.standard.ShellComponent;
import org.springframework.shell.standard.ShellMethod;
@ShellComponent
public class SampleCommands {
@ShellMethod("Hello World")
public void hello(int a, int b, int c) {
System.out.println("a=" + a + ", b=" + b + ", c=" + c);
}
}
Execution result
shell:>【hello 1 2 3】
a=1, b=2, c=3
shell:>【hello 1 2】
Parameter '--c int' should be specified
Details of the error have been omitted. You can use the stacktrace command to print the full stacktrace.
shell:>【hello a 2 3】
Failed to convert from type [java.lang.String] to type [int] for value 'a'; nested exception is java.lang.NumberFormatException: For input string: "a"
Details of the error have been omitted. You can use the stacktrace command to print the full stacktrace.
--If you define an argument to the method, you can pass the argument to the command. --The arguments passed to the command are passed to the method arguments in the same order. --An error will occur if there are insufficient arguments or if you pass a value that cannot be type converted.
package sample.spring.shell;
import org.springframework.shell.standard.ShellComponent;
import org.springframework.shell.standard.ShellMethod;
@ShellComponent
public class SampleCommands {
@ShellMethod("Hello World")
public void hello(int a, int b, int fooBar) {
System.out.println("a=" + a + ", b=" + b + ", fooBar=" + fooBar);
}
}
Execution result
shell:>【hello --a 1 --b 2 --foo-bar 3】
a=1, b=2, fooBar=3
shell:>【hello --foo-bar 3 --a 1 --b 2】
a=1, b=2, fooBar=3
shell:>【hello --b 2 1 3】
a=1, b=2, fooBar=3
--Arguments can also be specified with a name
--Specify the name as -[argument name] [value]
--By default, the argument name of the method is used as it is.
--However, if the camel case is the same as the command name and has two or more words, it will be replaced with a hyphen delimiter (--foo-bar
).
--You can mix unnamed argument specifications and named argument specifications.
--In that case, the named argument is assigned first to the method argument.
--And the remaining method arguments are assigned unnamed arguments in order
package sample.spring.shell;
import org.springframework.shell.standard.ShellComponent;
import org.springframework.shell.standard.ShellMethod;
@ShellComponent
public class SampleCommands {
@ShellMethod(value="Hello World", prefix="-")
public void hello(int a) {
System.out.println("a=" + a);
}
}
Execution result
shell:>【hello -a 1】
a=1
--You can change the prefix (-
) attached to the argument name when specifying the name with the prefix
attribute of @ ShellMethod
.
package sample.spring.shell;
import org.springframework.shell.standard.ShellComponent;
import org.springframework.shell.standard.ShellMethod;
import org.springframework.shell.standard.ShellOption;
@ShellComponent
public class SampleCommands {
@ShellMethod("Hello World")
public void hello(int a, @ShellOption("--foo") int b, @ShellOption({"-h", "--hoge"}) int c) {
System.out.println("a=" + a + ", b=" + b + ", c=" + c);
}
}
Execution result
shell:>【hello --a 1 --foo 2 -h 3】
a=1, b=2, c=3
shell:>【hello --a 1 --foo 2 --hoge 3】
a=1, b=2, c=3
--If you annotate a method argument with @ ShellOption
, you can change the command argument name with the value
attribute.
--Since the value
attribute can be specified as an array, multiple names can be assigned to the same argument.
package sample.spring.shell;
import org.springframework.shell.standard.ShellComponent;
import org.springframework.shell.standard.ShellMethod;
import org.springframework.shell.standard.ShellOption;
@ShellComponent
public class SampleCommands {
@ShellMethod("Hello World")
public void hello(@ShellOption(defaultValue="9") int a) {
System.out.println("a=" + a);
}
}
Execution result
shell:>【hello】
a=9
shell:>【hello 1】
a=1
--The defaultValue
attribute of @ ShellOption
can define the default value if that argument is not specified.
package sample.spring.shell;
import org.springframework.shell.standard.ShellComponent;
import org.springframework.shell.standard.ShellMethod;
import org.springframework.shell.standard.ShellOption;
import java.util.Arrays;
@ShellComponent
public class SampleCommands {
@ShellMethod("Hello World")
public void hello(@ShellOption(arity=3) int[] a, int b) {
System.out.println("a=" + Arrays.toString(a) + ", b=" + b);
}
}
Execution result
shell:>【hello 1 2 3 4】
a=[1, 2, 3], b=4
shell:>【hello --a 1 2 3 --b 4】
a=[1, 2, 3], b=4
shell:>【hello 1 --b 4 2 3】
a=[1, 2, 3], b=4
shell:>【hello --a 1 2 --b 4】
Failed to convert from type [java.lang.String] to type [@org.springframework.shell.standard.ShellOption int] for value '--b'; nested exception is java.lang.NumberFormatException: For input string: "--b"
Details of the error have been omitted. You can use the stacktrace command to print the full stacktrace.
shell:>【hello --a 1 2 3 4 --b 5】
Too many arguments: the following could not be mapped to parameters: '4'
Details of the error have been omitted. You can use the stacktrace command to print the full stacktrace.
--You can receive multiple values with one command argument
--Method arguments are defined as collection type or array type
--Also, annotate the argument with @ ShellOption
and specify the number of values to receive with the ʻarity attribute. --An error will occur if you try to pass a number different from the number specified by ʻarity
.
――It seems that you can't limit the number now (the document says TO BE IMPLEMENTED
)
package sample.spring.shell;
import org.springframework.shell.standard.ShellComponent;
import org.springframework.shell.standard.ShellMethod;
@ShellComponent
public class SampleCommands {
@ShellMethod("Hello World")
public void hello(boolean a) {
System.out.println("a=" + a);
}
}
Execution result
shell:>【hello】
a=false
shell:>【hello --a】
a=true
--If the argument type is boolean
, the specification method in the command changes a little.
--If no command argument is specified, it will be false
.
--When specifying command arguments, specify only the name and do not pass a value (an error will occur if you try to pass a value like --a true
)
--If you specify an argument, it becomes true
by itself.
package sample.spring.shell;
import org.springframework.shell.standard.ShellComponent;
import org.springframework.shell.standard.ShellMethod;
import org.springframework.shell.standard.ShellOption;
@ShellComponent
public class SampleCommands {
@ShellMethod("Hello World")
public void hello(@ShellOption(defaultValue="true") boolean a, @ShellOption(defaultValue="false") boolean b) {
System.out.println("a=" + a + ", b=" + b);
}
}
Execution result
shell:>【hello】
a=true, b=false
shell:>【hello --a --b】
a=false, b=true
--The behavior when " false "
is set to the default value is the same as when nothing is set.
--If no argument is specified false
--If you specify an argument, true
--If you set the default value to " true "
,
--If no argument is specified, it will be true
,
--If you specify an argument, it becomes false
package sample.spring.shell;
import org.springframework.shell.standard.ShellComponent;
import org.springframework.shell.standard.ShellMethod;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
@ShellComponent
public class SampleCommands {
@ShellMethod("Hello World")
public void hello(@Min(0) @Max(100) int a) {
System.out.println("a=" + a);
}
}
Execution result
shell:>【hello -1】
The following constraints were not met:
--a int : must be greater than or equal to 0 (You passed '-1')
shell:>【hello 0】
a=0
shell:>【hello 100】
a=100
shell:>【hello 101】
The following constraints were not met:
--a int : must be less than or equal to 100 (You passed '101')
--Spring Shell supports Bean Validation, and input checking can be performed by adding Bean Validation constraint annotation to method arguments. --Implementation library is Hibernate Validator --For Japanese localization of messages, [this method](https://qiita.com/opengl-8080/items/3926fbde5469c0b330c2#%E3%83%93%E3%83%AB%E3%83%88% E3% 82% A4% E3% 83% B3% E3% 81% AE% E5% 88% B6% E7% B4% 84% E3% 82% A2% E3% 83% 8E% E3% 83% 86% E3% 83% BC% E3% 82% B7% E3% 83% A7% E3% 83% B3% E3% 81% AE% E3% 83% 87% E3% 83% 95% E3% 82% A9% E3% 83% AB% E3% 83% 88% E3% 82% A8% E3% 83% A9% E3% 83% BC% E3% 83% A1% E3% 83% 83% E3% 82% BB% E3% 83% BC% E3% 82% B8% E3% 82% 92% E4% B8% 8A% E6% 9B% B8% E3% 81% 8D% E3% 81% 99% E3% 82% 8B) --However, it remains in English except for the Bean Validation error message.
SampleCommands.java
package sample.spring.shell;
import org.springframework.shell.standard.ShellComponent;
import org.springframework.shell.standard.ShellMethod;
@ShellComponent
public class SampleCommands {
@ShellMethod("Hello World")
public void hello(Hoge hoge) {
hoge.hello();
}
}
Hoge.java
package sample.spring.shell;
public class Hoge {
private final String value;
public Hoge(String value) {
this.value = value;
}
public void hello() {
System.out.println("Hoge(" + this.value + ")");
}
}
HogeConverter.java
package sample.spring.shell;
import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Component;
@Component
public class HogeConverter implements Converter<String, Hoge> {
@Override
public Hoge convert(String source) {
return new Hoge(source);
}
}
Execution result
shell:>【hello Hey】
Hoge(Hey)
--If you want to receive any type other than the basic type as an argument of the command method, you can do it by defining your own Converter
.
--Create a class that implements ʻorg.springframework.core.convert.converter.Converter <S, T> --Execute the
T convert (S)method and return the result of converting a value of type
S (mostly
String) to type
T. --Add
@Component` to make it registered in the container
package sample.spring.shell;
import org.springframework.shell.Availability;
import org.springframework.shell.standard.ShellComponent;
import org.springframework.shell.standard.ShellMethod;
@ShellComponent
public class SampleCommands {
private boolean greeted;
@ShellMethod("Hello World")
public void hello() {
System.out.println("Hello!!");
this.greeted = true;
}
@ShellMethod("Good Bye")
public void bye() {
System.out.println("Bye!!");
}
public Availability byeAvailability() {
return this.greeted
? Availability.available()
: Availability.unavailable("you does not greet yet.");
}
}
Execution result
shell:>【bye】
Command 'bye' exists but is not currently available because you does not greet yet.
Details of the error have been omitted. You can use the stacktrace command to print the full stacktrace.
shell:>【help】
AVAILABLE COMMANDS
Built-In Commands
...
Sample Commands
* bye: Good Bye
hello: Hello World
Commands marked with (*) are currently unavailable.
Type `help <command>` to learn more.
shell:>【hello】
Hello!!
shell:>【bye】
Bye!!
--Some commands may make you want to be unable to execute until a certain state is reached.
--For example, if you are trying to create a shell that connects to a server and issues some command
You may want to disable subsequent commands until the command to connect is successful.
--Spring Shell provides a mechanism to dynamically enable / disable commands.
--Invalid command will result in an error when executed
--In the above example, the bye
command is disabled until the hello
command is executed.
--The bye
command is judged to be valid or invalid by thebyeAvailability ()
method.
--A method with the suffix ʻAvailabilityadded to the name of the method for which you want to dynamically switch between valid and invalid is automatically identified as a judgment method. -
bye()->
byeAvailability() --Implement this method to return an object called ʻAvailability
--The ʻAvailability class provides two factory methods, ʻavailable ()
and ʻunavailable (String). --If valid, return the object created by the ʻavailable ()
method
--If invalid, return the object created by the ʻunavailable ()method --At this time, pass the reason why it is invalid as an argument in a short sentence. --Then, it is embedded in the error message
This command is currently not available because [here] ――So, if you write it so that it starts with a lowercase letter and ends with a dot, it feels good. --Information on whether the command is valid or invalid is reflected in the information when you see
help`.
package sample.spring.shell;
import org.springframework.shell.Availability;
import org.springframework.shell.standard.ShellComponent;
import org.springframework.shell.standard.ShellMethod;
import org.springframework.shell.standard.ShellMethodAvailability;
@ShellComponent
public class SampleCommands {
private boolean greeted;
@ShellMethod("Hello World")
public void hello() {
System.out.println("Hello!!");
this.greeted = true;
}
@ShellMethod("Good Bye")
@ShellMethodAvailability("checkByeAvailability")
public void bye() {
System.out.println("Bye!!");
}
public Availability checkByeAvailability() {
return this.greeted
? Availability.available()
: Availability.unavailable("you does not greet yet.");
}
}
--If you don't like the naming convention "[Target method name] Availability, you can change it to a method with any name. --Add the
@ShellMethodAvailability annotation to the method of the dynamic command, and specify the name of the method that determines whether it is valid or invalid in the
value` attribute.
package sample.spring.shell;
import org.springframework.shell.Availability;
import org.springframework.shell.standard.ShellComponent;
import org.springframework.shell.standard.ShellMethod;
import org.springframework.shell.standard.ShellMethodAvailability;
@ShellComponent
public class SampleCommands {
private boolean greeted;
@ShellMethod("Hello World")
public void hello() {
System.out.println("Hello!!");
this.greeted = true;
}
@ShellMethod("Good Bye")
public void bye() {
System.out.println("Bye!!");
}
@ShellMethod("lol")
public void laugh() {
System.out.println("HAHAHAHA!!");
}
@ShellMethodAvailability({"bye", "laugh"})
public Availability checkAvailability() {
return this.greeted
? Availability.available()
: Availability.unavailable("you does not greet yet.");
}
}
Execution result
shell:>【laugh】
Command 'laugh' exists but is not currently available because you does not greet yet.
Details of the error have been omitted. You can use the stacktrace command to print the full stacktrace.
shell:>【bye】
Command 'bye' exists but is not currently available because you does not greet yet.
Details of the error have been omitted. You can use the stacktrace command to print the full stacktrace.
shell:>【hello】
Hello!!
shell:>【laugh】
HAHAHAHA!!
shell:>【bye】
Bye!!
--If you want to control the enable / disable of multiple commands under the same conditions, you do not need to annotate each method with @ShellMethodAvailability
.
--Instead, annotate the valid / invalid judgment method with @ShellMethodAvailability
.
--And specify the ** command name ** of the array in the value
attribute
--Note that this is a command name, not a method name.
--In other words, if the method name is lotsOfLaugh
, the command name will be lots-of-laugh
, so it is the lots-of-laugh
that is specified for @ ShellMethodAvailability
.
SampleCommands.java
package sample.spring.shell;
import org.springframework.shell.standard.ShellComponent;
import org.springframework.shell.standard.ShellMethod;
@ShellComponent
public class SampleCommands {
private boolean greeted;
@ShellMethod("Hello World")
public void hello() {
System.out.println("Hello!!");
this.greeted = true;
}
public boolean isGreeted() {
return this.greeted;
}
}
SomeCommands.java
package sample.spring.shell;
import org.springframework.shell.Availability;
import org.springframework.shell.standard.ShellComponent;
import org.springframework.shell.standard.ShellMethod;
import org.springframework.shell.standard.ShellMethodAvailability;
@ShellComponent
public class SomeCommands {
private final SampleCommands sampleCommands;
public SomeCommands(SampleCommands sampleCommands) {
this.sampleCommands = sampleCommands;
}
@ShellMethod("Good Bye")
public void bye() {
System.out.println("Bye!!");
}
@ShellMethod("lol")
public void laugh() {
System.out.println("HAHAHAHA!!");
}
@ShellMethodAvailability
public Availability checkAvailability() {
return this.sampleCommands.isGreeted()
? Availability.available()
: Availability.unavailable("you does not greet yet.");
}
}
Execution result
shell:>【help】
AVAILABLE COMMANDS
Built-In Commands
...
Sample Commands
hello: Hello World
Some Commands
* bye: Good Bye
* laugh: lol
Commands marked with (*) are currently unavailable.
Type `help <command>` to learn more.
--If you want to control all the commands in the class at once, annotate the control method with @ ShellMethodAvailability
and do not set anything in the value
attribute.
--This takes advantage of the fact that the default value of the value
attribute is*
, which is a special wildcard for all commands.
--This will control all commands in the class.
--As the number of commands increases, it is better to group the commands to make it easier to see help etc. --Spring Shell provides a mechanism to group commands into arbitrary groups.
GreetingCommands.java
package sample.spring.shell;
import org.springframework.shell.standard.ShellComponent;
import org.springframework.shell.standard.ShellMethod;
@ShellComponent
public class GreetingCommands {
@ShellMethod("Hello World")
public void hello() {
System.out.println("Hello!!");
}
@ShellMethod("Good Bye")
public void bye() {
System.out.println("Bye!!");
}
}
CalcCommands.java
package sample.spring.shell;
import org.springframework.shell.standard.ShellComponent;
import org.springframework.shell.standard.ShellMethod;
@ShellComponent
public class CalcCommands {
@ShellMethod("a + b")
public int add(int a, int b) {
return a + b;
}
@ShellMethod("a - b")
public int minus(int a, int b) {
return a - b;
}
}
Execution result
shell:>【help】
AVAILABLE COMMANDS
Built-In Commands
...
Calc Commands
add: a + b
minus: a - b
Greeting Commands
bye: Good Bye
hello: Hello World
--If you do not specify a group, a group is defined for each class annotated with @ShellComponent
, and the commands defined in it are assigned to the group corresponding to that class.
--The group name will be the class name separated by words.
package sample.spring.shell;
import org.springframework.shell.standard.ShellComponent;
import org.springframework.shell.standard.ShellMethod;
@ShellComponent
public class GreetingCommands {
@ShellMethod(value="Hello World", group="Hello")
public void hello() {
System.out.println("Hello!!");
}
@ShellMethod("Good Bye")
public void bye() {
System.out.println("Bye!!");
}
}
Execution result
shell:>【help】
AVAILABLE COMMANDS
Built-In Commands
...
Greeting Commands
bye: Good Bye
Hello
hello: Hello World
--If you specify the group name in the group
attribute of @ ShellMethod
, you can specify the group for each command.
GreetingCommands.java
package sample.spring.shell;
import org.springframework.shell.standard.ShellCommandGroup;
import org.springframework.shell.standard.ShellComponent;
import org.springframework.shell.standard.ShellMethod;
@ShellComponent
@ShellCommandGroup("My Commands")
public class GreetingCommands {
@ShellMethod("Hello World")
public void hello() {
System.out.println("Hello!!");
}
@ShellMethod("Good Bye")
public void bye() {
System.out.println("Bye!!");
}
}
CalcCommands.java
package sample.spring.shell;
import org.springframework.shell.standard.ShellCommandGroup;
import org.springframework.shell.standard.ShellComponent;
import org.springframework.shell.standard.ShellMethod;
@ShellComponent
@ShellCommandGroup("My Commands")
public class CalcCommands {
@ShellMethod("a + b")
public int add(int a, int b) {
return a + b;
}
@ShellMethod("a - b")
public int minus(int a, int b) {
return a - b;
}
}
Execution result
shell:>【help】
AVAILABLE COMMANDS
Built-In Commands
...
My Commands
add: a + b
bye: Good Bye
hello: Hello World
minus: a - b
--Annotate the class that defines the command with @ShellCommandGroup
--And if you specify a group name with the value
attribute, the commands defined in that class will belong to that group.
--If the above-mentioned allocation for each command is specified, that will take precedence.
package-info.java
@ShellCommandGroup("my commands")
package sample.spring.shell;
import org.springframework.shell.standard.ShellCommandGroup;
Execution result
shell:>【help】
AVAILABLE COMMANDS
Built-In Commands
...
my commands
add: a + b
bye: Good Bye
hello: Hello World
minus: a - b
--Create package-info.java
and annotate the package with @ShellCommandGroup
--Then, the commands defined under that package will belong to the group specified there.
--If there is an allocation for each class mentioned above, that will take precedence.
package sample.spring.shell;
import org.springframework.shell.standard.ShellComponent;
import org.springframework.shell.standard.ShellMethod;
import org.springframework.shell.standard.ShellOption;
@ShellComponent
public class GreetingCommands {
@ShellMethod(value="Hello World")
public void hello(int a, @ShellOption(defaultValue="9", help="help text") int b) {
System.out.println("Hello!!");
}
}
Execution result
shell:>【help hello】
NAME
hello - Hello World
SYNOPSYS
hello [--a] int [[--b] int]
OPTIONS
--a int
[Mandatory]
--b int
help text
[Optional, default = 9]
--help [command name]
, you can check the detailed explanation of the specified command.
――Your own command also builds a nice help based on the definition information.
package sample.spring.shell;
import org.springframework.shell.standard.ShellComponent;
import org.springframework.shell.standard.ShellMethod;
@ShellComponent
public class GreetingCommands {
private boolean greeted;
@ShellMethod("Hello World")
public void hello() {
System.out.println("Hello!!");
this.greeted = true;
}
@ShellMethod("Good Bye")
public void bye() {
System.out.println("Bye!!");
}
public boolean isGreeted() {
return greeted;
}
}
MyPromptProvider.java
package sample.spring.shell;
import org.jline.utils.AttributedString;
import org.jline.utils.AttributedStyle;
import org.springframework.shell.jline.PromptProvider;
import org.springframework.stereotype.Component;
@Component
public class MyPromptProvider implements PromptProvider {
private final GreetingCommands greetingCommands;
public MyPromptProvider(GreetingCommands greetingCommands) {
this.greetingCommands = greetingCommands;
}
@Override
public AttributedString getPrompt() {
return this.greetingCommands.isGreeted()
? new AttributedString("greeted > ", AttributedStyle.DEFAULT.foreground(AttributedStyle.WHITE))
: new AttributedString("not greeted > ", AttributedStyle.DEFAULT.foreground(AttributedStyle.RED));
}
}
Execution result
not greeted > 【hello】
Hello!!
greeted >
--To change the prompt, create a class that implements PromptProvider
and register it in the container.
--Implement the getPrompt ()
method to return an instance of ʻAttributedString --ʻAttributedString
is a (ʻAttributed`) string with attribute information, and you can add character styles (bold, color, etc.).
build.gradle
dependencies {
compile('org.springframework.shell:spring-shell-starter:2.0.0.RELEASE') {
exclude module: 'spring-shell-standard-commands'
}
}
Execution result
shell:>【help】
No command found for 'help'
--Excluding spring-shell-standard-commands
from the dependencies will remove all built-in commands
―― ʻexit` also disappears, so you have to make your own command to terminate the shell.
package sample.spring.shell;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.util.StringUtils;
@SpringBootApplication
public class SampleApplication {
public static void main(String[] args) {
String[] disabledCommands = {"--spring.shell.command.help.enabled=false"};
String[] fullArgs = StringUtils.concatenateStringArrays(args, disabledCommands);
SpringApplication.run(SampleApplication.class, fullArgs);
}
}
Execution result
shell:>【help】
No command found for 'help'
Details of the error have been omitted. You can use the stacktrace command to print the full stacktrace.
shell:>【stacktrace】
org.springframework.shell.CommandNotFound: No command found for 'help'
at org.springframework.shell.Shell.evaluate(Shell.java:180)
at org.springframework.shell.Shell.run(Shell.java:134)
...
--By specifying spring.shell.command. [Command name] .enabled = [true | false]
as an argument at startup, you can control the enable / disable of built-in commands.
--In the above example, the image is as specified by the command line argument at startup, but it can also be specified by ʻapplication.properties` (I have not tried it, but it seems that it can be specified by environment variables)
SampleApplication.java
package sample.spring.shell;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.util.StringUtils;
@SpringBootApplication
public class SampleApplication {
public static void main(String[] args) {
String[] disabledCommands = {"--spring.shell.command.help.enabled=false"};
String[] fullArgs = StringUtils.concatenateStringArrays(args, disabledCommands);
SpringApplication.run(SampleApplication.class, fullArgs);
}
}
MyHelpCommand.java
package sample.spring.shell;
import org.springframework.shell.standard.ShellComponent;
import org.springframework.shell.standard.ShellMethod;
import org.springframework.shell.standard.commands.Help;
@ShellComponent
public class MyHelpCommand implements Help.Command {
@ShellMethod("My help command.")
public void help() {
System.out.println("HELP ME!!!!");
}
}
Execution result
shell:>【help】
HELP ME!!!!
--If you want to change the behavior of the built-in command, make the change by following the steps below.
[command name] .Command
.
--But it worked without implementing this interface (I'm not sure what it's used for)Recommended Posts