Switch to Ant lib for tar/zip tasks

The commons wrapper we were using didn't support executable files
so Ant seems like the best choice ultimately, even if it has a
lot of features we don't use or need.
This commit is contained in:
Dave Syer
2017-02-20 11:20:09 +00:00
committed by Stephane Nicoll
parent 09fc98ef96
commit 06f314dc8c
11 changed files with 131 additions and 58 deletions

View File

@@ -52,11 +52,6 @@
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.rauschig</groupId>
<artifactId>jarchivelib</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.spring.initializr</groupId>
<artifactId>initializr-web</artifactId>

0
initializr-generator/src/main/resources/project/gradle/gradlew.bat vendored Normal file → Executable file
View File

0
initializr-generator/src/main/resources/project/gradle3/gradlew.bat vendored Normal file → Executable file
View File

0
initializr-generator/src/main/resources/project/maven/mvnw vendored Normal file → Executable file
View File

0
initializr-generator/src/main/resources/project/maven/mvnw.cmd vendored Normal file → Executable file
View File

View File

@@ -217,6 +217,13 @@ public class ProjectAssert {
return this;
}
public ProjectAssert hasExecutableFile(String... localPaths) {
for (String localPath : localPaths) {
assertFile(localPath, true);
}
return this;
}
public ProjectAssert hasNoFile(String... localPaths) {
for (String localPath : localPaths) {
assertFile(localPath, false);
@@ -231,6 +238,13 @@ public class ProjectAssert {
return this;
}
public ProjectAssert assertExecutableFile(String localPath, boolean executable) {
File candidate = file(localPath);
assertEquals("Invalid (\"" + executable + "\") for " + localPath, executable,
candidate.exists() && candidate.canExecute());
return this;
}
private File file(String localPath) {
return new File(dir, localPath);
}

View File

@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
@@ -38,8 +37,14 @@
<artifactId>caffeine</artifactId>
</dependency>
<dependency>
<groupId>org.rauschig</groupId>
<artifactId>jarchivelib</artifactId>
<groupId>org.apache.ant</groupId>
<artifactId>ant</artifactId>
<exclusions>
<exclusion>
<groupId>org.apache.ant</groupId>
<artifactId>ant-launcher</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.json</groupId>

View File

@@ -16,6 +16,10 @@
package io.spring.initializr.web.project;
import static io.spring.initializr.util.Agent.AgentId.CURL;
import static io.spring.initializr.util.Agent.AgentId.HTTPIE;
import static io.spring.initializr.util.Agent.AgentId.SPRING_BOOT_CLI;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
@@ -25,7 +29,31 @@ import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.Tar;
import org.apache.tools.ant.taskdefs.Tar.TarCompressionMethod;
import org.apache.tools.ant.taskdefs.Tar.TarFileSet;
import org.apache.tools.ant.taskdefs.Zip;
import org.apache.tools.ant.types.ZipFileSet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.CacheControl;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.ResponseEntity.BodyBuilder;
import org.springframework.stereotype.Controller;
import org.springframework.util.DigestUtils;
import org.springframework.util.StreamUtils;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.resource.ResourceUrlProvider;
import com.samskivert.mustache.Mustache;
import io.spring.initializr.generator.BasicProjectRequest;
import io.spring.initializr.generator.CommandLineHelpGenerator;
import io.spring.initializr.generator.ProjectGenerator;
@@ -42,28 +70,6 @@ import io.spring.initializr.web.mapper.InitializrMetadataJsonMapper;
import io.spring.initializr.web.mapper.InitializrMetadataV21JsonMapper;
import io.spring.initializr.web.mapper.InitializrMetadataV2JsonMapper;
import io.spring.initializr.web.mapper.InitializrMetadataVersion;
import org.rauschig.jarchivelib.ArchiverFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.CacheControl;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.ResponseEntity.BodyBuilder;
import org.springframework.stereotype.Controller;
import org.springframework.util.DigestUtils;
import org.springframework.util.StreamUtils;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.resource.ResourceUrlProvider;
import static io.spring.initializr.util.Agent.AgentId.CURL;
import static io.spring.initializr.util.Agent.AgentId.HTTPIE;
import static io.spring.initializr.util.Agent.AgentId.SPRING_BOOT_CLI;
/**
* The main initializr controller provides access to the configured metadata and serves as
@@ -257,10 +263,24 @@ public class MainController extends AbstractInitializrController {
File download = projectGenerator.createDistributionFile(dir, ".zip");
String wrapperScript = getWrapperScript(request);
// TODO: file mode 755 for wrapper script?
ArchiverFactory.createArchiver("zip").create(download.getName(),
download.getCanonicalFile().getParentFile(), dir);
new File(dir, wrapperScript).setExecutable(true);
Zip zip = new Zip();
zip.setProject(new Project());
zip.setDefaultexcludes(false);
ZipFileSet set = new ZipFileSet();
set.setDir(dir);
set.setFileMode("755");
set.setIncludes(wrapperScript);
set.setDefaultexcludes(false);
zip.addFileset(set);
set = new ZipFileSet();
set.setDir(dir);
set.setIncludes("**,");
set.setExcludes(wrapperScript);
set.setDefaultexcludes(false);
zip.addFileset(set);
zip.setDestFile(download.getCanonicalFile());
zip.execute();
return upload(download, dir, generateFileName(request, "zip"), "application/zip");
}
@@ -274,10 +294,25 @@ public class MainController extends AbstractInitializrController {
File download = projectGenerator.createDistributionFile(dir, ".tar.gz");
String wrapperScript = getWrapperScript(request);
// TODO: file mode 755 for wrapper script?
ArchiverFactory.createArchiver("tar", "gz").create(download.getName(),
download.getCanonicalFile().getParentFile(), dir);
new File(dir, wrapperScript).setExecutable(true);
Tar zip = new Tar();
zip.setProject(new Project());
zip.setDefaultexcludes(false);
TarFileSet set = zip.createTarFileSet();
set.setDir(dir);
set.setFileMode("755");
set.setIncludes(wrapperScript);
set.setDefaultexcludes(false);
set = zip.createTarFileSet();
set.setDir(dir);
set.setIncludes("**,");
set.setExcludes(wrapperScript);
set.setDefaultexcludes(false);
zip.setDestFile(download.getCanonicalFile());
TarCompressionMethod method = new TarCompressionMethod();
method.setValue("gzip");
zip.setCompression(method );
zip.execute();
return upload(download, dir, generateFileName(request, "tar.gz"),
"application/x-compress");
}

View File

@@ -16,6 +16,8 @@
package io.spring.initializr.web;
import static org.junit.Assert.assertTrue;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
@@ -25,23 +27,17 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import io.spring.initializr.metadata.InitializrMetadata;
import io.spring.initializr.metadata.InitializrMetadataBuilder;
import io.spring.initializr.metadata.InitializrMetadataProvider;
import io.spring.initializr.metadata.InitializrProperties;
import io.spring.initializr.test.generator.ProjectAssert;
import io.spring.initializr.web.AbstractInitializrIntegrationTests.Config;
import io.spring.initializr.web.mapper.InitializrMetadataVersion;
import io.spring.initializr.web.support.DefaultInitializrMetadataProvider;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.Expand;
import org.apache.tools.ant.taskdefs.Untar;
import org.apache.tools.ant.taskdefs.Untar.UntarCompressionMethod;
import org.json.JSONObject;
import org.junit.Before;
import org.junit.Rule;
import org.junit.rules.TemporaryFolder;
import org.junit.runner.RunWith;
import org.rauschig.jarchivelib.ArchiverFactory;
import org.skyscreamer.jsonassert.JSONAssert;
import org.skyscreamer.jsonassert.JSONCompareMode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
@@ -57,7 +53,14 @@ import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.util.StreamUtils;
import org.springframework.web.client.RestTemplate;
import static org.junit.Assert.assertTrue;
import io.spring.initializr.metadata.InitializrMetadata;
import io.spring.initializr.metadata.InitializrMetadataBuilder;
import io.spring.initializr.metadata.InitializrMetadataProvider;
import io.spring.initializr.metadata.InitializrProperties;
import io.spring.initializr.test.generator.ProjectAssert;
import io.spring.initializr.web.AbstractInitializrIntegrationTests.Config;
import io.spring.initializr.web.mapper.InitializrMetadataVersion;
import io.spring.initializr.web.support.DefaultInitializrMetadataProvider;
/**
* @author Stephane Nicoll
@@ -183,10 +186,10 @@ public abstract class AbstractInitializrIntegrationTests {
File project = folder.newFolder();
switch (archiveType) {
case ZIP:
ArchiverFactory.createArchiver("zip").extract(archiveFile, project);
unzip(archiveFile, project);
break;
case TGZ:
ArchiverFactory.createArchiver("tar", "gz").extract(archiveFile, project);
untar(archiveFile, project);
break;
}
return new ProjectAssert(project);
@@ -196,6 +199,25 @@ public abstract class AbstractInitializrIntegrationTests {
}
}
private void untar(File archiveFile, File project) {
Untar expand = new Untar();
expand.setProject(new Project());
expand.setDest(project);
expand.setSrc(archiveFile);
UntarCompressionMethod method = new UntarCompressionMethod();
method.setValue("gzip");
expand.setCompression(method );
expand.execute();
}
private void unzip(File archiveFile, File project) {
Expand expand = new Expand();
expand.setProject(new Project());
expand.setDest(project);
expand.setSrc(archiveFile);
expand.execute();
}
protected File writeArchive(byte[] body) throws IOException {
File archiveFile = folder.newFile();
try (FileOutputStream stream = new FileOutputStream(archiveFile)) {

View File

@@ -55,7 +55,8 @@ public class MainControllerIntegrationTests
@Test
public void simpleZipProject() {
downloadZip("/starter.zip?style=web&style=jpa").isJavaProject()
.hasFile(".gitignore").isMavenProject()
.hasFile(".gitignore")
.hasExecutableFile("mvnw").isMavenProject()
.hasStaticAndTemplatesResources(true).pomAssert().hasDependenciesCount(3)
.hasSpringBootStarterDependency("web")
.hasSpringBootStarterDependency("data-jpa") // alias jpa -> data-jpa
@@ -65,7 +66,8 @@ public class MainControllerIntegrationTests
@Test
public void simpleTgzProject() {
downloadTgz("/starter.tgz?style=org.acme:foo").isJavaProject()
.hasFile(".gitignore").isMavenProject()
.hasFile(".gitignore")
.hasExecutableFile("mvnw").isMavenProject()
.hasStaticAndTemplatesResources(false).pomAssert().hasDependenciesCount(2)
.hasDependency("org.acme", "foo", "1.3.5");
}

View File

@@ -98,9 +98,9 @@
<version>1.5</version>
</dependency>
<dependency>
<groupId>org.rauschig</groupId>
<artifactId>jarchivelib</artifactId>
<version>0.7.1</version>
<groupId>org.apache.ant</groupId>
<artifactId>ant</artifactId>
<version>1.10.1</version>
</dependency>
</dependencies>
</dependencyManagement>