From 3bdccad9cde67e5fe53ef068a59f5869cb267e14 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Mon, 20 Oct 2014 11:58:14 +0200 Subject: [PATCH] Generate proper project archives This commit generates an archive name that is consistent with the chosen artifactId for the project. This prevents all archives to be named 'starter.zip'. If the custom artifact contains special characters, these are encoded (spaces are replaced by _ which seems a sensitive default) Fixes gh-36 --- initializr/pom.xml | 2 +- .../initializr/web/MainController.groovy | 23 +++++++++++-------- ...lizerControllerFormIntegrationTests.groovy | 17 +++++++++++--- .../initializr/web/support/HomePage.groovy | 9 ++++---- 4 files changed, 33 insertions(+), 18 deletions(-) diff --git a/initializr/pom.xml b/initializr/pom.xml index b9faa7fd..73e77248 100644 --- a/initializr/pom.xml +++ b/initializr/pom.xml @@ -10,7 +10,7 @@ UTF-8 - 1.1.5.RELEASE + 1.1.8.RELEASE diff --git a/initializr/src/main/groovy/io/spring/initializr/web/MainController.groovy b/initializr/src/main/groovy/io/spring/initializr/web/MainController.groovy index 00048c7a..fb8458e9 100644 --- a/initializr/src/main/groovy/io/spring/initializr/web/MainController.groovy +++ b/initializr/src/main/groovy/io/spring/initializr/web/MainController.groovy @@ -101,12 +101,7 @@ class MainController extends AbstractInitializrController { new AntBuilder().zip(destfile: download) { zipfileset(dir: dir, includes: '**') } - log.info("Uploading: ${download} (${download.bytes.length} bytes)") - def result = new ResponseEntity(download.bytes, - ['Content-Type': 'application/zip'] as HttpHeaders, HttpStatus.OK) - - projectGenerator.cleanTempFiles(dir) - result + upload(download, dir, generateFileName(request, 'zip'), 'application/zip') } @RequestMapping(value='/starter.tgz', produces='application/x-compress') @@ -119,10 +114,20 @@ class MainController extends AbstractInitializrController { new AntBuilder().tar(destfile: download, compression: 'gzip') { zipfileset(dir:dir, includes:'**') } - log.info("Uploading: ${download} (${download.bytes.length} bytes)") - def result = new ResponseEntity(download.bytes, - ['Content-Type':'application/x-compress'] as HttpHeaders, HttpStatus.OK) + upload(download, dir, generateFileName(request, 'tgz'), 'application/x-compress') + } + private static String generateFileName(ProjectRequest request, String extension) { + String tmp = request.artifactId.replaceAll(' ', '_') + URLEncoder.encode(tmp, 'UTF-8') + '.' + extension + } + + private ResponseEntity upload(File download, File dir, String fileName, String contentType) { + log.info("Uploading: ${download} (${download.bytes.length} bytes)") + String contentDispositionValue = "attachment; filename=\"$fileName\"" + def result = new ResponseEntity(download.bytes, + ['Content-Type': contentType, + 'Content-Disposition': contentDispositionValue] as HttpHeaders, HttpStatus.OK) projectGenerator.cleanTempFiles(dir) result } diff --git a/initializr/src/test/groovy/io/spring/initializr/web/AbstractInitializerControllerFormIntegrationTests.groovy b/initializr/src/test/groovy/io/spring/initializr/web/AbstractInitializerControllerFormIntegrationTests.groovy index ff3d8ddb..a9fb90a8 100644 --- a/initializr/src/test/groovy/io/spring/initializr/web/AbstractInitializerControllerFormIntegrationTests.groovy +++ b/initializr/src/test/groovy/io/spring/initializr/web/AbstractInitializerControllerFormIntegrationTests.groovy @@ -18,6 +18,7 @@ package io.spring.initializr.web import com.gargoylesoftware.htmlunit.WebClient import com.gargoylesoftware.htmlunit.WebRequest +import com.gargoylesoftware.htmlunit.WebResponse import com.gargoylesoftware.htmlunit.html.HtmlPage import io.spring.initializr.support.ProjectAssert import io.spring.initializr.web.support.HomePage @@ -27,11 +28,12 @@ import org.junit.Test import org.springframework.beans.factory.annotation.Autowired import org.springframework.test.context.ActiveProfiles -import org.springframework.test.web.servlet.MockMvc import org.springframework.test.web.servlet.htmlunit.MockMvcWebConnection import org.springframework.test.web.servlet.setup.MockMvcBuilders import org.springframework.web.context.WebApplicationContext +import static org.junit.Assert.assertEquals + /** * Integration tests that are actually using the HTML page to request new * projects. Used to test both the default home page and the legacy one @@ -64,7 +66,7 @@ abstract class AbstractInitializerControllerFormIntegrationTests extends Abstrac @Test void createDefaultProject() { def page = home() - def projectAssert = zipProjectAssert(page.generateProject()) + def projectAssert = zipProjectAssert(page.generateProject().contentAsStream.bytes) projectAssert.isMavenProject().isJavaProject().hasStaticAndTemplatesResources(false) .pomAssert().hasDependenciesCount(2) .hasSpringBootStarterRootDependency().hasSpringBootStarterDependency('test') @@ -78,7 +80,12 @@ abstract class AbstractInitializerControllerFormIntegrationTests extends Abstrac page.name = 'My project' page.description = 'A description for my project' page.dependencies << 'web' << 'data-jpa' - def projectAssert = zipProjectAssert(page.generateProject()) + + WebResponse webResponse = page.generateProject() + String value = webResponse.getResponseHeaderValue('Content-Disposition') + assertEquals 'attachment; filename="foo-bar.zip"', value + + def projectAssert = zipProjectAssert(webResponse) projectAssert.isMavenProject().isJavaProject().hasStaticAndTemplatesResources(true) projectAssert.pomAssert().hasGroupId('com.acme').hasArtifactId('foo-bar') @@ -115,6 +122,10 @@ abstract class AbstractInitializerControllerFormIntegrationTests extends Abstrac createHomePage(home) } + ProjectAssert zipProjectAssert(WebResponse webResponse) { + zipProjectAssert(webResponse.contentAsStream.bytes) + } + /** * Provide the context of the home page */ diff --git a/initializr/src/test/groovy/io/spring/initializr/web/support/HomePage.groovy b/initializr/src/test/groovy/io/spring/initializr/web/support/HomePage.groovy index 53d21064..40b23271 100644 --- a/initializr/src/test/groovy/io/spring/initializr/web/support/HomePage.groovy +++ b/initializr/src/test/groovy/io/spring/initializr/web/support/HomePage.groovy @@ -16,9 +16,8 @@ package io.spring.initializr.web.support -import com.gargoylesoftware.htmlunit.Page +import com.gargoylesoftware.htmlunit.WebResponse import com.gargoylesoftware.htmlunit.html.* -import io.spring.initializr.support.ProjectAssert /** * Represent the home page of the service. @@ -44,14 +43,14 @@ abstract class HomePage { /** * Generate a project using the specified temporary directory. Return - * the {@link ProjectAssert} instance. + * the {@link WebResponse}. * @see org.junit.rules.TemporaryFolder */ - byte[] generateProject() { + WebResponse generateProject() { setup() def submit = page.getElementByName('generate-project') def newMessagePage = submit.click(); - newMessagePage.webResponse.contentAsStream.bytes + newMessagePage.webResponse } /**