From 56adc9ab5ac64997d8f71db863ed7b8d5f571cc7 Mon Sep 17 00:00:00 2001 From: Eric Bottard Date: Wed, 23 Aug 2017 21:09:40 +0200 Subject: [PATCH] Write tutorial in ref doc --- .../src/main/asciidoc/using-spring-shell.adoc | 101 +++++++++++++++++- .../main/asciidoc/what-is-spring-shell.adoc | 14 +++ .../shell/standard/commands/Script.java | 2 +- .../shell/standard/commands/Stacktrace.java | 2 +- 4 files changed, 116 insertions(+), 3 deletions(-) diff --git a/spring-shell-docs/src/main/asciidoc/using-spring-shell.adoc b/spring-shell-docs/src/main/asciidoc/using-spring-shell.adoc index 4b07d31c..630f3634 100644 --- a/spring-shell-docs/src/main/asciidoc/using-spring-shell.adoc +++ b/spring-shell-docs/src/main/asciidoc/using-spring-shell.adoc @@ -1,16 +1,115 @@ +:starter-artifactId: spring-shell-starter + == Using Spring Shell -=== Getting started +=== Getting Started +To see what Spring Shell has to offer, let's write a trivial shell application that +has a simple command to add two numbers together. ==== Let's Write a Simple Boot App +Starting with version 2, Spring Shell has been rewritten from the ground up with various +enhancements in mind, one of which is easy integration with Spring Boot, although it is +not a strong requirement. +For the purpose of this tutorial, let's create a simple Boot application, for example +using http://start.spring.io. This minimal application only depends on `spring-boot-starter` +and configures the `spring-boot-maven-plugin`, generating an executable über-jar: + +[source, xml] +---- +... + + + org.springframework.boot + spring-boot-starter + + ... +---- ==== Adding a Dependency on Spring Shell +The easiest way to get going with Spring Shell is to depend on the `{starter-artifactId}` artifact. +This comes with everything one needs to use Spring Shell and plays nicely with Boot, +configuring only the necessary beans as needed: + +[source, xml, subs=attributes+] +---- +... + + org.springframework.shell + {starter-artifactId} + {project-version} + +... +---- + +Given that Spring Shell will kick in and start the REPL by virtue of this dependency being present, +you'll need to either build skipping tests (`-DskipTests`) throughout this tutorial or remove the sample integration test +that was generated by http://start.spring.io. If you don't do so, the integration test will create +the Spring `ApplicationContext` and stay stuck in the eval loop. ==== Your first command +It's time to add our first command. Create a new class (name it however you want) and +annotate it with `@ShellComponent` (a variation of `@Component` that is used to restrict +the set of classes that are scanned for candidate commands). + +Then, create an `add` method that takes two ints (`a` and `b`) and returns their sum. Annotate it +with `@ShellMethod` and provide a description of the command in the annotation (the only piece of +information that is required): + +[source, java] +---- +package com.example.demo; + +import org.springframework.shell.standard.ShellMethod; +import org.springframework.shell.standard.ShellComponent; + +@ShellComponent +public class MyCommands { + + @ShellMethod("Add two integers together.") + public int add(int a, int b) { + return a + b; + } +} +---- ==== Let's Give It a Ride! +Build the application and run the generated jar, like so; +[source, bash] +---- +./mvnw clean install -DskipTests +[...] +java -jar target/demo-0.0.1-SNAPSHOT.jar +---- +You'll be greeted by the following screen (the banner comes from Spring Boot, and can be customized +http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-banner[as usual]): + +[source] +---- + + . ____ _ __ _ _ + /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ +( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ + \\/ ___)| |_)| | | | | || (_| | ) ) ) ) + ' |____| .__|_| |_|_| |_\__, | / / / / + =========|_|==============|___/=/_/_/_/ + :: Spring Boot :: (v1.5.6.RELEASE) + +shell:> +---- + +Below is a yellow `shell:>` prompt that invites you to type commands. Type `add 1 2` then kbd:[ENTER] and admire the magic! + +[source, bash] +---- +shell:>add 1 2 +3 +---- + +Try to play with the shell (hint: there is a `help` command) and when you're done, type `exit` kbd:[ENTER]. + +The rest of this document delves deeper into the whole Spring Shell programming model. === Writing your own Commands `@ShellComponent`, `@ShellMethod`, etc. diff --git a/spring-shell-docs/src/main/asciidoc/what-is-spring-shell.adoc b/spring-shell-docs/src/main/asciidoc/what-is-spring-shell.adoc index 516980f2..fe78d52b 100644 --- a/spring-shell-docs/src/main/asciidoc/what-is-spring-shell.adoc +++ b/spring-shell-docs/src/main/asciidoc/what-is-spring-shell.adoc @@ -1,2 +1,16 @@ == What is Spring Shell? +Not all applications need a fancy web user interface! +Sometimes, interacting with an application using an interactive terminal is +the most appropriate way to get things done. + +Spring Shell allows one to easily create such a runnable application, where the +user will enter textual commands that will get executed until the program terminates. +The Spring Shell project provides the infrastructure to create such a REPL (Read, Eval, +Print Loop), allowing the developer to concentrate on the commands implementation, using +the familiar Spring programming model. + +Advanced features such as parsing, kbd:[TAB] completion, colorization of output, fancy ascii-art +table display, input conversion and validation all come for free, with the developer only +having to focus on core command logic. + diff --git a/spring-shell-standard-commands/src/main/java/org/springframework/shell/standard/commands/Script.java b/spring-shell-standard-commands/src/main/java/org/springframework/shell/standard/commands/Script.java index ebfa64e7..2414a655 100644 --- a/spring-shell-standard-commands/src/main/java/org/springframework/shell/standard/commands/Script.java +++ b/spring-shell-standard-commands/src/main/java/org/springframework/shell/standard/commands/Script.java @@ -43,7 +43,7 @@ public class Script { public interface Command { } - @ShellMethod(value = "Read and execute commands from a file") + @ShellMethod(value = "Read and execute commands from a file.") public void script(File file) throws IOException { Reader reader = new FileReader(file); try (FileInputProvider inputProvider = new FileInputProvider(reader, parser)) { diff --git a/spring-shell-standard-commands/src/main/java/org/springframework/shell/standard/commands/Stacktrace.java b/spring-shell-standard-commands/src/main/java/org/springframework/shell/standard/commands/Stacktrace.java index 40370a56..c64854cf 100644 --- a/spring-shell-standard-commands/src/main/java/org/springframework/shell/standard/commands/Stacktrace.java +++ b/spring-shell-standard-commands/src/main/java/org/springframework/shell/standard/commands/Stacktrace.java @@ -50,7 +50,7 @@ public class Stacktrace { private ThrowableResultHandler throwableResultHandler; - @ShellMethod(key = ThrowableResultHandler.DETAILS_COMMAND_NAME, value = "Display the full stacktrace of the last error") + @ShellMethod(key = ThrowableResultHandler.DETAILS_COMMAND_NAME, value = "Display the full stacktrace of the last error.") public void stacktrace() { if (throwableResultHandler.getLastError() != null) { throwableResultHandler.getLastError().printStackTrace(terminal.writer());