mirror of
https://gitee.com/dcren/initializr.git
synced 2025-07-15 14:04:30 +08:00
Migrate from Ant to Commons Compress
Closes gh-951
This commit is contained in:
parent
aad9ce07d7
commit
b769c8d6a0
@ -41,8 +41,8 @@
|
||||
<artifactId>spring-hateoas</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.ant</groupId>
|
||||
<artifactId>ant</artifactId>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-compress</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
|
@ -18,6 +18,7 @@ package io.spring.initializr.web.project;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
@ -25,6 +26,9 @@ import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
|
||||
import io.spring.initializr.generator.buildsystem.BuildSystem;
|
||||
import io.spring.initializr.generator.buildsystem.maven.MavenBuildSystem;
|
||||
@ -43,13 +47,16 @@ import io.spring.initializr.web.mapper.InitializrMetadataVersion;
|
||||
import io.spring.initializr.web.support.Agent;
|
||||
import io.spring.initializr.web.support.Agent.AgentId;
|
||||
import io.spring.initializr.web.support.CommandLineHelpGenerator;
|
||||
import org.apache.commons.compress.archivers.ArchiveEntry;
|
||||
import org.apache.commons.compress.archivers.ArchiveOutputStream;
|
||||
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
|
||||
import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;
|
||||
import org.apache.commons.compress.archivers.zip.UnixStat;
|
||||
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
|
||||
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
|
||||
import org.apache.commons.compress.compressors.gzip.GzipCompressorOutputStream;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.tools.ant.Project;
|
||||
import org.apache.tools.ant.taskdefs.Tar;
|
||||
import org.apache.tools.ant.taskdefs.Zip;
|
||||
import org.apache.tools.ant.types.TarFileSet;
|
||||
import org.apache.tools.ant.types.ZipFileSet;
|
||||
|
||||
import org.springframework.http.CacheControl;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
@ -221,26 +228,8 @@ public class MainController extends AbstractInitializrController {
|
||||
@ResponseBody
|
||||
public ResponseEntity<byte[]> springZip(ProjectRequest request) throws IOException {
|
||||
ProjectGenerationResult result = this.projectGenerationInvoker.invokeProjectStructureGeneration(request);
|
||||
File dir = result.getRootDirectory().toFile();
|
||||
Path archive = this.projectGenerationInvoker.createDistributionFile(result.getRootDirectory(), ".zip");
|
||||
String wrapperScript = getWrapperScript(result.getProjectDescription());
|
||||
Zip zip = new Zip();
|
||||
zip.setProject(new Project());
|
||||
zip.setDefaultexcludes(false);
|
||||
ZipFileSet set = new ZipFileSet();
|
||||
set.setDir(dir);
|
||||
set.setFileMode("755");
|
||||
set.createInclude().setName(wrapperScript);
|
||||
set.setDefaultexcludes(false);
|
||||
zip.addFileset(set);
|
||||
set = new ZipFileSet();
|
||||
set.setDir(dir);
|
||||
set.setIncludes("**,");
|
||||
set.createExclude().setName(wrapperScript);
|
||||
set.setDefaultexcludes(false);
|
||||
zip.addFileset(set);
|
||||
zip.setDestFile(archive.toFile().getCanonicalFile());
|
||||
zip.execute();
|
||||
Path archive = createArchive(result, "zip", ZipArchiveOutputStream::new, ZipArchiveEntry::new,
|
||||
(entry, mode) -> entry.setUnixMode(mode));
|
||||
return upload(archive, result.getRootDirectory(), generateFileName(request, "zip"), "application/zip");
|
||||
}
|
||||
|
||||
@ -248,31 +237,63 @@ public class MainController extends AbstractInitializrController {
|
||||
@ResponseBody
|
||||
public ResponseEntity<byte[]> springTgz(ProjectRequest request) throws IOException {
|
||||
ProjectGenerationResult result = this.projectGenerationInvoker.invokeProjectStructureGeneration(request);
|
||||
File dir = result.getRootDirectory().toFile();
|
||||
Path download = this.projectGenerationInvoker.createDistributionFile(result.getRootDirectory(), ".tar.gz");
|
||||
String wrapperScript = getWrapperScript(result.getProjectDescription());
|
||||
Tar zip = new Tar();
|
||||
zip.setProject(new Project());
|
||||
zip.setDefaultexcludes(false);
|
||||
TarFileSet set = zip.createTarFileSet();
|
||||
set.setDir(dir);
|
||||
set.setFileMode("755");
|
||||
set.createInclude().setName(wrapperScript);
|
||||
set.setDefaultexcludes(false);
|
||||
set = zip.createTarFileSet();
|
||||
set.setDir(dir);
|
||||
set.setIncludes("**,");
|
||||
set.createExclude().setName(wrapperScript);
|
||||
set.setDefaultexcludes(false);
|
||||
zip.setDestFile(download.toFile().getCanonicalFile());
|
||||
Tar.TarCompressionMethod method = new Tar.TarCompressionMethod();
|
||||
method.setValue("gzip");
|
||||
zip.setCompression(method);
|
||||
zip.execute();
|
||||
return upload(download, result.getRootDirectory(), generateFileName(request, "tar.gz"),
|
||||
Path archive = createArchive(result, "tar.gz", this::createTarArchiveOutputStream, TarArchiveEntry::new,
|
||||
(entry, mode) -> entry.setMode(mode));
|
||||
return upload(archive, result.getRootDirectory(), generateFileName(request, "tar.gz"),
|
||||
"application/x-compress");
|
||||
}
|
||||
|
||||
private TarArchiveOutputStream createTarArchiveOutputStream(OutputStream output) {
|
||||
try {
|
||||
return new TarArchiveOutputStream(new GzipCompressorOutputStream(output));
|
||||
}
|
||||
catch (IOException ex) {
|
||||
throw new IllegalStateException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private <T extends ArchiveEntry> Path createArchive(ProjectGenerationResult result, String fileExtension,
|
||||
Function<OutputStream, ? extends ArchiveOutputStream> archiveOutputStream,
|
||||
BiFunction<File, String, T> archiveEntry, BiConsumer<T, Integer> setMode) throws IOException {
|
||||
Path archive = this.projectGenerationInvoker.createDistributionFile(result.getRootDirectory(),
|
||||
"." + fileExtension);
|
||||
String wrapperScript = getWrapperScript(result.getProjectDescription());
|
||||
try (ArchiveOutputStream output = archiveOutputStream.apply(Files.newOutputStream(archive))) {
|
||||
Files.walk(result.getRootDirectory()).filter((path) -> !result.getRootDirectory().equals(path))
|
||||
.forEach((path) -> {
|
||||
try {
|
||||
String entryName = getEntryName(result.getRootDirectory(), path);
|
||||
T entry = archiveEntry.apply(path.toFile(), entryName);
|
||||
setMode.accept(entry, getUnixMode(wrapperScript, entryName, path));
|
||||
output.putArchiveEntry(entry);
|
||||
if (!Files.isDirectory(path)) {
|
||||
Files.copy(path, output);
|
||||
}
|
||||
output.closeArchiveEntry();
|
||||
}
|
||||
catch (IOException ex) {
|
||||
throw new IllegalStateException(ex);
|
||||
}
|
||||
});
|
||||
}
|
||||
return archive;
|
||||
}
|
||||
|
||||
private String getEntryName(Path root, Path path) {
|
||||
String entryName = root.relativize(path).toString().replace('\\', '/');
|
||||
if (Files.isDirectory(path)) {
|
||||
entryName += "/";
|
||||
}
|
||||
return entryName;
|
||||
}
|
||||
|
||||
private int getUnixMode(String wrapperScript, String entryName, Path path) {
|
||||
if (Files.isDirectory(path)) {
|
||||
return UnixStat.DIR_FLAG | UnixStat.DEFAULT_DIR_PERM;
|
||||
}
|
||||
return UnixStat.FILE_FLAG | (entryName.equals(wrapperScript) ? 0755 : UnixStat.DEFAULT_FILE_PERM);
|
||||
}
|
||||
|
||||
private String generateFileName(ProjectRequest request, String extension) {
|
||||
String candidate = (StringUtils.hasText(request.getArtifactId()) ? request.getArtifactId()
|
||||
: this.metadataProvider.get().getArtifactId().getContent());
|
||||
|
@ -16,15 +16,19 @@
|
||||
|
||||
package io.spring.initializr.web;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.attribute.PosixFilePermission;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
@ -32,10 +36,11 @@ import io.spring.initializr.generator.spring.test.ProjectAssert;
|
||||
import io.spring.initializr.web.AbstractInitializrIntegrationTests.Config;
|
||||
import io.spring.initializr.web.mapper.InitializrMetadataVersion;
|
||||
import io.spring.initializr.web.support.InitializrMetadataUpdateStrategy;
|
||||
import org.apache.tools.ant.Project;
|
||||
import org.apache.tools.ant.taskdefs.ExecTask;
|
||||
import org.apache.tools.ant.taskdefs.Expand;
|
||||
import org.apache.tools.ant.taskdefs.Untar;
|
||||
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
|
||||
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
|
||||
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
|
||||
import org.apache.commons.compress.archivers.zip.ZipFile;
|
||||
import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
@ -212,59 +217,45 @@ public abstract class AbstractInitializrIntegrationTests {
|
||||
}
|
||||
}
|
||||
|
||||
private void untar(Path archiveFile, Path project) {
|
||||
if (!runningOnWindows()) {
|
||||
createProjectDir(project);
|
||||
ExecTask execTask = new ExecTask();
|
||||
execTask.setProject(new Project());
|
||||
execTask.setExecutable("tar");
|
||||
execTask.createArg().setValue("-C");
|
||||
execTask.createArg().setValue(project.toFile().getAbsolutePath());
|
||||
execTask.createArg().setValue("-xf");
|
||||
execTask.createArg().setValue(archiveFile.toFile().getAbsolutePath());
|
||||
execTask.execute();
|
||||
private void untar(Path archiveFile, Path project) throws IOException {
|
||||
try (TarArchiveInputStream input = new TarArchiveInputStream(
|
||||
new GzipCompressorInputStream(Files.newInputStream(archiveFile)))) {
|
||||
TarArchiveEntry entry = null;
|
||||
while ((entry = input.getNextTarEntry()) != null) {
|
||||
Path path = project.resolve(entry.getName());
|
||||
if (entry.isDirectory()) {
|
||||
Files.createDirectories(path);
|
||||
}
|
||||
else {
|
||||
Untar expand = new Untar();
|
||||
expand.setProject(new Project());
|
||||
expand.setDest(project.toFile());
|
||||
expand.setSrc(archiveFile.toFile());
|
||||
Untar.UntarCompressionMethod method = new Untar.UntarCompressionMethod();
|
||||
method.setValue("gzip");
|
||||
expand.setCompression(method);
|
||||
expand.execute();
|
||||
Files.createDirectories(path.getParent());
|
||||
Files.write(path, StreamUtils.copyToByteArray(input));
|
||||
}
|
||||
Files.setPosixFilePermissions(path, getPosixFilePermissions(entry.getMode()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void createProjectDir(Path project) {
|
||||
ExecTask execTask = new ExecTask();
|
||||
execTask.setProject(new Project());
|
||||
execTask.setExecutable("mkdir");
|
||||
execTask.createArg().setValue(project.toFile().getAbsolutePath());
|
||||
execTask.execute();
|
||||
}
|
||||
|
||||
private void unzip(Path archiveFile, Path project) {
|
||||
if (!runningOnWindows()) {
|
||||
ExecTask execTask = new ExecTask();
|
||||
execTask.setProject(new Project());
|
||||
execTask.setExecutable("unzip");
|
||||
execTask.createArg().setValue(archiveFile.toFile().getAbsolutePath());
|
||||
execTask.createArg().setValue("-d");
|
||||
execTask.createArg().setValue(project.toFile().getAbsolutePath());
|
||||
execTask.execute();
|
||||
private void unzip(Path archiveFile, Path project) throws IOException {
|
||||
try (ZipFile zip = new ZipFile(archiveFile.toFile())) {
|
||||
Enumeration<? extends ZipArchiveEntry> entries = zip.getEntries();
|
||||
while (entries.hasMoreElements()) {
|
||||
ZipArchiveEntry entry = entries.nextElement();
|
||||
Path path = project.resolve(entry.getName());
|
||||
if (entry.isDirectory()) {
|
||||
Files.createDirectories(path);
|
||||
}
|
||||
else {
|
||||
Expand expand = new Expand();
|
||||
expand.setProject(new Project());
|
||||
expand.setDest(project.toFile());
|
||||
expand.setSrc(archiveFile.toFile());
|
||||
expand.execute();
|
||||
Files.createDirectories(path.getParent());
|
||||
Files.write(path, StreamUtils.copyToByteArray(zip.getInputStream(entry)));
|
||||
}
|
||||
Files.setPosixFilePermissions(path, getPosixFilePermissions(entry.getUnixMode()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean runningOnWindows() {
|
||||
return File.separatorChar == '\\';
|
||||
private Set<PosixFilePermission> getPosixFilePermissions(int unixMode) {
|
||||
return Arrays.stream(BitMaskFilePermission.values()).filter((permission) -> permission.permitted(unixMode))
|
||||
.map(BitMaskFilePermission::getFilePermission).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
protected Path writeArchive(byte[] body) throws IOException {
|
||||
@ -320,4 +311,43 @@ public abstract class AbstractInitializrIntegrationTests {
|
||||
|
||||
}
|
||||
|
||||
private enum BitMaskFilePermission {
|
||||
|
||||
OWNER_READ(0400),
|
||||
|
||||
OWNER_WRITE(0200),
|
||||
|
||||
OWNER_EXECUTE(0100),
|
||||
|
||||
GROUP_READ(0040),
|
||||
|
||||
GROUP_WRITE(0020),
|
||||
|
||||
GROUP_EXECUTE(0010),
|
||||
|
||||
OTHERS_READ(0004),
|
||||
|
||||
OTHERS_WRITE(0002),
|
||||
|
||||
OTHERS_EXECUTE(0001);
|
||||
|
||||
private int mask;
|
||||
|
||||
private PosixFilePermission filePermission;
|
||||
|
||||
BitMaskFilePermission(int mask) {
|
||||
this.mask = mask;
|
||||
this.filePermission = PosixFilePermission.valueOf(this.name());
|
||||
}
|
||||
|
||||
boolean permitted(int unixMode) {
|
||||
return (this.mask & unixMode) == this.mask;
|
||||
}
|
||||
|
||||
PosixFilePermission getFilePermission() {
|
||||
return this.filePermission;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
17
pom.xml
17
pom.xml
@ -41,6 +41,7 @@
|
||||
<java.version>1.8</java.version>
|
||||
<main.basedir>${basedir}</main.basedir>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<commons-compress.version>1.18</commons-compress.version>
|
||||
<junit-jupiter.version>5.4.2</junit-jupiter.version>
|
||||
<maven.version>3.6.1</maven.version>
|
||||
<maven-resolver.version>1.3.3</maven-resolver.version>
|
||||
@ -105,6 +106,11 @@
|
||||
<version>${revision}</version>
|
||||
<type>test-jar</type>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-compress</artifactId>
|
||||
<version>${commons-compress.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.maven</groupId>
|
||||
<artifactId>maven-resolver-provider</artifactId>
|
||||
@ -146,17 +152,6 @@
|
||||
<artifactId>android-json</artifactId>
|
||||
<version>0.0.20131108.vaadin1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.ant</groupId>
|
||||
<artifactId>ant</artifactId>
|
||||
<version>1.10.2</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.apache.ant</groupId>
|
||||
<artifactId>ant-launcher</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user