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
This commit is contained in:
Stephane Nicoll
2014-10-20 11:58:14 +02:00
parent 3fa1f72c4f
commit 3bdccad9cd
4 changed files with 33 additions and 18 deletions

View File

@@ -10,7 +10,7 @@
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring.boot.version>1.1.5.RELEASE</spring.boot.version>
<spring.boot.version>1.1.8.RELEASE</spring.boot.version>
</properties>
<dependencies>

View File

@@ -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<byte[]>(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<byte[]>(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<byte[]> 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<byte[]>(download.bytes,
['Content-Type': contentType,
'Content-Disposition': contentDispositionValue] as HttpHeaders, HttpStatus.OK)
projectGenerator.cleanTempFiles(dir)
result
}

View File

@@ -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
*/

View File

@@ -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
}
/**