Revisit posix short handling in Lexer
- Posix short style is expected to have only single dash and letters so use this style to come up better separation between options and arguments. - Backport #1077 - Fixes #1078
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2023 the original author or authors.
|
||||
* Copyright 2023-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.
|
||||
@@ -201,12 +201,17 @@ public interface Lexer {
|
||||
}
|
||||
}
|
||||
else if (isLastTokenOfType(tokenList, TokenType.OPTION)) {
|
||||
if (argument.startsWith("-")) {
|
||||
// posix short style can only have one or more letters
|
||||
int decuceArgumentStyle = decuceArgumentStyle(argument);
|
||||
if (decuceArgumentStyle > 0) {
|
||||
tokenList.add(Token.of(argument, TokenType.OPTION, i2));
|
||||
}
|
||||
else {
|
||||
else if (decuceArgumentStyle < 0) {
|
||||
tokenList.add(Token.of(argument, TokenType.ARGUMENT, i2));
|
||||
}
|
||||
else {
|
||||
tokenList.add(Token.of(argument, TokenType.OPTION, i2));
|
||||
}
|
||||
}
|
||||
else if (isLastTokenOfType(tokenList, TokenType.COMMAND)) {
|
||||
if (argument.startsWith("-")) {
|
||||
@@ -243,5 +248,28 @@ public interface Lexer {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static int decuceArgumentStyle(String str) {
|
||||
// positive - looks like posix short
|
||||
// 0 - looks like long option
|
||||
// negative - looks like argument, not option
|
||||
if (str.length() < 2) {
|
||||
return -1;
|
||||
}
|
||||
if (str.charAt(0) != '-') {
|
||||
return -1;
|
||||
}
|
||||
if (str.length() > 1 && str.charAt(0) == '-' && str.charAt(1) == '-') {
|
||||
return 0;
|
||||
}
|
||||
int ret = 1;
|
||||
for (int i = 1; i < str.length(); i++) {
|
||||
if (!Character.isLetter(str.charAt(i))) {
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2023 the original author or authors.
|
||||
* Copyright 2023-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.
|
||||
@@ -19,6 +19,8 @@ import java.util.List;
|
||||
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
|
||||
import org.springframework.shell.command.parser.Lexer.LexerResult;
|
||||
import org.springframework.shell.command.parser.ParserConfig.Feature;
|
||||
@@ -431,6 +433,42 @@ class LexerTests extends AbstractParsingTests {
|
||||
TokenType.ARGUMENT);
|
||||
}
|
||||
|
||||
@Nested
|
||||
class ShortOptions {
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = {
|
||||
"-1",
|
||||
"-1a",
|
||||
"-a1",
|
||||
"-ab1",
|
||||
"-ab1c"
|
||||
})
|
||||
void shouldNotBeOptionWhenDoesntLookLikeShortPosix(String arg) {
|
||||
register(ROOT6_OPTION_INT);
|
||||
List<Token> tokens = tokenize("root6", "--arg1", arg);
|
||||
|
||||
assertThat(tokens).extracting(Token::getType).containsExactly(TokenType.COMMAND, TokenType.OPTION,
|
||||
TokenType.ARGUMENT);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = {
|
||||
"-a",
|
||||
"-ab",
|
||||
"-abc",
|
||||
"--abc"
|
||||
})
|
||||
void shouldBeOptionWhenLooksLikeShortPosix(String arg) {
|
||||
register(ROOT6_OPTION_INT);
|
||||
List<Token> tokens = tokenize("root6", "--arg1", arg);
|
||||
|
||||
assertThat(tokens).extracting(Token::getType).containsExactly(TokenType.COMMAND, TokenType.OPTION,
|
||||
TokenType.OPTION);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Nested
|
||||
class Directives {
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2023 the original author or authors.
|
||||
* Copyright 2023-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.
|
||||
@@ -116,6 +116,18 @@ class ParserTests extends AbstractParsingTests {
|
||||
assertThat(ms.getMessage()).contains("Failed to convert");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void optionValueShouldBeNegativeInteger() {
|
||||
register(ROOT6_OPTION_INT);
|
||||
ParseResult result = parse("root6", "--arg1", "-1");
|
||||
assertThat(result).isNotNull();
|
||||
assertThat(result.commandRegistration()).isNotNull();
|
||||
assertThat(result.optionResults()).isNotEmpty();
|
||||
assertThat(result.optionResults().get(0).value()).isEqualTo(-1);
|
||||
assertThat(result.messageResults()).isEmpty();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Nested
|
||||
|
||||
Reference in New Issue
Block a user