Merge pull request #28138 from vignesh1992
* pr/28138: Polish 'Support both kebab-case and camelCase as Spring init CLI Options' Support both kebab-case and camelCase as Spring init CLI Options Closes gh-28138
This commit is contained in:
@@ -20,7 +20,10 @@ import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import joptsimple.OptionSet;
|
||||
import joptsimple.OptionSpec;
|
||||
@@ -38,6 +41,7 @@ import org.springframework.util.Assert;
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @author Eddú Meléndez
|
||||
* @author Vignesh Thangavel Ilangovan
|
||||
* @since 1.2.0
|
||||
*/
|
||||
public class InitCommand extends OptionParsingCommand {
|
||||
@@ -71,6 +75,21 @@ public class InitCommand extends OptionParsingCommand {
|
||||
*/
|
||||
static class InitOptionHandler extends OptionHandler {
|
||||
|
||||
/**
|
||||
* Mapping from camelCase options advertised by the service to our kebab-case
|
||||
* options.
|
||||
*/
|
||||
private static final Map<String, String> CAMEL_CASE_OPTIONS;
|
||||
static {
|
||||
Map<String, String> options = new HashMap<>();
|
||||
options.put("--groupId", "--group-id");
|
||||
options.put("--artifactId", "--artifact-id");
|
||||
options.put("--packageName", "--package-name");
|
||||
options.put("--javaVersion", "--java-version");
|
||||
options.put("--bootVersion", "--boot-version");
|
||||
CAMEL_CASE_OPTIONS = Collections.unmodifiableMap(options);
|
||||
}
|
||||
|
||||
private final ServiceCapabilitiesReportGenerator serviceCapabilitiesReport;
|
||||
|
||||
private final ProjectGenerator projectGenerator;
|
||||
@@ -112,9 +131,9 @@ public class InitCommand extends OptionParsingCommand {
|
||||
private OptionSpec<Void> force;
|
||||
|
||||
InitOptionHandler(InitializrService initializrService) {
|
||||
super(InitOptionHandler::processArgument);
|
||||
this.serviceCapabilitiesReport = new ServiceCapabilitiesReportGenerator(initializrService);
|
||||
this.projectGenerator = new ProjectGenerator(initializrService);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -129,15 +148,15 @@ public class InitCommand extends OptionParsingCommand {
|
||||
}
|
||||
|
||||
private void projectGenerationOptions() {
|
||||
this.groupId = option(Arrays.asList("groupId", "g"), "Project coordinates (for example 'org.test')")
|
||||
this.groupId = option(Arrays.asList("group-id", "g"), "Project coordinates (for example 'org.test')")
|
||||
.withRequiredArg();
|
||||
this.artifactId = option(Arrays.asList("artifactId", "a"),
|
||||
this.artifactId = option(Arrays.asList("artifact-id", "a"),
|
||||
"Project coordinates; infer archive name (for example 'test')").withRequiredArg();
|
||||
this.version = option(Arrays.asList("version", "v"), "Project version (for example '0.0.1-SNAPSHOT')")
|
||||
.withRequiredArg();
|
||||
this.name = option(Arrays.asList("name", "n"), "Project name; infer application name").withRequiredArg();
|
||||
this.description = option("description", "Project description").withRequiredArg();
|
||||
this.packageName = option("package-name", "Package name").withRequiredArg();
|
||||
this.packageName = option(Arrays.asList("package-name"), "Package name").withRequiredArg();
|
||||
this.type = option(Arrays.asList("type", "t"),
|
||||
"Project type. Not normally needed if you use --build "
|
||||
+ "and/or --format. Check the capabilities of the service (--list) for more details")
|
||||
@@ -249,6 +268,16 @@ public class InitCommand extends OptionParsingCommand {
|
||||
return request;
|
||||
}
|
||||
|
||||
private static String processArgument(String argument) {
|
||||
for (Map.Entry<String, String> entry : CAMEL_CASE_OPTIONS.entrySet()) {
|
||||
String name = entry.getKey();
|
||||
if (argument.startsWith(name + " ") || argument.startsWith(name + "=")) {
|
||||
return entry.getValue() + argument.substring(name.length());
|
||||
}
|
||||
}
|
||||
return argument;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
import java.util.function.Function;
|
||||
|
||||
import joptsimple.BuiltinHelpFormatter;
|
||||
import joptsimple.HelpFormatter;
|
||||
@@ -49,12 +50,30 @@ import org.springframework.boot.cli.command.status.ExitStatus;
|
||||
*/
|
||||
public class OptionHandler {
|
||||
|
||||
private final Function<String, String> argumentProcessor;
|
||||
|
||||
private OptionParser parser;
|
||||
|
||||
private String help;
|
||||
|
||||
private Collection<OptionHelp> optionHelp;
|
||||
|
||||
/**
|
||||
* Create a new {@link OptionHandler} instance.
|
||||
*/
|
||||
public OptionHandler() {
|
||||
this(Function.identity());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@link OptionHandler} instance with an argument processor.
|
||||
* @param argumentProcessor strategy that can be used to manipulate arguments before
|
||||
* they are used.
|
||||
*/
|
||||
public OptionHandler(Function<String, String> argumentProcessor) {
|
||||
this.argumentProcessor = argumentProcessor;
|
||||
}
|
||||
|
||||
public OptionSpecBuilder option(String name, String description) {
|
||||
return getParser().accepts(name, description);
|
||||
}
|
||||
@@ -80,6 +99,7 @@ public class OptionHandler {
|
||||
if ("-cp".equals(argsToUse[i])) {
|
||||
argsToUse[i] = "--cp";
|
||||
}
|
||||
argsToUse[i] = this.argumentProcessor.apply(argsToUse[i]);
|
||||
}
|
||||
OptionSet options = getParser().parse(argsToUse);
|
||||
return run(options);
|
||||
|
||||
@@ -44,6 +44,7 @@ import static org.mockito.Mockito.verify;
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @author Eddú Meléndez
|
||||
* @author Vignesh Thangavel Ilangovan
|
||||
*/
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class InitCommandTests extends AbstractHttpClientMockTests {
|
||||
@@ -272,6 +273,58 @@ class InitCommandTests extends AbstractHttpClientMockTests {
|
||||
assertThat(dependencies.contains("data-jpa")).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void parseProjectWithCamelCaseOptions() throws Exception {
|
||||
this.handler.disableProjectGeneration();
|
||||
this.command.run("--groupId=org.demo", "--artifactId=acme", "--version=1.2.3-SNAPSHOT", "--name=acme-sample",
|
||||
"--description=Acme sample project", "--packageName=demo.foo", "--type=ant-project", "--build=grunt",
|
||||
"--format=web", "--packaging=war", "--javaVersion=1.9", "--language=groovy",
|
||||
"--bootVersion=1.2.0.RELEASE", "--dependencies=web,data-jpa");
|
||||
assertThat(this.handler.lastRequest.getGroupId()).isEqualTo("org.demo");
|
||||
assertThat(this.handler.lastRequest.getArtifactId()).isEqualTo("acme");
|
||||
assertThat(this.handler.lastRequest.getVersion()).isEqualTo("1.2.3-SNAPSHOT");
|
||||
assertThat(this.handler.lastRequest.getName()).isEqualTo("acme-sample");
|
||||
assertThat(this.handler.lastRequest.getDescription()).isEqualTo("Acme sample project");
|
||||
assertThat(this.handler.lastRequest.getPackageName()).isEqualTo("demo.foo");
|
||||
assertThat(this.handler.lastRequest.getType()).isEqualTo("ant-project");
|
||||
assertThat(this.handler.lastRequest.getBuild()).isEqualTo("grunt");
|
||||
assertThat(this.handler.lastRequest.getFormat()).isEqualTo("web");
|
||||
assertThat(this.handler.lastRequest.getPackaging()).isEqualTo("war");
|
||||
assertThat(this.handler.lastRequest.getJavaVersion()).isEqualTo("1.9");
|
||||
assertThat(this.handler.lastRequest.getLanguage()).isEqualTo("groovy");
|
||||
assertThat(this.handler.lastRequest.getBootVersion()).isEqualTo("1.2.0.RELEASE");
|
||||
List<String> dependencies = this.handler.lastRequest.getDependencies();
|
||||
assertThat(dependencies).hasSize(2);
|
||||
assertThat(dependencies.contains("web")).isTrue();
|
||||
assertThat(dependencies.contains("data-jpa")).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void parseProjectWithKebabCaseOptions() throws Exception {
|
||||
this.handler.disableProjectGeneration();
|
||||
this.command.run("--group-id=org.demo", "--artifact-id=acme", "--version=1.2.3-SNAPSHOT", "--name=acme-sample",
|
||||
"--description=Acme sample project", "--package-name=demo.foo", "--type=ant-project", "--build=grunt",
|
||||
"--format=web", "--packaging=war", "--java-version=1.9", "--language=groovy",
|
||||
"--boot-version=1.2.0.RELEASE", "--dependencies=web,data-jpa");
|
||||
assertThat(this.handler.lastRequest.getGroupId()).isEqualTo("org.demo");
|
||||
assertThat(this.handler.lastRequest.getArtifactId()).isEqualTo("acme");
|
||||
assertThat(this.handler.lastRequest.getVersion()).isEqualTo("1.2.3-SNAPSHOT");
|
||||
assertThat(this.handler.lastRequest.getName()).isEqualTo("acme-sample");
|
||||
assertThat(this.handler.lastRequest.getDescription()).isEqualTo("Acme sample project");
|
||||
assertThat(this.handler.lastRequest.getPackageName()).isEqualTo("demo.foo");
|
||||
assertThat(this.handler.lastRequest.getType()).isEqualTo("ant-project");
|
||||
assertThat(this.handler.lastRequest.getBuild()).isEqualTo("grunt");
|
||||
assertThat(this.handler.lastRequest.getFormat()).isEqualTo("web");
|
||||
assertThat(this.handler.lastRequest.getPackaging()).isEqualTo("war");
|
||||
assertThat(this.handler.lastRequest.getJavaVersion()).isEqualTo("1.9");
|
||||
assertThat(this.handler.lastRequest.getLanguage()).isEqualTo("groovy");
|
||||
assertThat(this.handler.lastRequest.getBootVersion()).isEqualTo("1.2.0.RELEASE");
|
||||
List<String> dependencies = this.handler.lastRequest.getDependencies();
|
||||
assertThat(dependencies).hasSize(2);
|
||||
assertThat(dependencies.contains("web")).isTrue();
|
||||
assertThat(dependencies.contains("data-jpa")).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void overwriteFileInArchive(@TempDir File tempDir) throws Exception {
|
||||
File conflict = new File(tempDir, "test.txt");
|
||||
|
||||
Reference in New Issue
Block a user