Init command takes the output as last argument
This commit moves the --output switch to a regular argument. This aligns to other command, i.e. spring init my-project.zip would save the project to "my-project.zip" in the current directory. This commit also auto-detects the --extract option if the location ends with a slash, i.e. spring init demo/ would extract the content of the project in a demo directory that is local to the current directory. Fixes gh-1802
This commit is contained in:
@@ -17,7 +17,9 @@
|
||||
package org.springframework.boot.cli.command.init;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import joptsimple.OptionSet;
|
||||
import joptsimple.OptionSpec;
|
||||
@@ -27,6 +29,7 @@ import org.springframework.boot.cli.command.OptionParsingCommand;
|
||||
import org.springframework.boot.cli.command.options.OptionHandler;
|
||||
import org.springframework.boot.cli.command.status.ExitStatus;
|
||||
import org.springframework.boot.cli.util.Log;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* {@link Command} that initializes a project using Spring initializr.
|
||||
@@ -45,6 +48,11 @@ public class InitCommand extends OptionParsingCommand {
|
||||
+ "Initialzr (start.spring.io)", handler);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUsageHelp() {
|
||||
return "[options] [location]";
|
||||
}
|
||||
|
||||
static class InitOptionHandler extends OptionHandler {
|
||||
|
||||
private final ServiceCapabilitiesReportGenerator serviceCapabilitiesReport;
|
||||
@@ -73,8 +81,6 @@ public class InitCommand extends OptionParsingCommand {
|
||||
|
||||
private OptionSpec<Void> force;
|
||||
|
||||
private OptionSpec<String> output;
|
||||
|
||||
InitOptionHandler(InitializrService initializrService) {
|
||||
this.serviceCapabilitiesReport = new ServiceCapabilitiesReportGenerator(
|
||||
initializrService);
|
||||
@@ -123,14 +129,9 @@ public class InitCommand extends OptionParsingCommand {
|
||||
|
||||
private void otherOptions() {
|
||||
this.extract = option(Arrays.asList("extract", "x"),
|
||||
"Extract the project archive");
|
||||
"Extract the project archive. Inferred if a location is specified and ends with /");
|
||||
this.force = option(Arrays.asList("force", "f"),
|
||||
"Force overwrite of existing files");
|
||||
this.output = option(
|
||||
Arrays.asList("output", "o"),
|
||||
"Location of the generated project. Can be an absolute or a "
|
||||
+ "relative reference and should refer to a directory when "
|
||||
+ "--extract is used").withRequiredArg();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -160,12 +161,17 @@ public class InitCommand extends OptionParsingCommand {
|
||||
|
||||
protected void generateProject(OptionSet options) throws IOException {
|
||||
ProjectGenerationRequest request = createProjectGenerationRequest(options);
|
||||
this.projectGenerator.generateProject(request, options.has(this.force),
|
||||
options.has(this.extract), options.valueOf(this.output));
|
||||
this.projectGenerator.generateProject(request, options.has(this.force));
|
||||
}
|
||||
|
||||
protected ProjectGenerationRequest createProjectGenerationRequest(
|
||||
OptionSet options) {
|
||||
|
||||
List<?> nonOptionArguments = new ArrayList<Object>(
|
||||
options.nonOptionArguments());
|
||||
Assert.isTrue(nonOptionArguments.size() <= 1,
|
||||
"Only the target location may be specified");
|
||||
|
||||
ProjectGenerationRequest request = new ProjectGenerationRequest();
|
||||
request.setServiceUrl(options.valueOf(this.target));
|
||||
if (options.has(this.bootVersion)) {
|
||||
@@ -188,8 +194,10 @@ public class InitCommand extends OptionParsingCommand {
|
||||
if (options.has(this.type)) {
|
||||
request.setType(options.valueOf(this.type));
|
||||
}
|
||||
if (options.has(this.output)) {
|
||||
request.setOutput(options.valueOf(this.output));
|
||||
request.setExtract(options.has(this.extract));
|
||||
if (nonOptionArguments.size() == 1) {
|
||||
String output = (String) nonOptionArguments.get(0);
|
||||
request.setOutput(output);
|
||||
}
|
||||
return request;
|
||||
}
|
||||
|
||||
@@ -40,6 +40,8 @@ class ProjectGenerationRequest {
|
||||
|
||||
private String output;
|
||||
|
||||
private boolean extract;
|
||||
|
||||
private String bootVersion;
|
||||
|
||||
private List<String> dependencies = new ArrayList<String>();
|
||||
@@ -76,7 +78,25 @@ class ProjectGenerationRequest {
|
||||
}
|
||||
|
||||
public void setOutput(String output) {
|
||||
this.output = output;
|
||||
if (output != null && output.endsWith("/")) {
|
||||
this.output = output.substring(0, output.length() - 1);
|
||||
this.extract = true;
|
||||
} else {
|
||||
this.output = output;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify if the project archive should be extract in the output location. If
|
||||
* the {@link #getOutput() output} ends with "/", the project is extracted
|
||||
* automatically.
|
||||
*/
|
||||
public boolean isExtract() {
|
||||
return extract;
|
||||
}
|
||||
|
||||
public void setExtract(boolean extract) {
|
||||
this.extract = extract;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -41,24 +41,23 @@ public class ProjectGenerator {
|
||||
this.initializrService = initializrService;
|
||||
}
|
||||
|
||||
public void generateProject(ProjectGenerationRequest request, boolean force,
|
||||
boolean extract, String output) throws IOException {
|
||||
public void generateProject(ProjectGenerationRequest request, boolean force) throws IOException {
|
||||
ProjectGenerationResponse response = this.initializrService.generate(request);
|
||||
if (extract) {
|
||||
String fileName = (request.getOutput() != null ? request.getOutput() : response.getFileName());
|
||||
if (request.isExtract()) {
|
||||
if (isZipArchive(response)) {
|
||||
extractProject(response, output, force);
|
||||
extractProject(response, request.getOutput(), force);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
Log.info("Could not extract '" + response.getContentType() + "'");
|
||||
fileName = response.getFileName(); // Use value from the server since we can't extract it
|
||||
}
|
||||
}
|
||||
String fileName = response.getFileName();
|
||||
fileName = (fileName != null ? fileName : output);
|
||||
if (fileName == null) {
|
||||
throw new ReportableException(
|
||||
"Could not save the project, the server did not set a preferred "
|
||||
+ "file name. Use --output to specify the output location "
|
||||
+ "file name and no location was set. Specify the output location "
|
||||
+ "for the project.");
|
||||
}
|
||||
writeProject(response, fileName, force);
|
||||
@@ -102,7 +101,7 @@ public class ProjectGenerator {
|
||||
throw new ReportableException(file.isDirectory() ? "Directory" : "File"
|
||||
+ " '" + file.getName()
|
||||
+ "' already exists. Use --force if you want to overwrite or "
|
||||
+ "--output to specify an alternate location.");
|
||||
+ "specify an alternate location.");
|
||||
}
|
||||
if (!entry.isDirectory()) {
|
||||
FileCopyUtils.copy(StreamUtils.nonClosing(zipStream),
|
||||
@@ -123,7 +122,7 @@ public class ProjectGenerator {
|
||||
if (!overwrite) {
|
||||
throw new ReportableException("File '" + outputFile.getName()
|
||||
+ "' already exists. Use --force if you want to "
|
||||
+ "overwrite or --output to specify an alternate location.");
|
||||
+ "overwrite or specify an alternate location.");
|
||||
}
|
||||
if (!outputFile.delete()) {
|
||||
throw new ReportableException("Failed to delete existing file "
|
||||
|
||||
Reference in New Issue
Block a user