mirror of
https://gitee.com/dcren/initializr.git
synced 2025-07-15 23:13:30 +08:00
Initializr library
This commit splits the single file script in a library that can be released and published to the central repository. This allows anyone to start its own initializr instance with a proper configuration file and the following simple script: package app @Grab('io.spring.initalizr:initializr:1.0.0.BUILD-SNAPSHOT') class InitializerService { } The integration tests have been migrated so that they run as part of the build. Additional tests have been added to extract the content of the generated archive and assert the directory structure as well as the content of key files. Fixes gh-20
This commit is contained in:
parent
4fbec9e0c0
commit
1ea33488f6
2
.gitignore
vendored
2
.gitignore
vendored
@ -13,7 +13,7 @@ build
|
||||
target
|
||||
.springBeans
|
||||
tmp*
|
||||
spring
|
||||
initializer-service/spring
|
||||
grapes
|
||||
spring.zip
|
||||
repository/
|
||||
|
23
README.md
23
README.md
@ -30,10 +30,31 @@ Windows users we recommend [cygwin](http://cygwin.org)), or you can
|
||||
download the [zip file](http://start.spring.io/spring.zip) and unpack
|
||||
it yourself.
|
||||
|
||||
## Project structure
|
||||
|
||||
Initializr is a library that provides all the default features and a service with a very simple script
|
||||
that uses the auto-configuration feature of Spring Boot. All you need is _grabbing_ the library and
|
||||
create a proper configuration file with the following script:
|
||||
|
||||
```
|
||||
package org.acme.myapp
|
||||
|
||||
@Grab('io.spring.initalizr:initializr:1.0.0.BUILD-SNAPSHOT')
|
||||
class InitializerService { }
|
||||
```
|
||||
|
||||
As a reference, `initializr-service` represents the _default_ service that runs at http://start.spring.io
|
||||
|
||||
<a name="running_the_app"></a>
|
||||
## Running the app locally
|
||||
|
||||
Use the spring command:
|
||||
First make sure that you have built the library:
|
||||
|
||||
$ cd initializr
|
||||
$ mvn clean install
|
||||
|
||||
Once you have done that, you can easily start the app using the spring command from the `initializr-service`
|
||||
directory (`cd ../initializr-service`):
|
||||
|
||||
$ spring run app.groovy
|
||||
|
||||
|
301
app.groovy
301
app.groovy
@ -1,301 +0,0 @@
|
||||
package app
|
||||
|
||||
@Grab('spring-boot-starter-actuator')
|
||||
@Grab('org.codehaus.groovy:groovy-ant:2.3.2')
|
||||
|
||||
@Controller
|
||||
@Log
|
||||
class MainController {
|
||||
|
||||
@Value('${info.home:http://localhost:8080/}')
|
||||
private String home
|
||||
|
||||
@Value('${info.spring-boot.version}')
|
||||
private String bootVersion
|
||||
|
||||
@Value('${TMPDIR:.}')
|
||||
private String tmpdir
|
||||
|
||||
@Autowired
|
||||
private Reactor reactor
|
||||
|
||||
@Autowired
|
||||
private Projects projects
|
||||
|
||||
@ModelAttribute
|
||||
PomRequest pomRequest() {
|
||||
PomRequest request = new PomRequest()
|
||||
request.bootVersion = bootVersion
|
||||
request
|
||||
}
|
||||
|
||||
@RequestMapping(value='/')
|
||||
@ResponseBody
|
||||
Projects projects() {
|
||||
projects
|
||||
}
|
||||
|
||||
@RequestMapping(value='/', produces='text/html')
|
||||
@ResponseBody
|
||||
String home() {
|
||||
def model = [:]
|
||||
projects.properties.each { model[it.key] = it.value }
|
||||
template 'home.html', model
|
||||
}
|
||||
|
||||
@RequestMapping('/spring')
|
||||
@ResponseBody
|
||||
ResponseEntity<byte[]> spring() {
|
||||
File download = new File(tmpdir, 'spring.zip')
|
||||
if (!download.exists()) {
|
||||
log.info('Creating: ' + download)
|
||||
new AntBuilder().zip(destfile: download) {
|
||||
zipfileset(dir:'.', includes:'spring/bin/**', filemode:'775')
|
||||
zipfileset(dir:'.', includes:'spring/**', excludes:'spring/bin/**')
|
||||
}
|
||||
}
|
||||
log.info('Uploading: ' + download)
|
||||
new ResponseEntity<byte[]>(download.bytes, ['Content-Type':'application/zip'] as HttpHeaders, HttpStatus.OK)
|
||||
}
|
||||
|
||||
@RequestMapping(value='/starter.tgz', produces='application/x-compress')
|
||||
@ResponseBody
|
||||
ResponseEntity<byte[]> springTgz(PomRequest request) {
|
||||
|
||||
File dir = getProjectFiles(request)
|
||||
|
||||
File download = new File(tmpdir, dir.name + '.tgz')
|
||||
addTempFile(dir.name, download)
|
||||
|
||||
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)
|
||||
|
||||
cleanTempFiles(dir.name)
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
@RequestMapping('/starter.zip')
|
||||
@ResponseBody
|
||||
ResponseEntity<byte[]> springZip(PomRequest request) {
|
||||
|
||||
def dir = getProjectFiles(request)
|
||||
|
||||
File download = new File(tmpdir, dir.name + '.zip')
|
||||
addTempFile(dir.name, download)
|
||||
|
||||
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)
|
||||
|
||||
cleanTempFiles(dir.name)
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
private void addTempFile(String group, File file) {
|
||||
reactor.notify('/temp/' + group, Event.wrap(file))
|
||||
}
|
||||
|
||||
private void cleanTempFiles(String group) {
|
||||
reactor.notify('/clean/' + group)
|
||||
}
|
||||
|
||||
def getProjectFiles(PomRequest request) {
|
||||
|
||||
def model = [:]
|
||||
|
||||
File dir = File.createTempFile('tmp','',new File(tmpdir));
|
||||
addTempFile(dir.name, dir)
|
||||
dir.delete()
|
||||
dir.mkdirs()
|
||||
|
||||
if (request.type.contains('gradle')) {
|
||||
String gradle = new String(gradle(request, model).body)
|
||||
new File(dir, 'build.gradle').write(gradle)
|
||||
} else {
|
||||
String pom = new String(pom(request, model).body)
|
||||
new File(dir, 'pom.xml').write(pom)
|
||||
}
|
||||
|
||||
String language = request.language
|
||||
|
||||
File src = new File(new File(dir, 'src/main/' + language),request.packageName.replace('.', '/'))
|
||||
src.mkdirs()
|
||||
write(src, 'Application.' + language, model)
|
||||
|
||||
if (request.packaging=='war') {
|
||||
write(src, 'ServletInitializer.' + language, model)
|
||||
}
|
||||
|
||||
File test = new File(new File(dir, 'src/test/' + language),request.packageName.replace('.', '/'))
|
||||
test.mkdirs()
|
||||
if (model.styles.contains('-web')) {
|
||||
model.testAnnotations = '@WebAppConfiguration\n'
|
||||
model.testImports = 'import org.springframework.test.context.web.WebAppConfiguration;\n'
|
||||
} else {
|
||||
model.testAnnotations = ''
|
||||
model.testImports = ''
|
||||
}
|
||||
write(test, 'ApplicationTests.' + language, model)
|
||||
|
||||
File resources = new File(dir, 'src/main/resources')
|
||||
resources.mkdirs()
|
||||
new File(resources, 'application.properties').write('')
|
||||
|
||||
if (request.isWebStyle()) {
|
||||
new File(dir, 'src/main/resources/templates').mkdirs()
|
||||
new File(dir, 'src/main/resources/static').mkdirs()
|
||||
}
|
||||
|
||||
dir
|
||||
|
||||
}
|
||||
|
||||
def write(File src, String name, def model) {
|
||||
String tmpl = name.endsWith('.groovy') ? name + '.tmpl' : name
|
||||
def body = template tmpl, model
|
||||
new File(src, name).write(body)
|
||||
}
|
||||
|
||||
@RequestMapping('/pom')
|
||||
@ResponseBody
|
||||
ResponseEntity<byte[]> pom(PomRequest request, Map model) {
|
||||
model.bootVersion = request.bootVersion
|
||||
new ResponseEntity<byte[]>(render('starter-pom.xml', request, model), ['Content-Type':'application/octet-stream'] as HttpHeaders, HttpStatus.OK)
|
||||
|
||||
}
|
||||
|
||||
@RequestMapping('/build')
|
||||
@ResponseBody
|
||||
ResponseEntity<byte[]> gradle(PomRequest request, Map model) {
|
||||
model.bootVersion = request.bootVersion
|
||||
new ResponseEntity<byte[]>(render('starter-build.gradle', request, model), ['Content-Type':'application/octet-stream'] as HttpHeaders, HttpStatus.OK)
|
||||
}
|
||||
|
||||
byte[] render(String path, PomRequest request, Map model) {
|
||||
if (request.packaging=='war' && !request.isWebStyle()) {
|
||||
request.style << 'web'
|
||||
}
|
||||
log.info("Styles requested: ${request.style}, Type requested: ${request.type}")
|
||||
request.properties.each { model[it.key] = it.value }
|
||||
model.styles = fixStyles(request.style)
|
||||
template path, model
|
||||
}
|
||||
|
||||
private def fixStyles(def style) {
|
||||
if (style==null || style.size()==0) {
|
||||
style = ['']
|
||||
}
|
||||
if (!style.class.isArray() && !(style instanceof Collection)) {
|
||||
style = [style]
|
||||
}
|
||||
style = style.collect{ it=='jpa' ? 'data-jpa' : it }
|
||||
style.collect{ it=='' ? '' : '-' + it }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EnableReactor
|
||||
@Consumer
|
||||
@Log
|
||||
class TemporaryFileCleaner {
|
||||
|
||||
@Autowired
|
||||
Reactor reactor
|
||||
|
||||
private Map files = [:].withDefault { [] }
|
||||
|
||||
@Selector(value='/temp/{stem}', type=SelectorType.URI)
|
||||
void add(Event<File> file) {
|
||||
String stem = file.headers.stem
|
||||
files[stem] << file.data
|
||||
}
|
||||
|
||||
@Selector(value='/clean/{stem}', type=SelectorType.URI)
|
||||
void clean(Event<File> event) {
|
||||
String stem = event.headers.stem
|
||||
def tempFiles = files.remove(stem)
|
||||
log.fine 'Tempfiles: ' + tempFiles
|
||||
tempFiles.each { File file ->
|
||||
if (file.directory) {
|
||||
file.deleteDir()
|
||||
} else {
|
||||
file.delete()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class PomRequest {
|
||||
def style = []
|
||||
|
||||
String name = 'demo'
|
||||
String type = 'starter'
|
||||
String description = 'Demo project for Spring Boot'
|
||||
String groupId = 'org.test'
|
||||
String artifactId
|
||||
String version = '0.0.1-SNAPSHOT'
|
||||
String bootVersion
|
||||
String packaging = 'jar'
|
||||
String language = 'java'
|
||||
String packageName
|
||||
String javaVersion = '1.7'
|
||||
String getArtifactId() {
|
||||
artifactId == null ? name : artifactId
|
||||
}
|
||||
String getPackageName() {
|
||||
packageName == null ? name.replace('-', '.') : packageName
|
||||
}
|
||||
boolean isWebStyle() {
|
||||
style.any { webStyle(it) }
|
||||
}
|
||||
private boolean webStyle(String style) {
|
||||
style.contains('web') || style.contains('thymeleaf') || style.contains('freemarker') || style.contains('velocity') || style.contains('groovy-template')
|
||||
}
|
||||
}
|
||||
|
||||
@Component
|
||||
@ConfigurationProperties(prefix='projects', ignoreUnknownFields=false)
|
||||
class Projects {
|
||||
List<Style> styles
|
||||
List<Type> types
|
||||
List<Packaging> packagings
|
||||
List<JavaVersion> javaVersions
|
||||
List<Language> languages
|
||||
List<BootVersion> bootVersions
|
||||
static class Language {
|
||||
String name
|
||||
String value
|
||||
boolean selected
|
||||
}
|
||||
static class JavaVersion {
|
||||
String value
|
||||
boolean selected
|
||||
}
|
||||
static class Packaging {
|
||||
String name
|
||||
String value
|
||||
boolean selected
|
||||
}
|
||||
static class Type {
|
||||
String name
|
||||
String action
|
||||
String value
|
||||
boolean selected
|
||||
}
|
||||
static class BootVersion {
|
||||
String value
|
||||
boolean selected
|
||||
}
|
||||
static class Style {
|
||||
String name
|
||||
List<Map<String,Object>> starters
|
||||
}
|
||||
}
|
4
initializr-service/app.groovy
Normal file
4
initializr-service/app.groovy
Normal file
@ -0,0 +1,4 @@
|
||||
package app
|
||||
|
||||
@Grab('io.spring.initalizr:initializr:1.0.0.BUILD-SNAPSHOT')
|
||||
class InitializerService { }
|
@ -1,13 +1,13 @@
|
||||
info:
|
||||
project:
|
||||
name: Spring Start
|
||||
version: 0.2.1
|
||||
version: 0.3.0
|
||||
# remember to update static/install.sh as well:
|
||||
spring-boot:
|
||||
version: 1.1.5.RELEASE
|
||||
|
||||
projects:
|
||||
styles:
|
||||
initializr:
|
||||
dependencies:
|
||||
- name: Core
|
||||
starters:
|
||||
- name: Security
|
||||
@ -71,47 +71,50 @@ projects:
|
||||
- name: Remote Shell
|
||||
value: remote-shell
|
||||
types:
|
||||
- name: Maven POM
|
||||
action: /pom.xml
|
||||
value: pom.xml
|
||||
selected: false
|
||||
- name: Maven Project
|
||||
action: /starter.zip
|
||||
value: starter.zip
|
||||
selected: true
|
||||
- name: Gradle Config
|
||||
action: /build.gradle
|
||||
value: build.gradle
|
||||
selected: false
|
||||
- name: Gradle Project
|
||||
action: /starter.zip
|
||||
value: gradle.zip
|
||||
selected: false
|
||||
- name: Maven POM
|
||||
id: pom.xml
|
||||
default: false
|
||||
action: /pom.xml
|
||||
- name: Maven Project
|
||||
id: starter.zip
|
||||
default: true
|
||||
action: /starter.zip
|
||||
- name: Gradle Config
|
||||
id: build.gradle
|
||||
default: false
|
||||
action: /build.gradle
|
||||
- name: Gradle Project
|
||||
id: gradle.zip
|
||||
default: false
|
||||
action: /starter.zip
|
||||
packagings:
|
||||
- name: Jar
|
||||
value: jar
|
||||
selected: true
|
||||
id: jar
|
||||
default: true
|
||||
- name: War
|
||||
value: war
|
||||
selected: false
|
||||
id: war
|
||||
default: false
|
||||
javaVersions:
|
||||
- value: 1.6
|
||||
selected: false
|
||||
- value: 1.7
|
||||
selected: true
|
||||
- value: 1.8
|
||||
selected: false
|
||||
- id: 1.6
|
||||
default: false
|
||||
- id: 1.7
|
||||
default: true
|
||||
- id: 1.8
|
||||
default: false
|
||||
languages:
|
||||
- name: Groovy
|
||||
value: groovy
|
||||
selected: false
|
||||
id: groovy
|
||||
default: false
|
||||
- name: Java
|
||||
value: java
|
||||
selected: true
|
||||
id: java
|
||||
default: true
|
||||
bootVersions:
|
||||
- value: 1.2.0.BUILD-SNAPSHOT
|
||||
selected: false
|
||||
- value: 1.1.5.RELEASE
|
||||
selected: true
|
||||
- value: 1.0.2.RELEASE
|
||||
selected: false
|
||||
- name : Latest SNAPSHOT
|
||||
id: 1.2.0.BUILD-SNAPSHOT
|
||||
default: false
|
||||
- name: 1.1.5
|
||||
id: 1.1.5.RELEASE
|
||||
default: true
|
||||
- name: 1.0.2
|
||||
id: 1.0.2.RELEASE
|
||||
default: false
|
125
initializr/pom.xml
Normal file
125
initializr/pom.xml
Normal file
@ -0,0 +1,125 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>io.spring.initalizr</groupId>
|
||||
<artifactId>initializr</artifactId>
|
||||
<version>1.0.0.BUILD-SNAPSHOT</version>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<spring.boot.version>1.1.5.RELEASE</spring.boot.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-webmvc</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-groovy-templates</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-core</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.codehaus.groovy</groupId>
|
||||
<artifactId>groovy</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.groovy</groupId>
|
||||
<artifactId>groovy-ant</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>xmlunit</groupId>
|
||||
<artifactId>xmlunit</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-dependencies</artifactId>
|
||||
<version>${spring.boot.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>xmlunit</groupId>
|
||||
<artifactId>xmlunit</artifactId>
|
||||
<version>1.5</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<build>
|
||||
<sourceDirectory>src/main/groovy</sourceDirectory>
|
||||
<testSourceDirectory>src/test/groovy</testSourceDirectory>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.1</version>
|
||||
<configuration>
|
||||
<compilerId>groovy-eclipse-compiler</compilerId>
|
||||
</configuration>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.groovy</groupId>
|
||||
<artifactId>groovy-eclipse-compiler</artifactId>
|
||||
<version>2.8.0-01</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.groovy</groupId>
|
||||
<artifactId>groovy-eclipse-batch</artifactId>
|
||||
<version>2.1.8-01</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>2.16</version>
|
||||
<configuration>
|
||||
<includes>
|
||||
<include>**/*Tests.java</include>
|
||||
</includes>
|
||||
<excludes>
|
||||
<exclude>**/Abstract*.java</exclude>
|
||||
</excludes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.groovy</groupId>
|
||||
<artifactId>groovy-eclipse-compiler</artifactId>
|
||||
<version>2.8.0-01</version>
|
||||
<extensions>true</extensions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
@ -0,0 +1,37 @@
|
||||
package io.spring.initializr
|
||||
|
||||
import io.spring.initializr.web.MainController
|
||||
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties
|
||||
import org.springframework.context.annotation.Bean
|
||||
import org.springframework.context.annotation.Configuration
|
||||
|
||||
/**
|
||||
* {@link org.springframework.boot.autoconfigure.EnableAutoConfiguration
|
||||
* Auto-configuration} to configure Spring initializr. In a web environment,
|
||||
* configures the necessary controller to serve the applications from the
|
||||
* root context.
|
||||
*
|
||||
* <p>Project generation can be customized by defining a custom
|
||||
* {@link ProjectGenerator}.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @since 1.0
|
||||
*/
|
||||
@Configuration
|
||||
@EnableConfigurationProperties(InitializrMetadata.class)
|
||||
class InitializrAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(MainController.class)
|
||||
MainController initializrMainController() {
|
||||
new MainController()
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(ProjectGenerator.class)
|
||||
ProjectGenerator projectGenerator() {
|
||||
new ProjectGenerator()
|
||||
}
|
||||
}
|
@ -0,0 +1,106 @@
|
||||
package io.spring.initializr
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore
|
||||
import com.fasterxml.jackson.annotation.JsonInclude
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties
|
||||
|
||||
/**
|
||||
* The metadata using by the initializr, that is:
|
||||
*
|
||||
* <ul>
|
||||
* <li>Known dependencies gathered in group</li>
|
||||
* <li>The build types supported by the service</li>
|
||||
* <li>Supported Java versions</li>
|
||||
* <li>Supported language</li>
|
||||
* <li>Supported Spring Boot versions</li>
|
||||
* </ul>
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @since 1.0
|
||||
*/
|
||||
@ConfigurationProperties(prefix = 'initializr', ignoreUnknownFields = false)
|
||||
class InitializrMetadata {
|
||||
|
||||
final List<DependencyGroup> dependencies = new ArrayList<DependencyGroup>()
|
||||
|
||||
final List<Type> types = new ArrayList<Type>()
|
||||
|
||||
final List<Packaging> packagings = new ArrayList<Packaging>()
|
||||
|
||||
final List<JavaVersion> javaVersions = new ArrayList<JavaVersion>()
|
||||
|
||||
final List<Language> languages = new ArrayList<Language>()
|
||||
|
||||
final List<BootVersion> bootVersions = new ArrayList<BootVersion>()
|
||||
|
||||
/**
|
||||
* Initializes a {@link ProjectRequest} instance with the defaults
|
||||
* defined in this instance.
|
||||
*/
|
||||
void initializeProjectRequest(ProjectRequest request) {
|
||||
request.bootVersion = getDefault(bootVersions, request.bootVersion)
|
||||
request
|
||||
}
|
||||
|
||||
static def getDefault(List elements, String defaultValue) {
|
||||
for (DefaultIdentifiableElement element : elements) {
|
||||
if (element.default) {
|
||||
return element.id
|
||||
}
|
||||
}
|
||||
return defaultValue
|
||||
}
|
||||
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
static class DependencyGroup {
|
||||
|
||||
String name
|
||||
|
||||
final List<Map<String,Object>> starters= new ArrayList<>()
|
||||
|
||||
}
|
||||
|
||||
static class Type extends DefaultIdentifiableElement {
|
||||
|
||||
String action
|
||||
}
|
||||
|
||||
static class Packaging extends DefaultIdentifiableElement {
|
||||
}
|
||||
|
||||
static class JavaVersion extends DefaultIdentifiableElement {
|
||||
}
|
||||
|
||||
static class Language extends DefaultIdentifiableElement {
|
||||
}
|
||||
|
||||
static class BootVersion extends DefaultIdentifiableElement {
|
||||
}
|
||||
|
||||
static class DefaultIdentifiableElement extends IdentifiableElement {
|
||||
|
||||
@JsonIgnore
|
||||
private boolean defaultValue
|
||||
|
||||
void setDefault(boolean defaultValue) {
|
||||
this.defaultValue = defaultValue
|
||||
}
|
||||
|
||||
boolean isDefault() {
|
||||
return this.defaultValue
|
||||
}
|
||||
}
|
||||
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
static class IdentifiableElement {
|
||||
|
||||
String name
|
||||
|
||||
String id
|
||||
|
||||
String getName() {
|
||||
(name != null ? name : id)
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,171 @@
|
||||
package io.spring.initializr
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import org.springframework.beans.factory.annotation.Value
|
||||
import org.springframework.util.Assert
|
||||
|
||||
import static io.spring.initializr.support.GroovyTemplate.template
|
||||
|
||||
/**
|
||||
* Generate a project based on the configured metadata.
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @author Stephane Nicoll
|
||||
* @since 1.0
|
||||
*/
|
||||
class ProjectGenerator {
|
||||
|
||||
@Autowired
|
||||
InitializrMetadata metadata
|
||||
|
||||
@Value('${TMPDIR:.}')
|
||||
String tmpdir
|
||||
|
||||
private transient Map<String, List<File>> temporaryFiles = new HashMap<>()
|
||||
|
||||
/**
|
||||
* Generate a Maven pom for the specified {@link ProjectRequest}.
|
||||
*/
|
||||
byte[] generateMavenPom(ProjectRequest request) {
|
||||
Map model = initializeModel(request)
|
||||
doGenerateMavenPom(model)
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a Gradle build file for the specified {@link ProjectRequest}.
|
||||
*/
|
||||
byte[] generateGradleBuild(ProjectRequest request) {
|
||||
Map model = initializeModel(request)
|
||||
doGenerateGradleBuild(model)
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a project structure for the specified {@link ProjectRequest}. Returns
|
||||
* a directory containing the project.
|
||||
*/
|
||||
File generateProjectStructure(ProjectRequest request) {
|
||||
def model = initializeModel(request)
|
||||
|
||||
File dir = File.createTempFile('tmp', '', new File(tmpdir))
|
||||
addTempFile(dir.name, dir)
|
||||
dir.delete()
|
||||
dir.mkdirs()
|
||||
|
||||
if (request.type.contains('gradle')) {
|
||||
String gradle = new String(doGenerateGradleBuild(model))
|
||||
new File(dir, 'build.gradle').write(gradle)
|
||||
} else {
|
||||
String pom = new String(doGenerateMavenPom(model))
|
||||
new File(dir, 'pom.xml').write(pom)
|
||||
}
|
||||
|
||||
String language = request.language
|
||||
|
||||
File src = new File(new File(dir, 'src/main/' + language), request.packageName.replace('.', '/'))
|
||||
src.mkdirs()
|
||||
write(src, 'Application.' + language, model)
|
||||
|
||||
if (request.packaging == 'war') {
|
||||
write(src, 'ServletInitializer.' + language, model)
|
||||
}
|
||||
|
||||
File test = new File(new File(dir, 'src/test/' + language), request.packageName.replace('.', '/'))
|
||||
test.mkdirs()
|
||||
if (request.isWebStyle()) {
|
||||
model.testAnnotations = '@WebAppConfiguration\n'
|
||||
model.testImports = 'import org.springframework.test.context.web.WebAppConfiguration;\n'
|
||||
} else {
|
||||
model.testAnnotations = ''
|
||||
model.testImports = ''
|
||||
}
|
||||
write(test, 'ApplicationTests.' + language, model)
|
||||
|
||||
File resources = new File(dir, 'src/main/resources')
|
||||
resources.mkdirs()
|
||||
new File(resources, 'application.properties').write('')
|
||||
|
||||
if (request.isWebStyle()) {
|
||||
new File(dir, 'src/main/resources/templates').mkdirs()
|
||||
new File(dir, 'src/main/resources/static').mkdirs()
|
||||
}
|
||||
|
||||
dir
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a distribution file for the specified project structure
|
||||
* directory and extension
|
||||
*/
|
||||
File createDistributionFile(File dir, String extension) {
|
||||
File download = new File(tmpdir, dir.name + extension)
|
||||
addTempFile(dir.name, download)
|
||||
download
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean all the temporary files that are related to this root
|
||||
* directory.
|
||||
* @see #createDistributionFile
|
||||
*/
|
||||
void cleanTempFiles(File dir) {
|
||||
def tempFiles = temporaryFiles.remove(dir.name)
|
||||
if (tempFiles != null) {
|
||||
tempFiles.each { File file ->
|
||||
if (file.directory) {
|
||||
file.deleteDir()
|
||||
} else {
|
||||
file.delete()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Map initializeModel(ProjectRequest request) {
|
||||
Assert.notNull request.bootVersion, 'boot version must not be null'
|
||||
if (request.packaging == 'war' && !request.isWebStyle()) {
|
||||
request.style << 'web'
|
||||
}
|
||||
def model = [:]
|
||||
request.properties.each { model[it.key] = it.value }
|
||||
model.styles = fixStyles(request.style)
|
||||
model
|
||||
}
|
||||
|
||||
private def fixStyles(def style) {
|
||||
if (style == null || style.size() == 0) {
|
||||
style = ['']
|
||||
}
|
||||
if (!style.class.isArray() && !(style instanceof Collection)) {
|
||||
style = [style]
|
||||
}
|
||||
style = style.collect { it == 'jpa' ? 'data-jpa' : it }
|
||||
style.collect { it == '' ? '' : '-' + it }
|
||||
}
|
||||
|
||||
|
||||
private byte[] doGenerateMavenPom(Map model) {
|
||||
template 'starter-pom.xml', model
|
||||
}
|
||||
|
||||
|
||||
private byte[] doGenerateGradleBuild(Map model) {
|
||||
template 'starter-build.gradle', model
|
||||
}
|
||||
|
||||
def write(File src, String name, def model) {
|
||||
String tmpl = name.endsWith('.groovy') ? name + '.tmpl' : name
|
||||
def body = template tmpl, model
|
||||
new File(src, name).write(body)
|
||||
}
|
||||
|
||||
private void addTempFile(String group, File file) {
|
||||
def content = temporaryFiles.get(group)
|
||||
if (content == null) {
|
||||
content = new ArrayList<File>()
|
||||
temporaryFiles.put(group, content)
|
||||
}
|
||||
content.add(file)
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
package io.spring.initializr
|
||||
/**
|
||||
* A request to generate a project.
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @since 1.0
|
||||
*/
|
||||
class ProjectRequest {
|
||||
|
||||
def style = []
|
||||
|
||||
String name = 'demo'
|
||||
String type = 'starter'
|
||||
String description = 'Demo project for Spring Boot'
|
||||
String groupId = 'org.test'
|
||||
String artifactId
|
||||
String version = '0.0.1-SNAPSHOT'
|
||||
String bootVersion
|
||||
String packaging = 'jar'
|
||||
String language = 'java'
|
||||
String packageName
|
||||
String javaVersion = '1.7'
|
||||
|
||||
String getArtifactId() {
|
||||
artifactId == null ? name : artifactId
|
||||
}
|
||||
String getPackageName() {
|
||||
packageName == null ? name.replace('-', '.') : packageName
|
||||
}
|
||||
|
||||
boolean isWebStyle() {
|
||||
style.any { webStyle(it) }
|
||||
}
|
||||
|
||||
private boolean webStyle(String style) {
|
||||
style.contains('web') || style.contains('thymeleaf') || style.contains('freemarker') || style.contains('velocity') || style.contains('groovy-template')
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 2012-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.spring.initializr.support
|
||||
|
||||
import groovy.text.GStringTemplateEngine
|
||||
import groovy.text.Template
|
||||
import groovy.text.TemplateEngine
|
||||
import org.codehaus.groovy.control.CompilationFailedException
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
* @since 1.0
|
||||
*/
|
||||
class GroovyTemplate {
|
||||
|
||||
// This is a copy/paste from GroovyTemplate in spring-boot-cli. We should migrate
|
||||
// to Spring's native support available in 4.1
|
||||
|
||||
static String template(String name, Map<String, ?> model) throws IOException,
|
||||
CompilationFailedException, ClassNotFoundException {
|
||||
return template(new GStringTemplateEngine(), name, model)
|
||||
}
|
||||
|
||||
static String template(TemplateEngine engine, String name, Map<String, ?> model)
|
||||
throws IOException, CompilationFailedException, ClassNotFoundException {
|
||||
Writable writable = getTemplate(engine, name).make(model)
|
||||
StringWriter result = new StringWriter()
|
||||
writable.writeTo(result)
|
||||
return result.toString()
|
||||
}
|
||||
|
||||
static Template getTemplate(TemplateEngine engine, String name)
|
||||
throws CompilationFailedException, ClassNotFoundException, IOException {
|
||||
|
||||
File file = new File("templates", name)
|
||||
if (file.exists()) {
|
||||
return engine.createTemplate(file)
|
||||
}
|
||||
|
||||
ClassLoader classLoader = GroovyTemplate.class.getClassLoader()
|
||||
URL resource = classLoader.getResource("templates/" + name)
|
||||
if (resource != null) {
|
||||
return engine.createTemplate(resource)
|
||||
}
|
||||
|
||||
return engine.createTemplate(name)
|
||||
}
|
||||
}
|
@ -0,0 +1,111 @@
|
||||
package io.spring.initializr.web
|
||||
|
||||
import io.spring.initializr.InitializrMetadata
|
||||
import io.spring.initializr.ProjectGenerator
|
||||
import io.spring.initializr.ProjectRequest
|
||||
import org.slf4j.Logger
|
||||
import org.slf4j.LoggerFactory
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import org.springframework.http.HttpHeaders
|
||||
import org.springframework.http.HttpStatus
|
||||
import org.springframework.http.ResponseEntity
|
||||
import org.springframework.stereotype.Controller
|
||||
import org.springframework.web.bind.annotation.ModelAttribute
|
||||
import org.springframework.web.bind.annotation.RequestMapping
|
||||
import org.springframework.web.bind.annotation.ResponseBody
|
||||
|
||||
import static io.spring.initializr.support.GroovyTemplate.template
|
||||
|
||||
/**
|
||||
* The main initializr controller provides access to the configured
|
||||
* metadata and serves as a central endpoint to generate projects
|
||||
* or build files.
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @author Stephane Nicoll
|
||||
* @since 1.0
|
||||
*/
|
||||
@Controller
|
||||
class MainController {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(MainController.class)
|
||||
|
||||
@Autowired
|
||||
private InitializrMetadata metadata
|
||||
|
||||
@Autowired
|
||||
private ProjectGenerator projectGenerator
|
||||
|
||||
@ModelAttribute
|
||||
ProjectRequest projectRequest() {
|
||||
ProjectRequest request = new ProjectRequest();
|
||||
metadata.initializeProjectRequest(request)
|
||||
request
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/")
|
||||
@ResponseBody
|
||||
InitializrMetadata metadata() {
|
||||
metadata
|
||||
}
|
||||
|
||||
@RequestMapping(value = '/', produces = 'text/html')
|
||||
@ResponseBody
|
||||
String home() {
|
||||
def model = [:]
|
||||
metadata.properties.each { model[it.key] = it.value }
|
||||
template 'home.html', model
|
||||
}
|
||||
|
||||
@RequestMapping('/pom')
|
||||
@ResponseBody
|
||||
ResponseEntity<byte[]> pom(ProjectRequest request) {
|
||||
def mavenPom = projectGenerator.generateMavenPom(request)
|
||||
new ResponseEntity<byte[]>(mavenPom, ['Content-Type': 'application/octet-stream'] as HttpHeaders, HttpStatus.OK)
|
||||
}
|
||||
|
||||
@RequestMapping('/build')
|
||||
@ResponseBody
|
||||
ResponseEntity<byte[]> gradle(ProjectRequest request) {
|
||||
def gradleBuild = projectGenerator.generateGradleBuild(request)
|
||||
new ResponseEntity<byte[]>(gradleBuild, ['Content-Type': 'application/octet-stream'] as HttpHeaders, HttpStatus.OK)
|
||||
}
|
||||
|
||||
@RequestMapping('/starter.zip')
|
||||
@ResponseBody
|
||||
ResponseEntity<byte[]> springZip(ProjectRequest request) {
|
||||
def dir = projectGenerator.generateProjectStructure(request)
|
||||
|
||||
File download = projectGenerator.createDistributionFile(dir, '.zip')
|
||||
|
||||
new AntBuilder().zip(destfile: download) {
|
||||
zipfileset(dir: dir, includes: '**')
|
||||
}
|
||||
logger.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
|
||||
}
|
||||
|
||||
@RequestMapping(value='/starter.tgz', produces='application/x-compress')
|
||||
@ResponseBody
|
||||
ResponseEntity<byte[]> springTgz(ProjectRequest request) {
|
||||
def dir = projectGenerator.generateProjectStructure(request)
|
||||
|
||||
File download = projectGenerator.createDistributionFile(dir, '.tgz')
|
||||
|
||||
new AntBuilder().tar(destfile: download, compression: 'gzip') {
|
||||
zipfileset(dir:dir, includes:'**')
|
||||
}
|
||||
logger.info("Uploading: ${download} (${download.bytes.length} bytes)")
|
||||
def result = new ResponseEntity<byte[]>(download.bytes,
|
||||
['Content-Type':'application/x-compress'] as HttpHeaders, HttpStatus.OK)
|
||||
|
||||
projectGenerator.cleanTempFiles(dir)
|
||||
result
|
||||
}
|
||||
|
||||
}
|
1
initializr/src/main/resources/META-INF/spring.factories
Normal file
1
initializr/src/main/resources/META-INF/spring.factories
Normal file
@ -0,0 +1 @@
|
||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=io.spring.initializr.InitializrAutoConfiguration
|
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 62 KiB |
Before Width: | Height: | Size: 528 B After Width: | Height: | Size: 528 B |
Before Width: | Height: | Size: 8.9 KiB After Width: | Height: | Size: 8.9 KiB |
@ -57,9 +57,9 @@
|
||||
<div class="form-group">
|
||||
<label for="type" class="col-md-3 control-label">Type</label>
|
||||
<div class="col-md-8">
|
||||
<select class="form-control" id="type" name="packaging" onchange="javascript:updateForm(this)">
|
||||
<select class="form-control" id="type" name="type" onchange="javascript:updateForm(this)">
|
||||
<% types.each { %>
|
||||
<option data-action="${it.action}" value="${it.value}" ${it.selected==true ? ' selected' : ''}>${it.name}</option>
|
||||
<option data-action="${it.action}" value="${it.id}" ${it.default==true ? ' selected' : ''}>${it.name}</option>
|
||||
<% } %>
|
||||
</select>
|
||||
</div>
|
||||
@ -69,7 +69,7 @@
|
||||
<div class="col-md-8">
|
||||
<select class="form-control" id="packaging" name="packaging">
|
||||
<% packagings.each { %>
|
||||
<option value="${it.value}" ${it.selected==true ? ' selected' : ''}>${it.name}</option>
|
||||
<option value="${it.id}" ${it.default==true ? ' selected' : ''}>${it.name}</option>
|
||||
<% } %>
|
||||
</select>
|
||||
</div>
|
||||
@ -79,7 +79,7 @@
|
||||
<div class="col-md-8">
|
||||
<select class="form-control" name="javaVersion" id="javaVersion">
|
||||
<% javaVersions.each { %>
|
||||
<option value="${it.value}" ${it.selected==true ? ' selected' : ''}>${it.value}</option>
|
||||
<option value="${it.id}" ${it.default==true ? ' selected' : ''}>${it.name}</option>
|
||||
<% } %>
|
||||
</select>
|
||||
</div>
|
||||
@ -89,7 +89,7 @@
|
||||
<div class="col-md-8">
|
||||
<select class="form-control" name="language" id="language">
|
||||
<% languages.each { %>
|
||||
<option value="${it.value}" ${it.selected==true ? ' selected' : ''}>${it.name}</option>
|
||||
<option value="${it.id}" ${it.default==true ? ' selected' : ''}>${it.name}</option>
|
||||
<% } %>
|
||||
</select>
|
||||
</div>
|
||||
@ -99,7 +99,7 @@
|
||||
<div class="col-md-8">
|
||||
<select class="form-control" name="bootVersion" id="bootVersion">
|
||||
<% bootVersions.each { %>
|
||||
<option value="${it.value}" ${it.selected==true ? ' selected' : ''}>${it.value}</option>
|
||||
<option value="${it.id}" ${it.default==true ? ' selected' : ''}>${it.name}</option>
|
||||
<% } %>
|
||||
</select>
|
||||
</div>
|
||||
@ -107,7 +107,7 @@
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<h3>Project dependencies</h3>
|
||||
<% styles.each { %>
|
||||
<% dependencies.each { %>
|
||||
<div class="form-group col-sm-6">
|
||||
<h4>${it.name}</h4>
|
||||
<% it.starters.each { %>
|
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2012-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.spring.initializr
|
||||
|
||||
import org.junit.Test
|
||||
|
||||
import static org.junit.Assert.assertEquals
|
||||
|
||||
/**
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
class InitializrMetadataTests {
|
||||
|
||||
@Test
|
||||
public void getDefaultNoDefault() {
|
||||
List elements = []
|
||||
elements << createJavaVersion('one', false) << createJavaVersion('two', false)
|
||||
assertEquals 'three', InitializrMetadata.getDefault(elements, 'three')
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getDefaultWithDefault() {
|
||||
List elements = []
|
||||
elements << createJavaVersion('one', false) << createJavaVersion('two', true)
|
||||
assertEquals 'two', InitializrMetadata.getDefault(elements, 'three')
|
||||
}
|
||||
|
||||
private static InitializrMetadata.JavaVersion createJavaVersion(String version, boolean selected) {
|
||||
InitializrMetadata.JavaVersion javaVersion = new InitializrMetadata.JavaVersion()
|
||||
javaVersion.id = version
|
||||
javaVersion.default = selected
|
||||
javaVersion
|
||||
}
|
||||
}
|
@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright 2012-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.spring.initializr
|
||||
|
||||
import io.spring.initializr.support.InitializrMetadataBuilder
|
||||
import io.spring.initializr.support.PomAssert
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
|
||||
/**
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
class ProjectGeneratorTests {
|
||||
|
||||
private final ProjectGenerator projectGenerator = new ProjectGenerator()
|
||||
|
||||
@Before
|
||||
void setup() {
|
||||
InitializrMetadata metadata = InitializrMetadataBuilder.withDefaults()
|
||||
.addDependencyGroup('test', 'web', 'security', 'data-jpa', 'aop', 'batch', 'integration').get()
|
||||
projectGenerator.metadata = metadata
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultMavenPom() {
|
||||
ProjectRequest request = createProjectRequest('web')
|
||||
generateMavenPom(request).hasStartClass('demo.Application')
|
||||
.hasNoRepository().hasSpringBootStarterDependency('web')
|
||||
}
|
||||
|
||||
@Test
|
||||
public void mavenPomWithBootSnapshot() {
|
||||
ProjectRequest request = createProjectRequest('web')
|
||||
request.bootVersion = '1.0.1.BUILD-SNAPSHOT'
|
||||
generateMavenPom(request).hasStartClass('demo.Application')
|
||||
.hasSnapshotRepository().hasSpringBootStarterDependency('web')
|
||||
}
|
||||
|
||||
@Test
|
||||
public void mavenWarPomWithoutWebFacet() {
|
||||
ProjectRequest request = createProjectRequest('data-jpa')
|
||||
request.packaging = 'war'
|
||||
generateMavenPom(request).hasStartClass('demo.Application')
|
||||
.hasSpringBootStarterDependency('tomcat')
|
||||
.hasSpringBootStarterDependency('data-jpa')
|
||||
.hasSpringBootStarterDependency('web') // Added by web facet
|
||||
.hasSpringBootStarterDependency('test')
|
||||
.hasDependenciesCount(4)
|
||||
|
||||
}
|
||||
|
||||
PomAssert generateMavenPom(ProjectRequest request) {
|
||||
String content = new String(projectGenerator.generateMavenPom(request))
|
||||
return new PomAssert(content).validateProjectRequest(request)
|
||||
}
|
||||
|
||||
ProjectRequest createProjectRequest(String... styles) {
|
||||
ProjectRequest request = new ProjectRequest()
|
||||
projectGenerator.metadata.initializeProjectRequest(request)
|
||||
request.style.addAll Arrays.asList(styles)
|
||||
request
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Copyright 2012-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.spring.initializr.support
|
||||
|
||||
import io.spring.initializr.InitializrMetadata
|
||||
|
||||
/**
|
||||
* Easily create a {@link InitializrMetadata} instance for testing purposes.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @since 1.0
|
||||
*/
|
||||
class InitializrMetadataBuilder {
|
||||
|
||||
private final InitializrMetadata metadata = new InitializrMetadata()
|
||||
|
||||
|
||||
static InitializrMetadataBuilder withDefaults() {
|
||||
new InitializrMetadataBuilder().addDefaults()
|
||||
}
|
||||
|
||||
InitializrMetadata get() {
|
||||
metadata
|
||||
}
|
||||
|
||||
InitializrMetadataBuilder addDependencyGroup(String name, String... ids) {
|
||||
InitializrMetadata.DependencyGroup group = new InitializrMetadata.DependencyGroup()
|
||||
group.name = name
|
||||
for (String id : ids) {
|
||||
Map<String, Object> starter = new HashMap<>()
|
||||
starter.put('name', id)
|
||||
starter.put('value', id)
|
||||
group.starters.add(starter)
|
||||
}
|
||||
metadata.dependencies.add(group)
|
||||
this
|
||||
}
|
||||
|
||||
InitializrMetadataBuilder addDefaults() {
|
||||
addDefaultTypes().addDefaultPackagings().addDefaultJavaVersions()
|
||||
.addDefaultLanguages().addDefaultBootVersions()
|
||||
}
|
||||
|
||||
InitializrMetadataBuilder addDefaultTypes() {
|
||||
addType('pom.xml', false, '/pom.xml').addType('starter.zip', true, '/starter.zip')
|
||||
.addType('build.gradle', false, '/build.gradle').addType('gradle.zip', false, '/starter.zip')
|
||||
}
|
||||
|
||||
InitializrMetadataBuilder addType(String id, boolean defaultValue, String action) {
|
||||
InitializrMetadata.Type type = new InitializrMetadata.Type();
|
||||
type.id = id
|
||||
type.name = id
|
||||
type.default = defaultValue
|
||||
type.action = action
|
||||
metadata.types.add(type)
|
||||
this
|
||||
}
|
||||
|
||||
InitializrMetadataBuilder addDefaultPackagings() {
|
||||
addPackaging('jar', true).addPackaging('war', false)
|
||||
}
|
||||
|
||||
InitializrMetadataBuilder addPackaging(String id, boolean defaultValue) {
|
||||
InitializrMetadata.Packaging packaging = new InitializrMetadata.Packaging();
|
||||
packaging.id = id
|
||||
packaging.name = id
|
||||
packaging.default = defaultValue
|
||||
metadata.packagings.add(packaging)
|
||||
this
|
||||
}
|
||||
|
||||
InitializrMetadataBuilder addDefaultJavaVersions() {
|
||||
addJavaVersion('1.6', false).addJavaVersion('1.7', true).addJavaVersion('1.8', false)
|
||||
}
|
||||
|
||||
InitializrMetadataBuilder addJavaVersion(String version, boolean defaultValue) {
|
||||
InitializrMetadata.JavaVersion javaVersion = new InitializrMetadata.JavaVersion();
|
||||
javaVersion.id = version
|
||||
javaVersion.name = version
|
||||
javaVersion.default = defaultValue
|
||||
metadata.javaVersions.add(javaVersion)
|
||||
this
|
||||
}
|
||||
|
||||
InitializrMetadataBuilder addDefaultLanguages() {
|
||||
addLanguage('java', true).addPackaging('groovy', false)
|
||||
}
|
||||
|
||||
InitializrMetadataBuilder addLanguage(String id, boolean defaultValue) {
|
||||
InitializrMetadata.Language language = new InitializrMetadata.Language();
|
||||
language.id = id
|
||||
language.name = id
|
||||
language.default = defaultValue
|
||||
metadata.languages.add(language)
|
||||
this
|
||||
}
|
||||
|
||||
InitializrMetadataBuilder addDefaultBootVersions() {
|
||||
addBootVersion('1.0.2.RELEASE', false).addBootVersion('1.1.5.RELEASE', true)
|
||||
.addBootVersion('1.2.0.BUILD-SNAPSHOT', false)
|
||||
}
|
||||
|
||||
InitializrMetadataBuilder addBootVersion(String id, boolean defaultValue) {
|
||||
InitializrMetadata.BootVersion bootVersion = new InitializrMetadata.BootVersion();
|
||||
bootVersion.id = id
|
||||
bootVersion.name = id
|
||||
bootVersion.default = defaultValue
|
||||
metadata.bootVersions.add(bootVersion)
|
||||
this
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,209 @@
|
||||
/*
|
||||
* Copyright 2012-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.spring.initializr.support
|
||||
|
||||
import io.spring.initializr.ProjectRequest
|
||||
import org.custommonkey.xmlunit.SimpleNamespaceContext
|
||||
import org.custommonkey.xmlunit.XMLUnit
|
||||
import org.custommonkey.xmlunit.XpathEngine
|
||||
import org.w3c.dom.Document
|
||||
import org.w3c.dom.Element
|
||||
|
||||
import static org.junit.Assert.assertEquals
|
||||
import static org.junit.Assert.assertNotNull
|
||||
|
||||
/**
|
||||
* XPath assertions that are specific to a standard Maven POM.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @since 1.0
|
||||
*/
|
||||
class PomAssert {
|
||||
|
||||
final XpathEngine eng
|
||||
final Document doc
|
||||
final Map<String, Dependency> dependencies = new HashMap<String, Dependency>()
|
||||
|
||||
PomAssert(String content) {
|
||||
eng = XMLUnit.newXpathEngine()
|
||||
Map<String, String> context = new HashMap<String, String>()
|
||||
context.put 'pom', 'http://maven.apache.org/POM/4.0.0'
|
||||
SimpleNamespaceContext namespaceContext = new SimpleNamespaceContext(context)
|
||||
eng.namespaceContext = namespaceContext
|
||||
doc = XMLUnit.buildControlDocument(content);
|
||||
parseDependencies()
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate that this generated pom validates against its request.
|
||||
*/
|
||||
PomAssert validateProjectRequest(ProjectRequest request) {
|
||||
hasGroupId(request.groupId).hasArtifactId(request.artifactId).hasVersion(request.version).
|
||||
hasPackaging(request.packaging).hasName(request.name).hasDescription(request.description).
|
||||
hasBootVersion(request.bootVersion).hasJavaVersion(request.javaVersion)
|
||||
|
||||
}
|
||||
|
||||
PomAssert hasGroupId(String groupId) {
|
||||
assertEquals groupId, eng.evaluate(createRootNodeXPath('groupId'), doc);
|
||||
this
|
||||
}
|
||||
|
||||
PomAssert hasArtifactId(String artifactId) {
|
||||
assertEquals artifactId, eng.evaluate(createRootNodeXPath('artifactId'), doc);
|
||||
this
|
||||
}
|
||||
|
||||
PomAssert hasVersion(String version) {
|
||||
assertEquals version, eng.evaluate(createRootNodeXPath('version'), doc);
|
||||
this
|
||||
}
|
||||
|
||||
PomAssert hasPackaging(String packaging) {
|
||||
assertEquals packaging, eng.evaluate(createRootNodeXPath('packaging'), doc);
|
||||
this
|
||||
}
|
||||
|
||||
PomAssert hasName(String name) {
|
||||
assertEquals name, eng.evaluate(createRootNodeXPath('name'), doc);
|
||||
this
|
||||
}
|
||||
|
||||
PomAssert hasDescription(String description) {
|
||||
assertEquals description, eng.evaluate(createRootNodeXPath('description'), doc);
|
||||
this
|
||||
}
|
||||
|
||||
PomAssert hasBootVersion(String bootVersion) {
|
||||
assertEquals bootVersion, eng.evaluate(createRootNodeXPath('parent/pom:version'), doc)
|
||||
this
|
||||
}
|
||||
|
||||
PomAssert hasJavaVersion(String javaVersion) {
|
||||
assertEquals javaVersion, eng.evaluate(createPropertyNodeXpath('java.version'), doc)
|
||||
this
|
||||
}
|
||||
|
||||
PomAssert hasStartClass(String fqn) {
|
||||
assertEquals fqn, eng.evaluate(createPropertyNodeXpath('start-class'), doc)
|
||||
this
|
||||
}
|
||||
|
||||
PomAssert hasDependenciesCount(int count) {
|
||||
assertEquals 'Wrong number of declared dependencies -->' + dependencies.keySet(), count, dependencies.size()
|
||||
this
|
||||
}
|
||||
|
||||
PomAssert hasSpringBootStarterDependency(String dependency) {
|
||||
hasDependency('org.springframework.boot', 'spring-boot-starter-' + dependency)
|
||||
}
|
||||
|
||||
PomAssert hasDependency(String groupId, String artifactId) {
|
||||
hasDependency(groupId, artifactId, null)
|
||||
}
|
||||
|
||||
PomAssert hasDependency(String groupId, String artifactId, String version) {
|
||||
def id = generateId(groupId, artifactId)
|
||||
def dependency = dependencies.get(id)
|
||||
assertNotNull 'No dependency found with ' + id + ' --> ' + dependencies.keySet(), dependency
|
||||
if (version != null) {
|
||||
assertEquals 'Wrong version for '+dependency, version, dependency.version
|
||||
}
|
||||
this
|
||||
}
|
||||
|
||||
PomAssert hasNoRepository() {
|
||||
assertEquals 0, eng.getMatchingNodes(createRootNodeXPath('repositories'), doc).length
|
||||
this
|
||||
}
|
||||
|
||||
PomAssert hasSnapshotRepository() {
|
||||
hasRepository('spring-snapshots')
|
||||
hasPluginRepository('spring-snapshots')
|
||||
this
|
||||
}
|
||||
|
||||
def hasRepository(String name) {
|
||||
def nodes = eng.getMatchingNodes(createRootNodeXPath('repositories/pom:repository/pom:id'), doc)
|
||||
for (int i = 0; i < nodes.getLength(); i++) {
|
||||
if (name.equals(nodes.item(i).getTextContent())) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException('No repository found with id ' + name)
|
||||
}
|
||||
|
||||
def hasPluginRepository(String name) {
|
||||
def nodes = eng.getMatchingNodes(createRootNodeXPath('pluginRepositories/pom:pluginRepository/pom:id'), doc)
|
||||
for (int i = 0; i < nodes.getLength(); i++) {
|
||||
if (name.equals(nodes.item(i).getTextContent())) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException('No plugin repository found with id ' + name)
|
||||
}
|
||||
|
||||
static String createPropertyNodeXpath(String propertyName) {
|
||||
createRootNodeXPath('properties/pom:' + propertyName)
|
||||
}
|
||||
|
||||
static String createRootNodeXPath(String node) {
|
||||
'/pom:project/pom:' + node
|
||||
}
|
||||
|
||||
private def parseDependencies() {
|
||||
def nodes = eng.getMatchingNodes(createRootNodeXPath('dependencies/pom:dependency'), doc)
|
||||
for (int i = 0; i < nodes.length; i++) {
|
||||
def item = nodes.item(i)
|
||||
if (item instanceof Element) {
|
||||
Dependency dependency = new Dependency()
|
||||
Element element = (Element) item
|
||||
def groupId = element.getElementsByTagName('groupId')
|
||||
if (groupId.length > 0) {
|
||||
dependency.groupId = groupId.item(0).getTextContent()
|
||||
}
|
||||
def artifactId = element.getElementsByTagName('artifactId')
|
||||
if (artifactId.length > 0) {
|
||||
dependency.artifactId = artifactId.item(0).getTextContent()
|
||||
}
|
||||
def version = element.getElementsByTagName('version')
|
||||
if (version.length > 0) {
|
||||
dependency.version = version.item(0).getTextContent()
|
||||
}
|
||||
dependencies.put(dependency.generateId(), dependency)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private static String generateId(String groupId, String artifactId) {
|
||||
groupId + ':' + artifactId
|
||||
}
|
||||
|
||||
|
||||
private static class Dependency {
|
||||
String groupId
|
||||
String artifactId
|
||||
String version
|
||||
|
||||
String generateId() {
|
||||
generateId(groupId, artifactId)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright 2012-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.spring.initializr.support
|
||||
|
||||
import static org.junit.Assert.assertEquals
|
||||
|
||||
/**
|
||||
* Various project based assertions.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @since 1.0
|
||||
*/
|
||||
class ProjectAssert {
|
||||
|
||||
final File dir;
|
||||
|
||||
/**
|
||||
* Create a new instance with the directory holding the generated project.
|
||||
* @param dir
|
||||
*/
|
||||
ProjectAssert(File dir) {
|
||||
this.dir = dir
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a {@link PomAssert} for this project.
|
||||
*/
|
||||
PomAssert pomAssert() {
|
||||
new PomAssert(file('pom.xml').text)
|
||||
}
|
||||
|
||||
ProjectAssert isMavenProject() {
|
||||
hasFile('pom.xml').hasNoFile('build.gradle')
|
||||
}
|
||||
|
||||
ProjectAssert isGradleProject() {
|
||||
hasFile('build.gradle').hasNoFile('pom.xml')
|
||||
}
|
||||
|
||||
ProjectAssert isJavaProject() {
|
||||
hasFile('src/main/java/demo/Application.java',
|
||||
'src/test/java/demo/ApplicationTests.java',
|
||||
'src/main/resources/application.properties')
|
||||
}
|
||||
|
||||
ProjectAssert isJavaWarProject() {
|
||||
isJavaProject().hasStaticAndTemplatesResources(true)
|
||||
.hasFile('src/main/java/demo/ServletInitializer.java')
|
||||
}
|
||||
|
||||
ProjectAssert hasStaticAndTemplatesResources(boolean web) {
|
||||
assertFile('src/main/resources/templates', web)
|
||||
assertFile('src/main/resources/static', web)
|
||||
}
|
||||
|
||||
ProjectAssert hasFile(String... localPaths) {
|
||||
for (String localPath : localPaths) {
|
||||
assertFile(localPath, true)
|
||||
}
|
||||
this
|
||||
}
|
||||
|
||||
ProjectAssert hasNoFile(String... localPaths) {
|
||||
for (String localPath : localPaths) {
|
||||
assertFile(localPath, false)
|
||||
}
|
||||
this
|
||||
}
|
||||
|
||||
ProjectAssert assertFile(String localPath, boolean exist) {
|
||||
def candidate = file(localPath)
|
||||
assertEquals 'Invalid presence (' + exist + ') for ' + localPath, exist, candidate.exists()
|
||||
this
|
||||
}
|
||||
|
||||
private File file(String localPath) {
|
||||
new File(dir, localPath)
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,185 @@
|
||||
/*
|
||||
* Copyright 2012-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.spring.initializr.web
|
||||
|
||||
import io.spring.initializr.support.ProjectAssert
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.TemporaryFolder
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration
|
||||
import org.springframework.boot.test.IntegrationTest
|
||||
import org.springframework.boot.test.SpringApplicationConfiguration
|
||||
import org.springframework.http.*
|
||||
import org.springframework.test.context.ActiveProfiles
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner
|
||||
import org.springframework.test.context.web.WebAppConfiguration
|
||||
import org.springframework.web.client.RestTemplate
|
||||
|
||||
import static org.junit.Assert.*
|
||||
|
||||
/**
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SpringApplicationConfiguration(classes = Config.class)
|
||||
@WebAppConfiguration
|
||||
@IntegrationTest('server.port=0')
|
||||
@ActiveProfiles('test-default')
|
||||
class MainControllerIntegrationTests {
|
||||
|
||||
@Rule
|
||||
public final TemporaryFolder folder = new TemporaryFolder();
|
||||
|
||||
@Value('${local.server.port}')
|
||||
private int port
|
||||
|
||||
final RestTemplate restTemplate = new RestTemplate()
|
||||
|
||||
@Test
|
||||
public void simpleZipProject() {
|
||||
downloadZip('/starter.zip?style=web&style=jpa').isJavaProject().isMavenProject()
|
||||
.hasStaticAndTemplatesResources(true).pomAssert()
|
||||
.hasDependenciesCount(3)
|
||||
.hasSpringBootStarterDependency('web')
|
||||
.hasSpringBootStarterDependency('data-jpa') // alias jpa -> data-jpa
|
||||
.hasSpringBootStarterDependency('test')
|
||||
}
|
||||
|
||||
@Test
|
||||
public void simpleTgzProject() {
|
||||
downloadTgz('/starter.tgz?style=data-jpa').isJavaProject().isMavenProject()
|
||||
.hasStaticAndTemplatesResources(false).pomAssert()
|
||||
.hasDependenciesCount(2)
|
||||
.hasSpringBootStarterDependency('data-jpa')
|
||||
}
|
||||
|
||||
@Test
|
||||
public void gradleWarProject() {
|
||||
downloadZip('/starter.zip?style=web&style=security&packaging=war&type=gradle.zip').isJavaWarProject()
|
||||
.isGradleProject()
|
||||
}
|
||||
|
||||
// Existing tests for backward compatibility
|
||||
|
||||
@Test
|
||||
void homeIsForm() {
|
||||
String body = home()
|
||||
assertTrue 'Wrong body:\n' + body, body.contains('action="/starter.zip"')
|
||||
}
|
||||
|
||||
@Test
|
||||
void homeIsJson() {
|
||||
String body = restTemplate.getForObject(createUrl('/'), String)
|
||||
assertTrue('Wrong body:\n' + body, body.contains('{"dependencies"'))
|
||||
}
|
||||
|
||||
@Test
|
||||
void webIsAddedPom() {
|
||||
String body = restTemplate.getForObject(createUrl('/pom.xml?packaging=war'), String)
|
||||
assertTrue('Wrong body:\n' + body, body.contains('spring-boot-starter-web'))
|
||||
assertTrue('Wrong body:\n' + body, body.contains('provided'))
|
||||
}
|
||||
|
||||
@Test
|
||||
void webIsAddedGradle() {
|
||||
String body = restTemplate.getForObject(createUrl('/build.gradle?packaging=war'), String)
|
||||
assertTrue('Wrong body:\n' + body, body.contains('spring-boot-starter-web'))
|
||||
assertTrue('Wrong body:\n' + body, body.contains('providedRuntime'))
|
||||
}
|
||||
|
||||
@Test
|
||||
void infoHasExternalProperties() {
|
||||
String body = restTemplate.getForObject(createUrl('/info'), String)
|
||||
assertTrue('Wrong body:\n' + body, body.contains('"spring-boot"'))
|
||||
assertTrue('Wrong body:\n' + body, body.contains('"version":"1.1.5.RELEASE"'))
|
||||
}
|
||||
|
||||
@Test
|
||||
void homeHasWebStyle() {
|
||||
String body = home()
|
||||
assertTrue('Wrong body:\n' + body, body.contains('name="style" value="web"'))
|
||||
}
|
||||
|
||||
@Test
|
||||
void homeHasBootVersion() {
|
||||
String body = home()
|
||||
assertTrue('Wrong body:\n' + body, body.contains('name="bootVersion"'))
|
||||
assertTrue('Wrong body:\n' + body, body.contains('1.2.0.BUILD-SNAPSHOT"'))
|
||||
}
|
||||
|
||||
@Test
|
||||
void downloadStarter() {
|
||||
byte[] body = restTemplate.getForObject(createUrl('starter.zip'), byte[])
|
||||
assertNotNull(body)
|
||||
assertTrue(body.length > 100)
|
||||
}
|
||||
|
||||
@Test
|
||||
void installer() {
|
||||
ResponseEntity<String> response = restTemplate.getForEntity(createUrl('install.sh'), String)
|
||||
assertEquals(HttpStatus.OK, response.getStatusCode())
|
||||
assertNotNull(response.body)
|
||||
}
|
||||
|
||||
private String home() {
|
||||
HttpHeaders headers = new HttpHeaders()
|
||||
headers.setAccept([MediaType.TEXT_HTML])
|
||||
restTemplate.exchange(createUrl('/'), HttpMethod.GET, new HttpEntity<Void>(headers), String).body
|
||||
}
|
||||
|
||||
|
||||
private ProjectAssert downloadZip(String context) {
|
||||
byte[] body = restTemplate.getForObject(createUrl(context), byte[])
|
||||
File zipFile = writeArchive(body)
|
||||
|
||||
def project = folder.newFolder()
|
||||
new AntBuilder().unzip(dest: project, src: zipFile)
|
||||
new ProjectAssert(project)
|
||||
}
|
||||
|
||||
private ProjectAssert downloadTgz(String context) {
|
||||
byte[] body = restTemplate.getForObject(createUrl(context), byte[])
|
||||
File tgzFile = writeArchive(body)
|
||||
|
||||
def project = folder.newFolder()
|
||||
new AntBuilder().untar(dest: project, src: tgzFile, compression: 'gzip');
|
||||
new ProjectAssert(project)
|
||||
}
|
||||
|
||||
private File writeArchive(byte[] body) {
|
||||
def archiveFile = folder.newFile()
|
||||
def stream = new FileOutputStream(archiveFile)
|
||||
try {
|
||||
stream.write(body)
|
||||
} finally {
|
||||
stream.close()
|
||||
}
|
||||
archiveFile
|
||||
}
|
||||
|
||||
|
||||
String createUrl(String context) {
|
||||
return 'http://localhost:' + port + context
|
||||
}
|
||||
|
||||
@EnableAutoConfiguration
|
||||
static class Config {}
|
||||
|
||||
}
|
63
initializr/src/test/resources/application-test-default.yml
Normal file
63
initializr/src/test/resources/application-test-default.yml
Normal file
@ -0,0 +1,63 @@
|
||||
info:
|
||||
spring-boot:
|
||||
version: 1.1.5.RELEASE
|
||||
|
||||
|
||||
initializr:
|
||||
dependencies:
|
||||
- name: Core
|
||||
starters:
|
||||
- name: Web
|
||||
value: web
|
||||
- name: Security
|
||||
value: security
|
||||
- name: Data JPA
|
||||
value: data-jpa
|
||||
types:
|
||||
- name: Maven POM
|
||||
id: pom.xml
|
||||
default: false
|
||||
action: /pom.xml
|
||||
- name: Maven Project
|
||||
id: starter.zip
|
||||
default: true
|
||||
action: /starter.zip
|
||||
- name: Gradle Config
|
||||
id: build.gradle
|
||||
default: false
|
||||
action: /build.gradle
|
||||
- name: Gradle Project
|
||||
id: gradle.zip
|
||||
default: false
|
||||
action: /starter.zip
|
||||
packagings:
|
||||
- name: Jar
|
||||
id: jar
|
||||
default: true
|
||||
- name: War
|
||||
id: war
|
||||
default: false
|
||||
javaVersions:
|
||||
- id: 1.6
|
||||
default: false
|
||||
- id: 1.7
|
||||
default: true
|
||||
- id: 1.8
|
||||
default: false
|
||||
languages:
|
||||
- name: Groovy
|
||||
id: groovy
|
||||
default: false
|
||||
- name: Java
|
||||
id: java
|
||||
default: true
|
||||
bootVersions:
|
||||
- name : Latest SNAPSHOT
|
||||
id: 1.2.0.BUILD-SNAPSHOT
|
||||
default: false
|
||||
- name: 1.1.5
|
||||
id: 1.1.5.RELEASE
|
||||
default: true
|
||||
- name: 1.0.2
|
||||
id: 1.0.2.RELEASE
|
||||
default: false
|
@ -1,83 +0,0 @@
|
||||
package test
|
||||
|
||||
@SpringApplicationConfiguration(classes=TestConfiguration)
|
||||
@WebAppConfiguration
|
||||
@IntegrationTest('server.port:0')
|
||||
@DirtiesContext
|
||||
class IntegrationTests {
|
||||
|
||||
@Value('${local.server.port}')
|
||||
int port
|
||||
|
||||
private String home() {
|
||||
HttpHeaders headers = new HttpHeaders()
|
||||
headers.setAccept([MediaType.TEXT_HTML])
|
||||
new TestRestTemplate().exchange('http://localhost:' + port, HttpMethod.GET, new HttpEntity<Void>(headers), String).body
|
||||
}
|
||||
|
||||
@Test
|
||||
void homeIsForm() {
|
||||
String body = home()
|
||||
assertTrue('Wrong body:\n' + body, body.contains('action="/starter.zip"'))
|
||||
}
|
||||
|
||||
@Test
|
||||
void homeIsJson() {
|
||||
String body = new TestRestTemplate().getForObject('http://localhost:' + port, String)
|
||||
assertTrue('Wrong body:\n' + body, body.contains('{"styles"'))
|
||||
}
|
||||
|
||||
@Test
|
||||
void webIsAddedPom() {
|
||||
String body = new TestRestTemplate().getForObject('http://localhost:' + port + '/pom.xml?packaging=war', String)
|
||||
assertTrue('Wrong body:\n' + body, body.contains('spring-boot-starter-web'))
|
||||
assertTrue('Wrong body:\n' + body, body.contains('provided'))
|
||||
}
|
||||
|
||||
@Test
|
||||
void webIsAddedGradle() {
|
||||
String body = new TestRestTemplate().getForObject('http://localhost:' + port + '/build.gradle?packaging=war', String)
|
||||
assertTrue('Wrong body:\n' + body, body.contains('spring-boot-starter-web'))
|
||||
assertTrue('Wrong body:\n' + body, body.contains('providedRuntime'))
|
||||
}
|
||||
|
||||
@Test
|
||||
void infoHasExternalProperties() {
|
||||
String body = new TestRestTemplate().getForObject('http://localhost:' + port + '/info', String)
|
||||
assertTrue('Wrong body:\n' + body, body.contains('"project"'))
|
||||
}
|
||||
|
||||
@Test
|
||||
void homeHasWebStyle() {
|
||||
String body = home()
|
||||
assertTrue('Wrong body:\n' + body, body.contains('name="style" value="web"'))
|
||||
}
|
||||
|
||||
@Test
|
||||
void homeHasBootVersion() {
|
||||
String body = home()
|
||||
assertTrue('Wrong body:\n' + body, body.contains('name="bootVersion" value="1'))
|
||||
}
|
||||
|
||||
@Test
|
||||
void downloadStarter() {
|
||||
byte[] body = new TestRestTemplate().getForObject('http://localhost:' + port + 'starter.zip', byte[])
|
||||
assertNotNull(body)
|
||||
assertTrue(body.length>100)
|
||||
}
|
||||
|
||||
@Test
|
||||
void installer() {
|
||||
ResponseEntity<String> response = new TestRestTemplate().getForEntity('http://localhost:' + port + 'install.sh', String)
|
||||
assertEquals(HttpStatus.OK, response.getStatusCode())
|
||||
assertNotNull(response.body)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// CLI compiled classes are not @ComponentScannable so we have to create
|
||||
// an explicit configuration for the test
|
||||
@Configuration
|
||||
@Import([app.MainController, app.Projects, app.TemporaryFileCleaner])
|
||||
class TestConfiguration {
|
||||
}
|
Loading…
Reference in New Issue
Block a user