From 3fe26025cd8a04308bfc62210ddc3ee74337039d Mon Sep 17 00:00:00 2001 From: Janne Valkealahti Date: Fri, 14 Oct 2022 06:33:44 +0100 Subject: [PATCH] Process given values is a parser - Modify CommandParser to convert given option value if its type is defined - This change makes option default value to behave same as given value what comes for the actual value in a CommandContext. - Fixes #548 --- .../shell/command/CommandParser.java | 7 ++++- .../shell/command/CommandParserTests.java | 30 ++++++++++++++++++- .../shell/samples/e2e/OptionTypeCommands.java | 11 ++++++- 3 files changed, 45 insertions(+), 3 deletions(-) diff --git a/spring-shell-core/src/main/java/org/springframework/shell/command/CommandParser.java b/spring-shell-core/src/main/java/org/springframework/shell/command/CommandParser.java index a7ece482..a356acba 100644 --- a/spring-shell-core/src/main/java/org/springframework/shell/command/CommandParser.java +++ b/spring-shell-core/src/main/java/org/springframework/shell/command/CommandParser.java @@ -323,6 +323,11 @@ public interface CommandParser { List subArgs = lr.subList(1, lr.size()); ConvertArgumentsHolder holder = convertArguments(o, subArgs); Object value = holder.value; + if (conversionService != null && o.getType() != null && value != null) { + if (conversionService.canConvert(value.getClass(), o.getType().getRawClass())) { + value = conversionService.convert(value, o.getType().getRawClass()); + } + } Stream unmapped = holder.unmapped.stream() .map(um -> ParserResult.of(null, Arrays.asList(um), null, null)); Stream res = Stream.of(ParserResult.of(o, subArgs, value, null)); @@ -341,7 +346,7 @@ public interface CommandParser { defaultValueOptionsToCheck.remove(pr.option); } }); - defaultValueOptionsToCheck.stream() + defaultValueOptionsToCheck.stream() .filter(co -> co.getDefaultValue() != null) .forEach(co -> { Object value = co.getDefaultValue(); diff --git a/spring-shell-core/src/test/java/org/springframework/shell/command/CommandParserTests.java b/spring-shell-core/src/test/java/org/springframework/shell/command/CommandParserTests.java index 52ffd9af..bb8d025e 100644 --- a/spring-shell-core/src/test/java/org/springframework/shell/command/CommandParserTests.java +++ b/spring-shell-core/src/test/java/org/springframework/shell/command/CommandParserTests.java @@ -292,7 +292,7 @@ public class CommandParserTests extends AbstractCommandTests { CommandParserResults results = parser.parse(options, args); assertThat(results.results()).hasSize(1); assertThat(results.results().get(0).option()).isSameAs(option1); - assertThat(results.results().get(0).value()).isEqualTo(new String[] { "1", "2" }); + assertThat(results.results().get(0).value()).isEqualTo(new int[] { 1, 2 }); } @Test @@ -337,6 +337,34 @@ public class CommandParserTests extends AbstractCommandTests { assertThat(results.results().get(0).value()).isEqualTo(true); } + @Test + public void testIntegerWithDefault() { + ResolvableType type = ResolvableType.forType(Integer.class); + CommandOption option1 = CommandOption.of(new String[] { "arg1" }, new Character[0], "description", type, false, + "1", null, null, null, null, null); + + List options = Arrays.asList(option1); + String[] args = new String[]{}; + CommandParserResults results = parser.parse(options, args); + assertThat(results.results()).hasSize(1); + assertThat(results.results().get(0).option()).isSameAs(option1); + assertThat(results.results().get(0).value()).isEqualTo(1); + } + + @Test + public void testIntegerWithGivenValue() { + ResolvableType type = ResolvableType.forType(Integer.class); + CommandOption option1 = CommandOption.of(new String[] { "arg1" }, new Character[0], "description", type, false, + null, null, null, null, null, null); + + List options = Arrays.asList(option1); + String[] args = new String[] { "--arg1", "1" }; + CommandParserResults results = parser.parse(options, args); + assertThat(results.results()).hasSize(1); + assertThat(results.results().get(0).option()).isSameAs(option1); + assertThat(results.results().get(0).value()).isEqualTo(1); + } + private static CommandOption longOption(String name) { return longOption(name, null); } diff --git a/spring-shell-samples/src/main/java/org/springframework/shell/samples/e2e/OptionTypeCommands.java b/spring-shell-samples/src/main/java/org/springframework/shell/samples/e2e/OptionTypeCommands.java index 3b53116d..7238f8ed 100644 --- a/spring-shell-samples/src/main/java/org/springframework/shell/samples/e2e/OptionTypeCommands.java +++ b/spring-shell-samples/src/main/java/org/springframework/shell/samples/e2e/OptionTypeCommands.java @@ -15,6 +15,8 @@ */ package org.springframework.shell.samples.e2e; +import java.io.PrintWriter; + import org.springframework.context.annotation.Bean; import org.springframework.shell.command.CommandRegistration; import org.springframework.shell.standard.ShellComponent; @@ -48,7 +50,14 @@ public class OptionTypeCommands extends BaseE2ECommands { .label("MYLABEL") .and() .withTarget() - .consumer(ctx -> {}) + .consumer(ctx -> { + PrintWriter writer = ctx.getTerminal().writer(); + if (ctx.hasMappedOption("arg3")) { + int v = ctx.getOptionValue("arg3"); + writer.append("arg3=" + Integer.toString(v) + "\n"); + } + writer.flush(); + }) .and() .build(); }