Add ability to run commands and exit

This commit is contained in:
Eric Bottard
2017-08-30 16:54:36 +02:00
parent 1216adbef8
commit 9f88c03cf3
10 changed files with 49 additions and 33 deletions

View File

@@ -49,8 +49,6 @@ import org.springframework.util.ReflectionUtils;
*/
public class Shell implements CommandRegistry {
private final InputProvider inputProvider;
private final ResultHandler resultHandler;
@Autowired
@@ -65,8 +63,7 @@ public class Shell implements CommandRegistry {
*/
protected static final Object UNRESOLVED = new Object();
public Shell(InputProvider inputProvider, ResultHandler resultHandler) {
this.inputProvider = inputProvider;
public Shell(ResultHandler resultHandler) {
this.resultHandler = resultHandler;
}
@@ -94,9 +91,9 @@ public class Shell implements CommandRegistry {
/**
* The main program loop: acquire input, try to match it to a command and evaluate. Repeat until a
* {@link ResultHandler} causes the process to exit.
* {@link ResultHandler} causes the process to exit or there is no input.
*/
public void run() throws IOException {
public void run(InputProvider inputProvider) throws IOException {
while (true) {
Input input;
try {

View File

@@ -16,6 +16,7 @@
package org.springframework.shell;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
@@ -40,14 +41,9 @@ public class SpringShellAutoConfiguration {
}
@Bean
@ConditionalOnMissingBean(ApplicationRunner.class)
public ApplicationRunner applicationRunner(Shell shell) {
return new ApplicationRunner() {
@Override
public void run(ApplicationArguments args) throws Exception {
shell.run();
}
};
public Shell shell(@Qualifier("main") ResultHandler resultHandler) {
return new Shell(resultHandler);
}
}

View File

@@ -16,7 +16,7 @@
package org.springframework.shell.jline;
import java.io.IOException;
import java.io.*;
import java.nio.file.Paths;
import java.util.List;
import java.util.stream.Collectors;
@@ -35,6 +35,8 @@ import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.context.ApplicationListener;
@@ -61,16 +63,15 @@ import org.springframework.shell.Shell;
@Configuration
class JLineShellAutoConfiguration {
@Autowired
@Qualifier("main")
private ResultHandler resultHandler;
@Autowired
private PromptProvider promptProvider;
@Autowired
private History history;
@Autowired
private Shell shell;
@Bean
public Terminal terminal() {
try {
@@ -82,10 +83,31 @@ class JLineShellAutoConfiguration {
}
@Bean
public Shell shell() {
return new Shell(new JLineInputProvider(lineReader(), promptProvider), resultHandler);
@ConditionalOnMissingBean(ApplicationRunner.class)
public ApplicationRunner applicationRunner(Parser parser) {
return new ApplicationRunner() {
@Override
public void run(ApplicationArguments args) throws Exception {
List<File> scriptsToRun = args.getNonOptionArgs().stream()
.filter(s -> s.startsWith("@"))
.map(s -> new File(s.substring(1)))
.collect(Collectors.toList());
if (scriptsToRun.isEmpty()) {
InputProvider inputProvider = new JLineInputProvider(lineReader(), promptProvider);
shell.run(inputProvider);
} else {
for (File file : scriptsToRun) {
try (Reader reader = new FileReader(file); FileInputProvider inputProvider = new FileInputProvider(reader, parser)) {
shell.run(inputProvider);
}
}
}
}
};
}
@Bean
@ConditionalOnMissingBean(PromptProvider.class)
public PromptProvider promptProvider() {
@@ -127,7 +149,7 @@ class JLineShellAutoConfiguration {
*/
@PostConstruct
public void lateInit() {
completer().setShell(shell());
completer().setShell(shell);
}
@Bean
@@ -151,7 +173,7 @@ class JLineShellAutoConfiguration {
public AttributedString highlight(LineReader reader, String buffer) {
int l = 0;
String best = null;
for (String command : shell().listCommands().keySet()) {
for (String command : shell.listCommands().keySet()) {
if (buffer.startsWith(command) && command.length() > l) {
l = command.length();
best = command;

View File

@@ -32,5 +32,6 @@ public class AttributedCharSequenceResultHandler extends TerminalAwareResultHand
@Override
public void handleResult(AttributedCharSequence result) {
terminal.writer().println(result.toAnsi(terminal));
terminal.writer().flush();
}
}

View File

@@ -37,6 +37,7 @@ public class CommandNotFoundResultHandler extends TerminalAwareResultHandler imp
public void handleResult(CommandNotFound result) {
terminal.writer().println(new AttributedString(result.getMessage(),
AttributedStyle.DEFAULT.foreground(AttributedStyle.RED)).toAnsi());
terminal.writer().flush();
}
}

View File

@@ -31,5 +31,6 @@ public class TerminalSizeAwareResultHandler extends TerminalAwareResultHandler i
public void handleResult(TerminalSizeAware result) {
CharSequence toPrint = result.render(terminal.getWidth());
terminal.writer().println(toPrint);
terminal.writer().flush();
}
}

View File

@@ -58,6 +58,7 @@ public class ThrowableResultHandler extends TerminalAwareResultHandler implement
.toAnsi()
);
}
terminal.writer().flush();
}
/**

View File

@@ -82,7 +82,7 @@ public class ShellTest {
shell.methodTargets = Collections.singletonMap("hello world", MethodTarget.of("helloWorld", this, "Say hello"));
try {
shell.run();
shell.run(inputProvider);
fail("Exit expected");
}
catch (Exit expected) {
@@ -100,7 +100,7 @@ public class ShellTest {
shell.methodTargets = Collections.singletonMap("bonjour", MethodTarget.of("helloWorld", this, "Say hello"));
try {
shell.run();
shell.run(inputProvider);
fail("Exit expected");
}
catch (Exit expected) {
@@ -119,7 +119,7 @@ public class ShellTest {
shell.methodTargets = Collections.singletonMap("hello world", MethodTarget.of("helloWorld", this, "Say hello"));
try {
shell.run();
shell.run(inputProvider);
fail("Exit expected");
}
catch (Exit expected) {
@@ -138,7 +138,7 @@ public class ShellTest {
shell.methodTargets = Collections.singletonMap("fail", MethodTarget.of("failing", this, "Will throw an exception"));
try {
shell.run();
shell.run(inputProvider);
fail("Exit expected");
}
catch (Exit expected) {
@@ -154,7 +154,7 @@ public class ShellTest {
when(parameterResolver.supports(any())).thenReturn(true);
when(inputProvider.readInput()).thenReturn(() -> "// This is a comment", (Input) null);
shell.run();
shell.run(inputProvider);
}

View File

@@ -16,6 +16,7 @@
package org.springframework.shell.samples;
import org.jline.terminal.Terminal;
import org.jline.utils.AttributedString;
import org.jline.utils.AttributedStyle;

View File

@@ -47,11 +47,7 @@ public class Script {
public void script(File file) throws IOException {
Reader reader = new FileReader(file);
try (FileInputProvider inputProvider = new FileInputProvider(reader, parser)) {
Input input = inputProvider.readInput();
while (input != null) {
shell.evaluate(input);
input = inputProvider.readInput();
}
shell.run(inputProvider);
}
}