Handle arg looking options better
- Now lexing better with valid options - Only report unrecognised option with double dash as current parser don't have structure to do deeper analysis. - Fixes #651
This commit is contained in:
@@ -22,6 +22,7 @@ import java.util.Collections;
|
|||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.Deque;
|
import java.util.Deque;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
@@ -213,7 +214,15 @@ public interface CommandParser {
|
|||||||
.filter(o -> o.isRequired())
|
.filter(o -> o.isRequired())
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
Lexer lexer = new Lexer(args);
|
Set<String> splitValidValues = options.stream()
|
||||||
|
.flatMap(o -> {
|
||||||
|
Stream<String> longs = Stream.of(o.getLongNames()).map(l -> "--" + l);
|
||||||
|
Stream<String> shorts = Stream.of(o.getShortNames()).map(s -> "-"+ Character.toString(s));
|
||||||
|
return Stream.concat(longs, shorts);
|
||||||
|
})
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
|
||||||
|
Lexer lexer = new Lexer(args, splitValidValues);
|
||||||
List<List<String>> lexerResults = lexer.visit();
|
List<List<String>> lexerResults = lexer.visit();
|
||||||
Parser parser = new Parser();
|
Parser parser = new Parser();
|
||||||
ParserResults parserResults = parser.visit(lexerResults, options);
|
ParserResults parserResults = parser.visit(lexerResults, options);
|
||||||
@@ -228,7 +237,7 @@ public interface CommandParser {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
for (String arg : pr.args) {
|
for (String arg : pr.args) {
|
||||||
if (arg.startsWith("-")) {
|
if (arg.startsWith("--")) {
|
||||||
errors.add(UnrecognisedOptionException.of(String.format("Unrecognised option '%s'", arg),
|
errors.add(UnrecognisedOptionException.of(String.format("Unrecognised option '%s'", arg),
|
||||||
arg));
|
arg));
|
||||||
}
|
}
|
||||||
@@ -520,11 +529,13 @@ public interface CommandParser {
|
|||||||
*/
|
*/
|
||||||
private static class Lexer {
|
private static class Lexer {
|
||||||
private final String[] args;
|
private final String[] args;
|
||||||
Lexer(String[] args) {
|
private final Set<String> splitValidValues;
|
||||||
|
Lexer(String[] args, Set<String> splitValues) {
|
||||||
this.args = args;
|
this.args = args;
|
||||||
|
this.splitValidValues = splitValues;
|
||||||
}
|
}
|
||||||
List<List<String>> visit() {
|
List<List<String>> visit() {
|
||||||
return Utils.split(args, t -> t.startsWith("-"));
|
return Utils.split(args, t -> splitValidValues.contains(t));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,8 +26,10 @@ import org.springframework.core.ResolvableType;
|
|||||||
import org.springframework.core.convert.ConversionService;
|
import org.springframework.core.convert.ConversionService;
|
||||||
import org.springframework.core.convert.support.DefaultConversionService;
|
import org.springframework.core.convert.support.DefaultConversionService;
|
||||||
import org.springframework.shell.command.CommandParser.CommandParserResults;
|
import org.springframework.shell.command.CommandParser.CommandParserResults;
|
||||||
|
import org.springframework.shell.command.CommandParser.MissingOptionException;
|
||||||
import org.springframework.shell.command.CommandParser.NotEnoughArgumentsOptionException;
|
import org.springframework.shell.command.CommandParser.NotEnoughArgumentsOptionException;
|
||||||
import org.springframework.shell.command.CommandParser.TooManyArgumentsOptionException;
|
import org.springframework.shell.command.CommandParser.TooManyArgumentsOptionException;
|
||||||
|
import org.springframework.shell.command.CommandParser.UnrecognisedOptionException;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
@@ -496,6 +498,11 @@ public class CommandParserTests extends AbstractCommandTests {
|
|||||||
CommandParserResults results = parser.parse(options, args);
|
CommandParserResults results = parser.parse(options, args);
|
||||||
assertThat(results.results()).hasSize(0);
|
assertThat(results.results()).hasSize(0);
|
||||||
assertThat(results.errors()).hasSize(1);
|
assertThat(results.errors()).hasSize(1);
|
||||||
|
assertThat(results.errors()).satisfiesExactly(
|
||||||
|
e -> {
|
||||||
|
assertThat(e).isInstanceOf(UnrecognisedOptionException.class);
|
||||||
|
}
|
||||||
|
);
|
||||||
assertThat(results.positional()).hasSize(1);
|
assertThat(results.positional()).hasSize(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -508,6 +515,11 @@ public class CommandParserTests extends AbstractCommandTests {
|
|||||||
CommandParserResults results = parser.parse(options, args);
|
CommandParserResults results = parser.parse(options, args);
|
||||||
assertThat(results.results()).hasSize(1);
|
assertThat(results.results()).hasSize(1);
|
||||||
assertThat(results.errors()).hasSize(1);
|
assertThat(results.errors()).hasSize(1);
|
||||||
|
assertThat(results.errors()).satisfiesExactly(
|
||||||
|
e -> {
|
||||||
|
assertThat(e).isInstanceOf(UnrecognisedOptionException.class);
|
||||||
|
}
|
||||||
|
);
|
||||||
assertThat(results.positional()).hasSize(1);
|
assertThat(results.positional()).hasSize(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -520,9 +532,29 @@ public class CommandParserTests extends AbstractCommandTests {
|
|||||||
CommandParserResults results = parser.parse(options, args);
|
CommandParserResults results = parser.parse(options, args);
|
||||||
assertThat(results.results()).hasSize(0);
|
assertThat(results.results()).hasSize(0);
|
||||||
assertThat(results.errors()).hasSize(2);
|
assertThat(results.errors()).hasSize(2);
|
||||||
|
assertThat(results.errors()).satisfiesExactly(
|
||||||
|
e -> {
|
||||||
|
assertThat(e).isInstanceOf(UnrecognisedOptionException.class);
|
||||||
|
},
|
||||||
|
e -> {
|
||||||
|
assertThat(e).isInstanceOf(MissingOptionException.class);
|
||||||
|
}
|
||||||
|
);
|
||||||
assertThat(results.positional()).hasSize(1);
|
assertThat(results.positional()).hasSize(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDashOptionValueDoNotError() {
|
||||||
|
// gh-651
|
||||||
|
CommandOption option1 = longOption("arg1");
|
||||||
|
List<CommandOption> options = Arrays.asList(option1);
|
||||||
|
String[] args = new String[]{"--arg1", "-1"};
|
||||||
|
CommandParserResults results = parser.parse(options, args);
|
||||||
|
assertThat(results.results()).hasSize(1);
|
||||||
|
assertThat(results.errors()).hasSize(0);
|
||||||
|
assertThat(results.positional()).hasSize(0);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPositionDoesNotAffectRequiredErrorWithOtherErrors() {
|
public void testPositionDoesNotAffectRequiredErrorWithOtherErrors() {
|
||||||
// gh-601
|
// gh-601
|
||||||
|
|||||||
Reference in New Issue
Block a user