diff --git a/spring-shell-core/src/main/java/org/springframework/shell/core/command/DefaultCommandParser.java b/spring-shell-core/src/main/java/org/springframework/shell/core/command/DefaultCommandParser.java index 8e1fa7ee8..fb4a8b5b2 100644 --- a/spring-shell-core/src/main/java/org/springframework/shell/core/command/DefaultCommandParser.java +++ b/spring-shell-core/src/main/java/org/springframework/shell/core/command/DefaultCommandParser.java @@ -52,7 +52,7 @@ public class DefaultCommandParser implements CommandParser { @Override public ParsedInput parse(String input) { log.debug("Parsing input: " + input); - List words = List.of(input.split(" (?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)")); + List words = List.of(input.split("\\s+(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)")); // the first word is the (root) command name String commandName = words.get(0); @@ -143,7 +143,7 @@ private CommandOption parseOption(String word) { String value = ""; if (word.startsWith("--")) { word = word.substring(2); - String[] tokens = word.split("="); + String[] tokens = word.split("=", 2); longName = tokens[0]; if (tokens.length > 1) { value = tokens[1]; @@ -151,7 +151,7 @@ private CommandOption parseOption(String word) { } else if (word.startsWith("-")) { word = word.substring(1); - String[] tokens = word.split("="); + String[] tokens = word.split("=", 2); shortName = tokens[0].charAt(0); if (tokens.length > 1) { value = tokens[1]; diff --git a/spring-shell-core/src/test/java/org/springframework/shell/core/command/DefaultCommandParserTests.java b/spring-shell-core/src/test/java/org/springframework/shell/core/command/DefaultCommandParserTests.java index 38c47cb62..f81fcc568 100644 --- a/spring-shell-core/src/test/java/org/springframework/shell/core/command/DefaultCommandParserTests.java +++ b/spring-shell-core/src/test/java/org/springframework/shell/core/command/DefaultCommandParserTests.java @@ -184,39 +184,50 @@ static Stream parseWithQuotedOptionData() { Arguments.of("mycommand --option=\\\"value\\\"", "option", ' ', "\\\"value\\\""), Arguments.of("mycommand --option=\"value\"", "option", ' ', "value"), Arguments.of("mycommand --option=\"value1 value2\"", "option", ' ', "value1 value2"), + Arguments.of("mycommand --option=\"value1=value2\"", "option", ' ', "value1=value2"), Arguments.of("mycommand --option=value1\"inside\"value2", "option", ' ', "value1\"inside\"value2"), Arguments.of("mycommand --option=\"value1 \\\"inside\\\" value2\"", "option", ' ', "value1 \"inside\" value2"), Arguments.of("mycommand --option=value1'inside'value2", "option", ' ', "value1'inside'value2"), Arguments.of("mycommand --option=\"value1 'inside' value2\"", "option", ' ', "value1 'inside' value2"), + Arguments.of("mycommand --option=value", "option", ' ', "value"), + Arguments.of("mycommand --option=\"value\"", "option", ' ', "value"), Arguments.of("mycommand --option value", "option", ' ', "value"), Arguments.of("mycommand --option \\\"value\\\"", "option", ' ', "\\\"value\\\""), Arguments.of("mycommand --option \"value\"", "option", ' ', "value"), Arguments.of("mycommand --option \"value1 value2\"", "option", ' ', "value1 value2"), + Arguments.of("mycommand --option \"value1=value2\"", "option", ' ', "value1=value2"), Arguments.of("mycommand --option value1\"inside\"value2", "option", ' ', "value1\"inside\"value2"), Arguments.of("mycommand --option \"value1 \\\"inside\\\" value2\"", "option", ' ', "value1 \"inside\" value2"), Arguments.of("mycommand --option value1'inside'value2", "option", ' ', "value1'inside'value2"), Arguments.of("mycommand --option \"value1 'inside' value2\"", "option", ' ', "value1 'inside' value2"), + Arguments.of("mycommand --option value", "option", ' ', "value"), + Arguments.of("mycommand --option \"value\"", "option", ' ', "value"), Arguments.of("mycommand -o=value", "", 'o', "value"), Arguments.of("mycommand -o=\\\"value\\\"", "", 'o', "\\\"value\\\""), Arguments.of("mycommand -o=\"value\"", "", 'o', "value"), Arguments.of("mycommand -o=\"value1 value2\"", "", 'o', "value1 value2"), + Arguments.of("mycommand -o=\"value1=value2\"", "", 'o', "value1=value2"), Arguments.of("mycommand -o=value1\"inside\"value2", "", 'o', "value1\"inside\"value2"), Arguments.of("mycommand -o=\"value1 \\\"inside\\\" value2\"", "", 'o', "value1 \"inside\" value2"), Arguments.of("mycommand -o=value1'inside'value2", "", 'o', "value1'inside'value2"), Arguments.of("mycommand -o=\"value1 'inside' value2\"", "", 'o', "value1 'inside' value2"), + Arguments.of("mycommand -o=value", "", 'o', "value"), + Arguments.of("mycommand -o=\"value\"", "", 'o', "value"), Arguments.of("mycommand -o value", "", 'o', "value"), Arguments.of("mycommand -o \\\"value\\\"", "", 'o', "\\\"value\\\""), Arguments.of("mycommand -o \"value\"", "", 'o', "value"), Arguments.of("mycommand -o \"value1 value2\"", "", 'o', "value1 value2"), + Arguments.of("mycommand -o \"value1=value2\"", "", 'o', "value1=value2"), Arguments.of("mycommand -o value1\"inside\"value2", "", 'o', "value1\"inside\"value2"), Arguments.of("mycommand -o \"value1 \\\"inside\\\" value2\"", "", 'o', "value1 \"inside\" value2"), Arguments.of("mycommand -o value1'inside'value2", "", 'o', "value1'inside'value2"), - Arguments.of("mycommand -o \"value1 'inside' value2\"", "", 'o', "value1 'inside' value2")); + Arguments.of("mycommand -o \"value1 'inside' value2\"", "", 'o', "value1 'inside' value2"), + Arguments.of("mycommand -o \"value\"", "", 'o', "value")); } @ParameterizedTest @@ -236,10 +247,12 @@ static Stream parseWithQuotedArgumentData() { Arguments.of("mycommand -- \\\"value\\\"", "\\\"value\\\""), Arguments.of("mycommand -- \"value\"", "value"), Arguments.of("mycommand -- \"value1 value2\"", "value1 value2"), + Arguments.of("mycommand -- \"value1=value2\"", "value1=value2"), Arguments.of("mycommand -- value1\"inside\"value2", "value1\"inside\"value2"), Arguments.of("mycommand -- \"value1 \\\"inside\\\" value2\"", "value1 \"inside\" value2"), Arguments.of("mycommand -- value1'inside'value2", "value1'inside'value2"), - Arguments.of("mycommand -- \"value1 'inside' value2\"", "value1 'inside' value2")); + Arguments.of("mycommand -- \"value1 'inside' value2\"", "value1 'inside' value2"), + Arguments.of("mycommand -- value", "value"), Arguments.of("mycommand -- \"value\"", "value")); } } \ No newline at end of file