Rework command parser
- Previously CommandParser contained parser which was scannerless type of brute force parsing of command line args. - Contract in that old parser wasn't super clear what is its role with caller as it was given options and registration was parsed in a Shell class. - Add completely new parser package which has better model and which will be much easier to modify for future needs. - Change some interfaces around parsing so that we do as much in this new parsing model instead of pre-parsing something in a Shell class. - We also try to move away from using exceptions as a message delivery which had its own problems. Instead introducing parser messages which gives better info when errors are detected. - Add ParserConfig class which allows to expose settings to change some parser features. Later this will be exposed to user so that some features can be turned on/off for an actual shell needs. - Fixes #646
This commit is contained in:
@@ -21,6 +21,8 @@ import java.util.Set;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.shell.command.CommandRegistration;
|
||||
import org.springframework.shell.command.annotation.Command;
|
||||
import org.springframework.shell.command.annotation.Option;
|
||||
import org.springframework.shell.standard.ShellComponent;
|
||||
import org.springframework.shell.standard.ShellMethod;
|
||||
import org.springframework.shell.standard.ShellOption;
|
||||
@@ -107,6 +109,102 @@ public class OptionTypeCommands {
|
||||
}
|
||||
}
|
||||
|
||||
@Command(command = BaseE2ECommands.ANNO, group = BaseE2ECommands.GROUP)
|
||||
public static class Annotation extends BaseE2ECommands {
|
||||
|
||||
@Command(command = "option-type-string")
|
||||
public String optionTypeStringAnnotation(
|
||||
@Option(longNames = "arg1")
|
||||
String arg1
|
||||
) {
|
||||
return "Hello " + arg1;
|
||||
}
|
||||
|
||||
@Command(command = "option-type-boolean")
|
||||
public String optionTypeBooleanAnnotation(
|
||||
@ShellOption()
|
||||
@Option(longNames = "arg1")
|
||||
boolean arg1,
|
||||
@ShellOption(defaultValue = "true")
|
||||
@Option(longNames = "arg2", defaultValue = "true")
|
||||
boolean arg2,
|
||||
@ShellOption(defaultValue = "false")
|
||||
@Option(longNames = "arg3", defaultValue = "false")
|
||||
boolean arg3,
|
||||
@ShellOption()
|
||||
@Option(longNames = "arg4")
|
||||
Boolean arg4,
|
||||
@ShellOption(defaultValue = "true")
|
||||
@Option(longNames = "arg5", defaultValue = "true")
|
||||
Boolean arg5,
|
||||
@ShellOption(defaultValue = "false")
|
||||
@Option(longNames = "arg6", defaultValue = "false")
|
||||
Boolean arg6
|
||||
) {
|
||||
return String.format("Hello arg1=%s arg2=%s arg3=%s arg4=%s arg5=%s arg6=%s", arg1, arg2, arg3, arg4, arg5,
|
||||
arg6);
|
||||
}
|
||||
|
||||
@Command(command = "option-type-integer")
|
||||
public String optionTypeIntegerAnnotation(
|
||||
@Option(longNames = "arg1")
|
||||
int arg1,
|
||||
@Option(longNames = "arg2")
|
||||
Integer arg2
|
||||
) {
|
||||
return String.format("Hello '%s' '%s'", arg1, arg2);
|
||||
}
|
||||
|
||||
@Command(command = "option-type-enum")
|
||||
public String optionTypeEnumAnnotation(
|
||||
@Option(longNames = "arg1")
|
||||
OptionTypeEnum arg1
|
||||
) {
|
||||
return "Hello " + arg1;
|
||||
}
|
||||
|
||||
@Command(command = "option-type-string-array")
|
||||
public String optionTypeStringArrayAnnotation(
|
||||
@Option(longNames = "arg1")
|
||||
String[] arg1
|
||||
) {
|
||||
return "Hello " + stringOfStrings(arg1);
|
||||
}
|
||||
|
||||
@Command(command = "option-type-int-array")
|
||||
public String optionTypeIntArrayAnnotation(
|
||||
@Option(longNames = "arg1")
|
||||
int[] arg1
|
||||
) {
|
||||
return "Hello " + stringOfInts(arg1);
|
||||
}
|
||||
|
||||
@Command(command = "option-type-string-list")
|
||||
public String optionTypeStringListAnnotation(
|
||||
@Option(longNames = "arg1")
|
||||
List<String> arg1
|
||||
) {
|
||||
return "Hello " + arg1;
|
||||
}
|
||||
|
||||
@Command(command = "option-type-string-set")
|
||||
public String optionTypeStringSetAnnotation(
|
||||
@Option(longNames = "arg1")
|
||||
Set<String> arg1
|
||||
) {
|
||||
return "Hello " + arg1;
|
||||
}
|
||||
|
||||
@Command(command = "option-type-string-collection")
|
||||
public String optionTypeStringCollectionAnnotation(
|
||||
@Option(longNames = "arg1")
|
||||
Collection<String> arg1
|
||||
) {
|
||||
return "Hello " + arg1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Component
|
||||
public static class Registration extends BaseE2ECommands {
|
||||
|
||||
|
||||
@@ -17,24 +17,27 @@ package org.springframework.shell.samples.e2e;
|
||||
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
|
||||
import org.springframework.shell.command.annotation.EnableCommand;
|
||||
import org.springframework.shell.samples.AbstractSampleTests;
|
||||
import org.springframework.shell.samples.e2e.OptionTypeCommands.Annotation;
|
||||
import org.springframework.shell.samples.e2e.OptionTypeCommands.LegacyAnnotation;
|
||||
import org.springframework.shell.samples.e2e.OptionTypeCommands.Registration;
|
||||
import org.springframework.shell.test.ShellTestClient.BaseShellSession;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
|
||||
@ContextConfiguration(classes = { LegacyAnnotation.class, Registration.class })
|
||||
@EnableCommand(Annotation.class)
|
||||
class OptionTypeCommandsTests extends AbstractSampleTests {
|
||||
|
||||
@ParameterizedTest
|
||||
@E2ESource(command = "option-type-string --arg1 hi", annox = false)
|
||||
@E2ESource(command = "option-type-string --arg1 hi")
|
||||
void optionTypeString(String command, boolean interactive) {
|
||||
BaseShellSession<?> session = createSession(command, interactive);
|
||||
assertScreenContainsText(session, "Hello hi");
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@E2ESource(command = "option-type-boolean", annox = false, reg = false)
|
||||
@E2ESource(command = "option-type-boolean", reg = false)
|
||||
void optionTypeBooleanWithAnno(String command, boolean interactive) {
|
||||
BaseShellSession<?> session = createSession(command, interactive);
|
||||
assertScreenContainsText(session, "Hello arg1=false arg2=true arg3=false arg4=false arg5=true arg6=false");
|
||||
@@ -48,49 +51,49 @@ class OptionTypeCommandsTests extends AbstractSampleTests {
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@E2ESource(command = "option-type-integer --arg1 1 --arg2 2", annox = false)
|
||||
@E2ESource(command = "option-type-integer --arg1 1 --arg2 2")
|
||||
void optionTypeInteger(String command, boolean interactive) {
|
||||
BaseShellSession<?> session = createSession(command, interactive);
|
||||
assertScreenContainsText(session, "Hello '1' '2'");
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@E2ESource(command = "option-type-enum --arg1 ONE", annox = false)
|
||||
@E2ESource(command = "option-type-enum --arg1 ONE")
|
||||
void optionTypeEnum(String command, boolean interactive) {
|
||||
BaseShellSession<?> session = createSession(command, interactive);
|
||||
assertScreenContainsText(session, "Hello ONE");
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@E2ESource(command = "option-type-string-array --arg1 one two", annox = false)
|
||||
@E2ESource(command = "option-type-string-array --arg1 one two")
|
||||
void optionTypeStringArray(String command, boolean interactive) {
|
||||
BaseShellSession<?> session = createSession(command, interactive);
|
||||
assertScreenContainsText(session, "Hello [one,two]");
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@E2ESource(command = "option-type-int-array --arg1 1 2", annox = false)
|
||||
@E2ESource(command = "option-type-int-array --arg1 1 2")
|
||||
void optionTypeIntArray(String command, boolean interactive) {
|
||||
BaseShellSession<?> session = createSession(command, interactive);
|
||||
assertScreenContainsText(session, "Hello [1,2]");
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@E2ESource(command = "option-type-string-list --arg1 one two", annox = false)
|
||||
@E2ESource(command = "option-type-string-list --arg1 one two")
|
||||
void optionTypeStringList(String command, boolean interactive) {
|
||||
BaseShellSession<?> session = createSession(command, interactive);
|
||||
assertScreenContainsText(session, "Hello [one, two]");
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@E2ESource(command = "option-type-string-set --arg1 one two", annox = false)
|
||||
@E2ESource(command = "option-type-string-set --arg1 one two")
|
||||
void optionTypeStringSet(String command, boolean interactive) {
|
||||
BaseShellSession<?> session = createSession(command, interactive);
|
||||
assertScreenContainsText(session, "Hello [one, two]");
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@E2ESource(command = "option-type-string-collection --arg1 one two", annox = false)
|
||||
@E2ESource(command = "option-type-string-collection --arg1 one two")
|
||||
void optionTypeStringCollection(String command, boolean interactive) {
|
||||
BaseShellSession<?> session = createSession(command, interactive);
|
||||
assertScreenContainsText(session, "Hello [one, two]");
|
||||
|
||||
Reference in New Issue
Block a user