Use string array in ShellRunner
- In ShellRunner interface replace use of boot's ApplicationArguments into plain string array. - Deprecate old methods with some fallbacks to give time for users to do updates. - NonInteractiveShellRunner contains one breaking change due to its public api to set function doing conversion from ApplicationArguments which was potentially used via customizer hooks. - Deprecations planned to get removed in 3.4.x. - Fixes #1057
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2021-2022 the original author or authors.
|
||||
* Copyright 2021-2024 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -56,6 +56,27 @@ public class DefaultShellApplicationRunner implements ShellApplicationRunner {
|
||||
@Override
|
||||
public void run(ApplicationArguments args) throws Exception {
|
||||
log.debug("Checking shell runners {}", shellRunners);
|
||||
|
||||
// Handle new ShellRunner api
|
||||
String[] sourceArgs = args.getSourceArgs();
|
||||
boolean canRun = false;
|
||||
for (ShellRunner runner : shellRunners) {
|
||||
try {
|
||||
canRun = runner.run(sourceArgs);
|
||||
} catch (Exception e) {
|
||||
break;
|
||||
}
|
||||
if (canRun) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (canRun) {
|
||||
// new api handled execution
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle old deprecated ShellRunner api
|
||||
Optional<ShellRunner> optional = shellRunners.stream()
|
||||
.filter(sh -> sh.canRun(args))
|
||||
.findFirst();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2021 the original author or authors.
|
||||
* Copyright 2021-2024 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -27,16 +27,41 @@ public interface ShellRunner {
|
||||
/**
|
||||
* Checks if a particular shell runner can execute.
|
||||
*
|
||||
* For {@link #canRun(ApplicationArguments)} and
|
||||
* {@link #run(ApplicationArguments)} prefer {@link #run(String[])}.
|
||||
*
|
||||
* @param args the application arguments
|
||||
* @return true if shell runner can execute
|
||||
*/
|
||||
boolean canRun(ApplicationArguments args);
|
||||
@Deprecated(since = "3.3.0", forRemoval = true)
|
||||
default boolean canRun(ApplicationArguments args) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute application.
|
||||
*
|
||||
* For {@link #canRun(ApplicationArguments)} and
|
||||
* {@link #run(ApplicationArguments)} prefer {@link #run(String[])}.
|
||||
*
|
||||
* @param args the application argumets
|
||||
* @throws Exception in errors
|
||||
*/
|
||||
void run(ApplicationArguments args) throws Exception;
|
||||
@Deprecated(since = "3.3.0", forRemoval = true)
|
||||
default void run(ApplicationArguments args) throws Exception {
|
||||
throw new UnsupportedOperationException("Should get implemented together with canRun");
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute {@code ShellRunner} with given args. Return value indicates if run
|
||||
* operation happened and no further runners should be used.
|
||||
*
|
||||
* @param args the raw arguments
|
||||
* @return true if run execution happened
|
||||
* @throws Exception possible error during run
|
||||
*/
|
||||
default boolean run(String[] args) throws Exception {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -21,7 +21,6 @@ import org.jline.reader.LineReader;
|
||||
import org.jline.reader.UserInterruptException;
|
||||
import org.jline.utils.AttributedString;
|
||||
|
||||
import org.springframework.boot.ApplicationArguments;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.shell.ExitRequest;
|
||||
import org.springframework.shell.Input;
|
||||
@@ -67,14 +66,10 @@ public class InteractiveShellRunner implements ShellRunner {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(ApplicationArguments args) throws Exception {
|
||||
public boolean run(String[] args) throws Exception {
|
||||
shellContext.setInteractionMode(InteractionMode.INTERACTIVE);
|
||||
InputProvider inputProvider = new JLineInputProvider(lineReader, promptProvider);
|
||||
shell.run(inputProvider);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canRun(ApplicationArguments args) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2021-2023 the original author or authors.
|
||||
* Copyright 2021-2024 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -25,7 +25,6 @@ import org.jline.reader.ParsedLine;
|
||||
import org.jline.reader.Parser;
|
||||
import org.jline.reader.impl.DefaultParser;
|
||||
|
||||
import org.springframework.boot.ApplicationArguments;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.shell.Input;
|
||||
import org.springframework.shell.InputProvider;
|
||||
@@ -34,6 +33,7 @@ import org.springframework.shell.ShellRunner;
|
||||
import org.springframework.shell.Utils;
|
||||
import org.springframework.shell.context.InteractionMode;
|
||||
import org.springframework.shell.context.ShellContext;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
@@ -65,8 +65,8 @@ public class NonInteractiveShellRunner implements ShellRunner {
|
||||
private static final String SINGLE_QUOTE = "\'";
|
||||
private static final String DOUBLE_QUOTE = "\"";
|
||||
|
||||
private Function<ApplicationArguments, List<String>> commandsFromInputArgs = args -> {
|
||||
if (args.getSourceArgs().length == 0) {
|
||||
private Function<String[], List<String>> commandsFromArgs = args -> {
|
||||
if (ObjectUtils.isEmpty(args)) {
|
||||
if (StringUtils.hasText(primaryCommand)) {
|
||||
Collections.singletonList(primaryCommand);
|
||||
}
|
||||
@@ -75,7 +75,7 @@ public class NonInteractiveShellRunner implements ShellRunner {
|
||||
}
|
||||
}
|
||||
// re-quote if needed having whitespace
|
||||
String raw = Arrays.stream(args.getSourceArgs())
|
||||
String raw = Arrays.stream(args)
|
||||
.map(a -> {
|
||||
if (!isQuoted(a) && StringUtils.containsWhitespace(a)) {
|
||||
return "\"" + a + "\"";
|
||||
@@ -113,12 +113,12 @@ public class NonInteractiveShellRunner implements ShellRunner {
|
||||
/**
|
||||
* Sets the function that creates the command() to run from the input application arguments.
|
||||
*
|
||||
* @param commandsFromInputArgs function that takes input application arguments and creates zero or more commands
|
||||
* @param commandsFromArgs function that takes input application arguments and creates zero or more commands
|
||||
* where each command is a string that specifies the command and options
|
||||
* (eg. 'history --file myHistory.txt')
|
||||
*/
|
||||
public void setCommandsFromInputArgs(Function<ApplicationArguments, List<String>> commandsFromInputArgs) {
|
||||
this.commandsFromInputArgs = commandsFromInputArgs;
|
||||
public void setCommandsFromArgs(Function<String[], List<String>> commandsFromArgs) {
|
||||
this.commandsFromArgs = commandsFromArgs;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -131,19 +131,18 @@ public class NonInteractiveShellRunner implements ShellRunner {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canRun(ApplicationArguments args) {
|
||||
return !commandsFromInputArgs.apply(args).isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(ApplicationArguments args) throws Exception {
|
||||
shellContext.setInteractionMode(InteractionMode.NONINTERACTIVE);
|
||||
List<String> commands = this.commandsFromInputArgs.apply(args);
|
||||
public boolean run(String[] args) throws Exception {
|
||||
List<String> commands = commandsFromArgs.apply(args);
|
||||
if (commands.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
List<ParsedLine> parsedLines = commands.stream()
|
||||
.map(rawCommandLine -> lineParser.parse(rawCommandLine, rawCommandLine.length() + 1))
|
||||
.collect(Collectors.toList());
|
||||
MultiParsedLineInputProvider inputProvider = new MultiParsedLineInputProvider(parsedLines);
|
||||
shellContext.setInteractionMode(InteractionMode.NONINTERACTIVE);
|
||||
shell.run(inputProvider);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -19,15 +19,16 @@ package org.springframework.shell.jline;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.Reader;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.jline.reader.Parser;
|
||||
|
||||
import org.springframework.boot.ApplicationArguments;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.shell.Shell;
|
||||
import org.springframework.shell.ShellRunner;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
/**
|
||||
* A {@link ShellRunner} that looks for process arguments that start with {@literal @}, which are then interpreted as
|
||||
@@ -59,19 +60,16 @@ public class ScriptShellRunner implements ShellRunner {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canRun(ApplicationArguments args) {
|
||||
String[] sourceArgs = args.getSourceArgs();
|
||||
if (sourceArgs.length > 0 && sourceArgs[0].startsWith("@") && sourceArgs[0].length() > 1) {
|
||||
return true;
|
||||
public boolean run(String[] args) throws Exception {
|
||||
String[] sourceArgs = args;
|
||||
if (ObjectUtils.isEmpty(sourceArgs)) {
|
||||
return false;
|
||||
}
|
||||
if (!(sourceArgs[0].startsWith("@") && sourceArgs[0].length() > 1)) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//tag::documentation[]
|
||||
|
||||
@Override
|
||||
public void run(ApplicationArguments args) throws Exception {
|
||||
List<File> scriptsToRun = args.getNonOptionArgs().stream()
|
||||
List<File> scriptsToRun = Arrays.asList(args).stream()
|
||||
.filter(s -> s.startsWith("@"))
|
||||
.map(s -> new File(s.substring(1)))
|
||||
.collect(Collectors.toList());
|
||||
@@ -82,7 +80,8 @@ public class ScriptShellRunner implements ShellRunner {
|
||||
shell.run(inputProvider);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
//end::documentation[]
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user