Add support for WAR packaging

This commit is contained in:
Dave Syer 2014-05-29 16:26:47 +01:00
parent f0e07531cc
commit d6c77bb9ef
7 changed files with 107 additions and 18 deletions

View File

@ -10,7 +10,7 @@ class MainController {
@Value('${info.home:http://localhost:8080/}') @Value('${info.home:http://localhost:8080/}')
private String home private String home
@Value('${info.spring-boot.version:1.0.1.RELEASE}') @Value('${info.spring-boot.version:1.0.2.RELEASE}')
private String bootVersion private String bootVersion
@Value('${TMPDIR:.}') @Value('${TMPDIR:.}')
@ -29,6 +29,7 @@ class MainController {
// sort lists // sort lists
model['styles'] = projects.styles.sort { it.name } model['styles'] = projects.styles.sort { it.name }
model['types'] = projects.types.sort { it.name } model['types'] = projects.types.sort { it.name }
model['packagings'] = projects.packagings.sort { it.name }
template 'home.html', model template 'home.html', model
} }
@ -43,7 +44,7 @@ class MainController {
zipfileset(dir:'.', includes:'spring/**', excludes:'spring/bin/**') zipfileset(dir:'.', includes:'spring/**', excludes:'spring/bin/**')
} }
} }
log.info('Downloading: ' + download) log.info('Uploading: ' + download)
new ResponseEntity<byte[]>(download.bytes, ['Content-Type':'application/zip'] as HttpHeaders, HttpStatus.OK) new ResponseEntity<byte[]>(download.bytes, ['Content-Type':'application/zip'] as HttpHeaders, HttpStatus.OK)
} }
@ -64,7 +65,7 @@ class MainController {
log.info("Uploading: ${download} (${download.bytes.length} bytes)") log.info("Uploading: ${download} (${download.bytes.length} bytes)")
def result = new ResponseEntity<byte[]>(download.bytes, ['Content-Type':'application/x-compress'] as HttpHeaders, HttpStatus.OK) def result = new ResponseEntity<byte[]>(download.bytes, ['Content-Type':'application/x-compress'] as HttpHeaders, HttpStatus.OK)
log.info('Notifying reactor: ' + download) log.fine('Notifying reactor: ' + download)
reactor.notify('tempfiles', Event.wrap(tempFiles)) reactor.notify('tempfiles', Event.wrap(tempFiles))
result result
@ -93,7 +94,7 @@ class MainController {
result result
} }
def getProjectFiles(File dir, PomRequest request) { def getProjectFiles(File dir, PomRequest request) {
def tempFiles = [] def tempFiles = []
@ -102,15 +103,21 @@ class MainController {
dir.delete() dir.delete()
dir.mkdirs() dir.mkdirs()
String pom = new String(pom(request, model).body) if (request.type.contains('gradle')) {
new File(dir, 'pom.xml').write(pom) String gradle = new String(gradle(request, model).body)
new File(dir, 'build.gradle').write(gradle)
String gradle = new String(gradle(request, model).body) } else {
new File(dir, 'build.gradle').write(gradle) String pom = new String(pom(request, model).body)
new File(dir, 'pom.xml').write(pom)
}
File src = new File(new File(dir, 'src/main/java'),request.packageName.replace('.', '/')) File src = new File(new File(dir, 'src/main/java'),request.packageName.replace('.', '/'))
src.mkdirs() src.mkdirs()
write(src, 'Application.java', model) write(src, 'Application.java', model)
if (request.packaging=='war') {
write(src, 'ServletInitializer.java', model)
}
File test = new File(new File(dir, 'src/test/java'),request.packageName.replace('.', '/')) File test = new File(new File(dir, 'src/test/java'),request.packageName.replace('.', '/'))
test.mkdirs() test.mkdirs()
@ -154,6 +161,10 @@ class MainController {
byte[] render(String path, PomRequest request, Map model) { byte[] render(String path, PomRequest request, Map model) {
if (request.packaging=='war' && !request.style.any { isWebStyle(it) }) {
request.style << 'web'
}
def style = request.style def style = request.style
log.info('Styles requested: ' + style) log.info('Styles requested: ' + style)
@ -166,6 +177,7 @@ class MainController {
model.name = request.name model.name = request.name
model.description = request.description model.description = request.description
model.packageName = request.packageName model.packageName = request.packageName
model.packaging = request.packaging
if (style==null || style.size()==0) { if (style==null || style.size()==0) {
style = [''] style = ['']
@ -182,6 +194,10 @@ class MainController {
body body
} }
private boolean isWebStyle(String style) {
return style.contains('web') || style.contains('thymeleaf') || style.contains('freemarker') || style.contains('velocity') || style.contains('groovy-template')
}
} }
@EnableReactor @EnableReactor
@ -194,7 +210,7 @@ class TemporaryFileCleaner {
@Selector('tempfiles') @Selector('tempfiles')
void clean(def tempFiles) { void clean(def tempFiles) {
log.info 'Tempfiles: ' + tempFiles log.fine 'Tempfiles: ' + tempFiles
if (tempFiles) { if (tempFiles) {
tempFiles.each { tempFiles.each {
File file = it as File File file = it as File
@ -218,6 +234,7 @@ class PomRequest {
String groupId = 'org.test' String groupId = 'org.test'
String artifactId String artifactId
String version = '0.0.1-SNAPSHOT' String version = '0.0.1-SNAPSHOT'
String packaging = 'jar'
String packageName String packageName
String getArtifactId() { String getArtifactId() {
artifactId == null ? name : artifactId artifactId == null ? name : artifactId
@ -231,5 +248,17 @@ class PomRequest {
@ConfigurationProperties(prefix='projects', ignoreUnknownFields=false) @ConfigurationProperties(prefix='projects', ignoreUnknownFields=false)
class Projects { class Projects {
List<Map<String,Object>> styles List<Map<String,Object>> styles
List<Map<String,Object>> types List<Type> types
List<Packaging> packagings
static class Packaging {
String name
String value
boolean selected
}
static class Type {
String name
String action
String value
boolean selected
}
} }

View File

@ -4,12 +4,20 @@ info:
version: 0.1.0 version: 0.1.0
# remember to update static/install.sh as well: # remember to update static/install.sh as well:
spring-boot: spring-boot:
version: 1.1.0.RELEASE version: 1.1.0.BUILD-SNAPSHOT
projects: projects:
styles: styles:
- name: Web - name: Web
value: web value: web
- name: Websocket
value: websocket
- name: Freemarker
value: freemarker
- name: Velocity
value: velocity
- name: Groovy Templates
value: groovy-templates
- name: Thymeleaf - name: Thymeleaf
value: thymeleaf value: thymeleaf
- name: Actuator - name: Actuator
@ -32,19 +40,43 @@ projects:
value: data-mongodb value: data-mongodb
- name: Redis - name: Redis
value: redis value: redis
- name: Gemfire
value: data-gemfire
- name: Solr
value: data-solr
- name: Rest Repositories - name: Rest Repositories
value: data-rest value: data-rest
- name: Remote Shell - name: Remote Shell
value: remote-shell value: remote-shell
- name: Mobile - name: Mobile
value: mobile value: mobile
- name: Facebook
value: social-facebook
- name: LinkedIn
value: social-linkedin
- name: Twitter
value: social-twitter
types: types:
- name: Maven POM - name: Maven POM
action: /pom.xml
value: pom.xml value: pom.xml
selected: false selected: false
- name: Maven Project - name: Maven Project
action: /starter.zip
value: starter.zip value: starter.zip
selected: true selected: true
- name: Gradle - name: Gradle Config
action: /build.gradle
value: build.gradle value: build.gradle
selected: false selected: false
- name: Gradle Project
action: /starter.zip
value: gradle.zip
selected: false
packagings:
- name: Jar
value: jar
selected: true
- name: War
value: war
selected: false

View File

@ -0,0 +1,13 @@
package ${packageName};
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.web.SpringBootServletInitializer;
public class ServletInitializer extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
}
}

View File

@ -49,7 +49,13 @@
<label>Type:</label> <label>Type:</label>
<% types.each { %> <% types.each { %>
<label class="radio"> <label class="radio">
<input type="radio" name="type" value="${it.value}"${it.selected ? ' checked="true"' : ''} onclick="javascript:this.form.action='/${it.value}'"/> <input type="radio" name="type" value="${it.value}"${it.selected==true ? ' checked="true"' : ''} onclick="javascript:this.form.action='${it.action}'"/>
${it.name}
</label><% } %>
<label>Packaging:</label>
<% packagings.each { %>
<label class="radio">
<input type="radio" name="packaging" value="${it.value}"${it.selected==true ? ' checked="true"' : ''}/>
${it.name} ${it.name}
</label><% } %> </label><% } %>
<button type="submit" class="btn">Generate</button> <button type="submit" class="btn">Generate</button>

View File

@ -16,9 +16,11 @@ buildscript {
apply plugin: 'java' apply plugin: 'java'
apply plugin: 'eclipse' apply plugin: 'eclipse'
apply plugin: 'idea' apply plugin: 'idea'
apply plugin: 'spring-boot' apply plugin: 'spring-boot' <% if (packaging=='war') { %>
apply plugin: 'war'
<% } %>
jar { <% if (packaging=='war') { %>war<% } else { %>jar<% } %> {
baseName = '${artifactId}' baseName = '${artifactId}'
version = '${version}' version = '${version}'
} }

View File

@ -6,6 +6,7 @@
<groupId>${groupId}</groupId> <groupId>${groupId}</groupId>
<artifactId>${artifactId}</artifactId> <artifactId>${artifactId}</artifactId>
<version>${version}</version> <version>${version}</version>
<packaging>${packaging}</packaging>
<name>${name}</name> <name>${name}</name>
<description>${description}</description> <description>${description}</description>
@ -82,4 +83,4 @@
</pluginRepositories> </pluginRepositories>
<% } %> <% } %>
</project> </project>

View File

@ -15,6 +15,12 @@ class IntegrationTests {
assertTrue('Wrong body:\n' + body, body.contains('action="/starter.zip"')) assertTrue('Wrong body:\n' + body, body.contains('action="/starter.zip"'))
} }
@Test
void webIsAdded() {
String body = new TestRestTemplate().getForObject('http://localhost:' + port + '/pom.xml?packaging=war', String)
assertTrue('Wrong body:\n' + body, body.contains('spring-boot-starter-web'))
}
@Test @Test
void infoHasExternalProperties() { void infoHasExternalProperties() {
String body = new TestRestTemplate().getForObject('http://localhost:' + port + '/info', String) String body = new TestRestTemplate().getForObject('http://localhost:' + port + '/info', String)
@ -36,7 +42,7 @@ class IntegrationTests {
} }
// CLI compliled classes are not @ComponentScannable so we have to create // CLI compiled classes are not @ComponentScannable so we have to create
// an explicit configuration for the test // an explicit configuration for the test
@Configuration @Configuration
@Import([app.MainController, app.Projects, app.TemporaryFileCleaner]) @Import([app.MainController, app.Projects, app.TemporaryFileCleaner])