diff --git a/initializr-actuator/pom.xml b/initializr-actuator/pom.xml index c2009ad3..67e94c40 100644 --- a/initializr-actuator/pom.xml +++ b/initializr-actuator/pom.xml @@ -52,11 +52,6 @@ test-jar test - - org.rauschig - jarchivelib - test - io.spring.initializr initializr-web diff --git a/initializr-generator/src/main/resources/project/gradle/gradlew.bat b/initializr-generator/src/main/resources/project/gradle/gradlew.bat old mode 100644 new mode 100755 diff --git a/initializr-generator/src/main/resources/project/gradle3/gradlew.bat b/initializr-generator/src/main/resources/project/gradle3/gradlew.bat old mode 100644 new mode 100755 diff --git a/initializr-generator/src/main/resources/project/maven/mvnw b/initializr-generator/src/main/resources/project/maven/mvnw old mode 100644 new mode 100755 diff --git a/initializr-generator/src/main/resources/project/maven/mvnw.cmd b/initializr-generator/src/main/resources/project/maven/mvnw.cmd old mode 100644 new mode 100755 diff --git a/initializr-generator/src/test/java/io/spring/initializr/test/generator/ProjectAssert.java b/initializr-generator/src/test/java/io/spring/initializr/test/generator/ProjectAssert.java index 31c1415e..864fbea3 100644 --- a/initializr-generator/src/test/java/io/spring/initializr/test/generator/ProjectAssert.java +++ b/initializr-generator/src/test/java/io/spring/initializr/test/generator/ProjectAssert.java @@ -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); } diff --git a/initializr-web/pom.xml b/initializr-web/pom.xml index 8a36e50b..1fa0f417 100644 --- a/initializr-web/pom.xml +++ b/initializr-web/pom.xml @@ -1,7 +1,6 @@ - + 4.0.0 io.spring.initializr @@ -38,8 +37,14 @@ caffeine - org.rauschig - jarchivelib + org.apache.ant + ant + + + org.apache.ant + ant-launcher + + org.json diff --git a/initializr-web/src/main/java/io/spring/initializr/web/project/MainController.java b/initializr-web/src/main/java/io/spring/initializr/web/project/MainController.java index bab9c6a9..0e2c4f75 100644 --- a/initializr-web/src/main/java/io/spring/initializr/web/project/MainController.java +++ b/initializr-web/src/main/java/io/spring/initializr/web/project/MainController.java @@ -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"); } diff --git a/initializr-web/src/test/java/io/spring/initializr/web/AbstractInitializrIntegrationTests.java b/initializr-web/src/test/java/io/spring/initializr/web/AbstractInitializrIntegrationTests.java index b7359a34..e152e865 100644 --- a/initializr-web/src/test/java/io/spring/initializr/web/AbstractInitializrIntegrationTests.java +++ b/initializr-web/src/test/java/io/spring/initializr/web/AbstractInitializrIntegrationTests.java @@ -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)) { diff --git a/initializr-web/src/test/java/io/spring/initializr/web/project/MainControllerIntegrationTests.java b/initializr-web/src/test/java/io/spring/initializr/web/project/MainControllerIntegrationTests.java index 8d155e5e..0bfc97fe 100644 --- a/initializr-web/src/test/java/io/spring/initializr/web/project/MainControllerIntegrationTests.java +++ b/initializr-web/src/test/java/io/spring/initializr/web/project/MainControllerIntegrationTests.java @@ -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"); } diff --git a/pom.xml b/pom.xml index 1acfe891..57138c8e 100644 --- a/pom.xml +++ b/pom.xml @@ -98,9 +98,9 @@ 1.5 - org.rauschig - jarchivelib - 0.7.1 + org.apache.ant + ant + 1.10.1