Add support for exit codes
- New configurations to CommandRegistration - Re-using exit code concepts from boot - Handling exit codes only in non-interactive mode - Adding e2e commands and tests for better coverage - Fixes #431
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright 2022 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.shell.boot;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.springframework.boot.ExitCodeExceptionMapper;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.shell.command.CommandExecution;
|
||||
import org.springframework.shell.exit.ExitCodeMappings;
|
||||
|
||||
/**
|
||||
* {@link EnableAutoConfiguration Auto-configuration} for exit codes.
|
||||
*
|
||||
* @author Janne Valkealahti
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
public class ExitCodeAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public ShellExitCodeExceptionMapper shellExitCodeExceptionMapper() {
|
||||
return new ShellExitCodeExceptionMapper();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public ShellExitCodeMappingsExceptionMapper shellExitCodeMappingsExceptionMapper() {
|
||||
return new ShellExitCodeMappingsExceptionMapper();
|
||||
}
|
||||
|
||||
static class ShellExitCodeExceptionMapper implements ExitCodeExceptionMapper {
|
||||
|
||||
@Override
|
||||
public int getExitCode(Throwable exception) {
|
||||
if (exception.getCause() instanceof CommandExecution.CommandParserExceptionsException) {
|
||||
return 2;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
static class ShellExitCodeMappingsExceptionMapper implements ExitCodeExceptionMapper, ExitCodeMappings {
|
||||
|
||||
private final List<Function<Throwable, Integer>> functions = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public void reset(List<Function<Throwable, Integer>> functions) {
|
||||
this.functions.clear();
|
||||
if (functions != null) {
|
||||
this.functions.addAll(functions);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getExitCode(Throwable exception) {
|
||||
int exitCode = 0;
|
||||
for (Function<Throwable, Integer> function : functions) {
|
||||
Integer code = function.apply(exception.getCause());
|
||||
if (code != null) {
|
||||
if (code > 0 && code > exitCode || code < 0 && code < exitCode) {
|
||||
exitCode = code;
|
||||
}
|
||||
}
|
||||
}
|
||||
return exitCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -34,6 +34,8 @@ import org.springframework.shell.ResultHandler;
|
||||
import org.springframework.shell.ResultHandlerService;
|
||||
import org.springframework.shell.Shell;
|
||||
import org.springframework.shell.command.CommandCatalog;
|
||||
import org.springframework.shell.context.ShellContext;
|
||||
import org.springframework.shell.exit.ExitCodeMappings;
|
||||
import org.springframework.shell.result.GenericResultHandlerService;
|
||||
import org.springframework.shell.result.ResultHandlerConfig;
|
||||
|
||||
@@ -65,8 +67,9 @@ public class SpringShellAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
public Shell shell(ResultHandlerService resultHandlerService, CommandCatalog commandRegistry, Terminal terminal,
|
||||
@Qualifier("shellConversionService") ConversionService shellConversionService) {
|
||||
Shell shell = new Shell(resultHandlerService, commandRegistry, terminal);
|
||||
@Qualifier("shellConversionService") ConversionService shellConversionService, ShellContext shellContext,
|
||||
ExitCodeMappings exitCodeMappings) {
|
||||
Shell shell = new Shell(resultHandlerService, commandRegistry, terminal, shellContext, exitCodeMappings);
|
||||
shell.setConversionService(shellConversionService);
|
||||
return shell;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
||||
org.springframework.shell.boot.ExitCodeAutoConfiguration,\
|
||||
org.springframework.shell.boot.ShellContextAutoConfiguration,\
|
||||
org.springframework.shell.boot.SpringShellAutoConfiguration,\
|
||||
org.springframework.shell.boot.ShellRunnerAutoConfiguration,\
|
||||
|
||||
Reference in New Issue
Block a user