More metadata for types

This commit adds a 'tags' attribute to each type. Two tags are currently
available:

1. build defines the build system that should be included in the project
(maven and gradle)
2. format defines the format of the project (build for the build file and
project for a project archive)

When a type id is specified, the build tag is used to figure out which
build system should be used. If no type is specified we fallback to Maven
as we were already doing.

Fixes gh-43
This commit is contained in:
Stephane Nicoll
2014-10-30 11:15:47 +01:00
parent 7350cd165d
commit d1a51c431b
10 changed files with 251 additions and 10 deletions

View File

@@ -119,21 +119,33 @@ initializr:
- name: Maven POM
id: maven-build
sts-id: pom.xml
tags:
build: maven
format: build
default: false
action: /pom.xml
- name: Maven Project
id: maven-project
sts-id: starter.zip
tags:
build: maven
format: project
default: true
action: /starter.zip
- name: Gradle Config
id: gradle-build
sts-id: build.gradle
tags:
build: gradle
format: build
default: false
action: /build.gradle
- name: Gradle Project
id: gradle-project
sts-id: gradle.zip
tags:
build: gradle
format: project
default: false
action: /starter.zip
packagings:

View File

@@ -74,6 +74,19 @@ class InitializrMetadata {
indexedDependencies[id]
}
/**
* Return the {@link Type} with the specified id or {@code null} if no
* such type exists.
*/
Type getType(String id) {
for (it in this.types) {
if (id.equals(it.id) || id.equals(it.stsId)) {
return it
}
}
return null
}
/**
* Create an URL suitable to download Spring Boot cli for the specified version and extension.
*/
@@ -247,6 +260,8 @@ class InitializrMetadata {
String stsId
String action
final Map<String, String> tags = [:]
}
static class Packaging extends DefaultIdentifiableElement {

View File

@@ -76,7 +76,7 @@ class ProjectGenerator {
dir.delete()
dir.mkdirs()
if (request.type.contains('gradle')) {
if ('gradle'.equals(request.build)) {
def gradle = new String(doGenerateGradleBuild(model))
new File(dir, 'build.gradle').write(gradle)
} else {

View File

@@ -44,6 +44,7 @@ class ProjectRequest {
def dependencies = []
def facets = []
def build
/**
* Resolve this instance against the specified {@link InitializrMetadata}
@@ -72,6 +73,17 @@ class ProjectRequest {
}
}
}
if (this.type) {
InitializrMetadata.Type type = metadata.getType(this.type)
if (!type) {
throw new InvalidProjectRequestException("Unknown type '${this.type}' check project metadata")
}
String buildTag = type.tags['build']
if (buildTag) {
this.build = buildTag
}
}
afterResolution(metadata)
}

View File

@@ -90,16 +90,16 @@ class ProjectGenerationMetricsListenerTests {
def request = initialize()
request.resolve(metadata)
listener.onGeneratedProject(request)
metricsAssert.hasValue(1, 'initializr.type.starter_zip')
metricsAssert.hasValue(1, 'initializr.type.maven-project')
}
@Test
void explicitType() {
def request = initialize()
request.type = 'build.gradle'
request.type = 'gradle-build'
request.resolve(metadata)
listener.onGeneratedProject(request)
metricsAssert.hasValue(1, 'initializr.type.build_gradle')
metricsAssert.hasValue(1, 'initializr.type.gradle-build')
}
@Test
@@ -174,7 +174,7 @@ class ProjectGenerationMetricsListenerTests {
void collectAllMetrics() {
def request = initialize()
request.style << 'web' << 'security'
request.type = 'gradle.zip'
request.type = 'gradle-project'
request.packaging = 'jar'
request.javaVersion = '1.6'
request.language = 'groovy'
@@ -184,7 +184,7 @@ class ProjectGenerationMetricsListenerTests {
listener.onGeneratedProject(request)
metricsAssert.hasValue(1, 'initializr.requests',
'initializr.dependency.web', 'initializr.dependency.security',
'initializr.type.gradle_zip', 'initializr.packaging.jar',
'initializr.type.gradle-project', 'initializr.packaging.jar',
'initializr.java_version.1_6', 'initializr.language.groovy',
'initializr.boot_version.1_0_2_RELEASE').metricsCount(8)
}

View File

@@ -22,6 +22,7 @@ import org.junit.Test
import org.junit.rules.ExpectedException
import static org.junit.Assert.assertEquals
import static org.junit.Assert.assertNull
/**
* @author Stephane Nicoll
@@ -37,8 +38,10 @@ class ProjectRequestTests {
def metadata = InitializrMetadataBuilder.withDefaults()
.addDependencyGroup('code', 'web', 'security', 'spring-data').validateAndGet()
request.type = 'maven-project'
request.style << 'web' << 'spring-data'
request.resolve(metadata)
assertEquals 'Build type not detected', 'maven', request.build
assertBootStarter(request.dependencies[0], 'web')
assertBootStarter(request.dependencies[1], 'spring-data')
}
@@ -78,6 +81,38 @@ class ProjectRequestTests {
request.resolve(metadata)
}
@Test
void resolveBuild() {
def request = new ProjectRequest()
def metadata = InitializrMetadataBuilder.withDefaults().validateAndGet()
request.type = 'gradle-project'
request.resolve(metadata)
assertEquals 'gradle', request.build
}
@Test
void resolveBuildNoTag() {
def request = new ProjectRequest()
def metadata = InitializrMetadataBuilder.withDefaults()
.addType('foo', false, '/foo.zip', null, null).validateAndGet()
request.type = 'foo'
request.resolve(metadata)
assertNull request.build
}
@Test
void resolveUnknownType() {
def request = new ProjectRequest()
def metadata = InitializrMetadataBuilder.withDefaults().validateAndGet()
request.type = 'foo-project'
thrown.expect(InvalidProjectRequestException)
thrown.expectMessage('foo-project')
request.resolve(metadata)
}
private static void assertBootStarter(InitializrMetadata.Dependency actual, String name) {
def expected = new InitializrMetadata.Dependency()
expected.asSpringBootStarter(name)

View File

@@ -68,16 +68,24 @@ class InitializrMetadataBuilder {
}
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')
addType('maven-build', false, '/pom.xml', 'maven', 'build')
.addType('maven-project', true, '/starter.zip', 'maven', 'project')
.addType('gradle-build', false, '/build.gradle', 'gradle', 'build')
.addType('gradle-project', false, '/starter.zip', 'gradle', 'project')
}
InitializrMetadataBuilder addType(String id, boolean defaultValue, String action) {
InitializrMetadataBuilder addType(String id, boolean defaultValue, String action, String build, String format) {
def type = new InitializrMetadata.Type()
type.id = id
type.name = id
type.default = defaultValue
type.action = action
if (build) {
type.tags['build'] = build
}
if (format) {
type.tags['format'] = format
}
metadata.types.add(type)
this
}

View File

@@ -107,10 +107,17 @@ class MainControllerIntegrationTests extends AbstractInitializrControllerIntegra
@Test // Test that the current output is exactly what we expect
void validateCurrentProjectMetadata() {
def json = restTemplate.getForObject(createUrl('/'), String.class)
def expected = readJson('1.0.1')
def expected = readJson('1.1.0')
JSONAssert.assertEquals(expected, new JSONObject(json), JSONCompareMode.STRICT)
}
@Test // Test that the current code complies "at least" with 1.0.1
void validateProjectMetadata101() {
def json = restTemplate.getForObject(createUrl('/'), String.class)
def expected = readJson('1.0.1')
JSONAssert.assertEquals(expected, new JSONObject(json), JSONCompareMode.LENIENT)
}
@Test // Test that the current code complies "at least" with 1.0.0
void validateProjectMetadata100() {
def json = restTemplate.getForObject(createUrl('/'), String.class)

View File

@@ -31,21 +31,33 @@ initializr:
- name: Maven POM
id: maven-build
sts-id: pom.xml
tags:
build: maven
format: build
default: false
action: /pom.xml
- name: Maven Project
id: maven-project
sts-id: starter.zip
tags:
build: maven
format: project
default: true
action: /starter.zip
- name: Gradle Config
id: gradle-build
sts-id: build.gradle
tags:
build: gradle
format: build
default: false
action: /build.gradle
- name: Gradle Project
id: gradle-project
sts-id: gradle.zip
tags:
build: gradle
format: project
default: false
action: /starter.zip
packagings:

View File

@@ -0,0 +1,140 @@
{"dependencies": [
{
"name": "Core",
"content": [
{
"name": "Web",
"id": "web",
"description": "Web dependency description"
},
{
"name": "Security",
"id": "security"
},
{
"name": "Data JPA",
"id": "data-jpa"
}
]
},
{
"name": "Other",
"content": [
{
"name": "Foo",
"id": "org.acme:foo"
},
{
"name": "Bar",
"id": "org.acme:bar"
}
]
}
], "types": [
{
"name": "Maven POM",
"id": "maven-build",
"action": "/pom.xml",
"tags": {
"build": "maven",
"format": "build"
},
"default": false
},
{
"name": "Maven Project",
"id": "maven-project",
"action": "/starter.zip",
"tags": {
"build": "maven",
"format": "project"
},
"default": true
},
{
"name": "Gradle Config",
"id": "gradle-build",
"action": "/build.gradle",
"tags": {
"build": "gradle",
"format": "build"
},
"default": false
},
{
"name": "Gradle Project",
"id": "gradle-project",
"action": "/starter.zip",
"tags": {
"build": "gradle",
"format": "project"
},
"default": false
}
], "packagings": [
{
"name": "Jar",
"id": "jar",
"default": true
},
{
"name": "War",
"id": "war",
"default": false
}
], "javaVersions": [
{
"name": "1.6",
"id": "1.6",
"default": false
},
{
"name": "1.7",
"id": "1.7",
"default": true
},
{
"name": "1.8",
"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.4",
"id": "1.1.4.RELEASE",
"default": true
},
{
"name": "1.0.2",
"id": "1.0.2.RELEASE",
"default": false
}
], "defaults": {
"groupId": "org.test",
"artifactId": "demo",
"version": "0.0.1-SNAPSHOT",
"name": "demo",
"description": "Demo project for Spring Boot",
"packageName": "demo",
"type": "maven-project",
"packaging": "jar",
"javaVersion": "1.7",
"language": "java",
"bootVersion": "1.1.4.RELEASE"
}}