mirror of
https://gitee.com/dcren/initializr.git
synced 2025-09-19 18:22:26 +08:00
Redirect Spring cli distribution bundle
This commit adds the '/spring' endpoint that is used to download the Spring CLI distribution bundle. Instead of relying on the presence of a local 'spring.zip' file uploaded as part of the application, a redirect to a configurable repository is used. It is possible to download both the zip and the tar.gz distribution by specifying the extension in the url (i.e. /spring.tar.gz provides the tar.gz distribution. Fixes gh-31
This commit is contained in:
@@ -71,11 +71,9 @@ An example Cloud Foundry `manifest.yml` file is provided. You should ensure that
|
||||
the application name and URL (name and host values) are suitable for your environment
|
||||
before running `cf push`.
|
||||
|
||||
You can jar up the app and make it executable in any environment. Care is needed with the includes and excludes:
|
||||
You can jar up the app and make it executable in any environment.
|
||||
|
||||
$ version=1.1.5.RELEASE
|
||||
$ wget -O spring.zip https://repo.spring.io/org/springframework/boot/spring-boot-cli/${version}/spring-boot-cli-${version}-bin.zip
|
||||
$ spring jar --include '+spring.zip' start.jar app.groovy
|
||||
$ spring jar start.jar app.groovy
|
||||
|
||||
To deploy on Cloudfoundry:
|
||||
|
||||
|
@@ -21,6 +21,8 @@ import javax.annotation.PostConstruct
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore
|
||||
import com.fasterxml.jackson.annotation.JsonInclude
|
||||
import groovy.transform.ToString
|
||||
import org.slf4j.Logger
|
||||
import org.slf4j.LoggerFactory
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties
|
||||
|
||||
@@ -33,6 +35,8 @@ import org.springframework.boot.context.properties.ConfigurationProperties
|
||||
* <li>Supported Java versions</li>
|
||||
* <li>Supported language</li>
|
||||
* <li>Supported Spring Boot versions</li>
|
||||
* <li>Default settings used to generate the project</li>
|
||||
* <li>Environment related settings</li>
|
||||
* </ul>
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
@@ -41,6 +45,8 @@ import org.springframework.boot.context.properties.ConfigurationProperties
|
||||
@ConfigurationProperties(prefix = 'initializr', ignoreUnknownFields = false)
|
||||
class InitializrMetadata {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(InitializrMetadata)
|
||||
|
||||
final List<DependencyGroup> dependencies = new ArrayList<DependencyGroup>()
|
||||
|
||||
final List<Type> types = new ArrayList<Type>()
|
||||
@@ -55,6 +61,9 @@ class InitializrMetadata {
|
||||
|
||||
final Defaults defaults = new Defaults()
|
||||
|
||||
@JsonIgnore
|
||||
final Env env = new Env()
|
||||
|
||||
@JsonIgnore
|
||||
final Map<String, Dependency> indexedDependencies = new HashMap<String, Dependency>()
|
||||
|
||||
@@ -76,11 +85,6 @@ class InitializrMetadata {
|
||||
request[key] = value
|
||||
}
|
||||
}
|
||||
request.type = getDefault(types, request.type)
|
||||
request.packaging = getDefault(packagings, request.packaging)
|
||||
request.javaVersion = getDefault(javaVersions, request.javaVersion)
|
||||
request.language = getDefault(languages, request.language)
|
||||
request.bootVersion = getDefault(bootVersions, request.bootVersion)
|
||||
request
|
||||
}
|
||||
|
||||
@@ -98,6 +102,13 @@ class InitializrMetadata {
|
||||
}
|
||||
}
|
||||
}
|
||||
env.validate()
|
||||
|
||||
defaults.type = getDefault(types)
|
||||
defaults.packaging = getDefault(packagings)
|
||||
defaults.javaVersion = getDefault(javaVersions)
|
||||
defaults.language = getDefault(languages)
|
||||
defaults.bootVersion = getDefault(bootVersions)
|
||||
}
|
||||
|
||||
private void indexDependency(String id, Dependency dependency) {
|
||||
@@ -135,13 +146,14 @@ class InitializrMetadata {
|
||||
}
|
||||
}
|
||||
|
||||
static def getDefault(List elements, String defaultValue) {
|
||||
static def getDefault(List elements) {
|
||||
for (DefaultIdentifiableElement element : elements) {
|
||||
if (element.default) {
|
||||
return element.id
|
||||
}
|
||||
}
|
||||
return defaultValue
|
||||
logger.warn('No default found amongst' + elements)
|
||||
return (elements.isEmpty() ? null : elements.get(0).id)
|
||||
}
|
||||
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
@@ -225,6 +237,11 @@ class InitializrMetadata {
|
||||
String name = 'demo'
|
||||
String description = 'Demo project for Spring Boot'
|
||||
String packageName
|
||||
String type
|
||||
String packaging
|
||||
String javaVersion
|
||||
String language
|
||||
String bootVersion
|
||||
|
||||
/**
|
||||
* Return the artifactId or the name of the project if none is set.
|
||||
@@ -242,6 +259,28 @@ class InitializrMetadata {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines additional environment settings
|
||||
*/
|
||||
static class Env {
|
||||
|
||||
String artifactRepository = 'https://repo.spring.io/release/'
|
||||
|
||||
/**
|
||||
* Create an URL suitable to download Spring Boot cli for the specified version and extension.
|
||||
*/
|
||||
String createCliDistributionURl(String version, String extension) {
|
||||
artifactRepository + "org/springframework/boot/spring-boot-cli/$version/spring-boot-cli-$version-bin.$extension"
|
||||
}
|
||||
|
||||
void validate() {
|
||||
if (!artifactRepository.endsWith('/')) {
|
||||
artifactRepository = artifactRepository + '/'
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class DefaultIdentifiableElement extends IdentifiableElement {
|
||||
|
||||
@JsonIgnore
|
||||
|
@@ -74,6 +74,16 @@ class MainController {
|
||||
template 'home.html', model
|
||||
}
|
||||
|
||||
@RequestMapping('/spring')
|
||||
String spring() {
|
||||
'redirect:' + metadata.env.createCliDistributionURl(metadata.defaults.bootVersion, 'zip')
|
||||
}
|
||||
|
||||
@RequestMapping(value = ['/spring.tar.gz', 'spring.tgz'])
|
||||
String springTgz() {
|
||||
'redirect:' + metadata.env.createCliDistributionURl(metadata.defaults.bootVersion, 'tar.gz')
|
||||
}
|
||||
|
||||
@RequestMapping('/pom')
|
||||
@ResponseBody
|
||||
ResponseEntity<byte[]> pom(ProjectRequest request) {
|
||||
@@ -124,4 +134,6 @@ class MainController {
|
||||
result
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@@ -120,7 +120,7 @@ class InitializrMetadataTests {
|
||||
|
||||
|
||||
InitializrMetadata metadata = InitializrMetadataBuilder.withDefaults()
|
||||
.addDependencyGroup('foo', dependency, dependency2).get()
|
||||
.addDependencyGroup('foo', dependency, dependency2).validateAndGet()
|
||||
|
||||
assertSame dependency, metadata.getDependency('first')
|
||||
assertSame dependency2, metadata.getDependency('second')
|
||||
@@ -137,7 +137,7 @@ class InitializrMetadataTests {
|
||||
|
||||
thrown.expect(IllegalArgumentException)
|
||||
thrown.expectMessage('conflict')
|
||||
builder.get()
|
||||
builder.validateAndGet()
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -147,7 +147,7 @@ class InitializrMetadataTests {
|
||||
dependency.aliases.add('alias2')
|
||||
|
||||
InitializrMetadata metadata = InitializrMetadataBuilder.withDefaults()
|
||||
.addDependencyGroup('foo', dependency).get()
|
||||
.addDependencyGroup('foo', dependency).validateAndGet()
|
||||
|
||||
assertSame dependency, metadata.getDependency('first')
|
||||
assertSame dependency, metadata.getDependency('alias1')
|
||||
@@ -168,28 +168,42 @@ class InitializrMetadataTests {
|
||||
|
||||
thrown.expect(IllegalArgumentException)
|
||||
thrown.expectMessage('alias2')
|
||||
builder.get()
|
||||
builder.validateAndGet()
|
||||
}
|
||||
|
||||
@Test
|
||||
void createProjectRequest() {
|
||||
InitializrMetadata metadata = InitializrMetadataBuilder.withDefaults().get()
|
||||
InitializrMetadata metadata = InitializrMetadataBuilder.withDefaults().validateAndGet()
|
||||
ProjectRequest request = doCreateProjectRequest(metadata)
|
||||
assertEquals metadata.defaults.groupId, request.groupId
|
||||
}
|
||||
|
||||
@Test
|
||||
void validateArtifactRepository() {
|
||||
InitializrMetadata metadata = InitializrMetadataBuilder.withDefaults().instance()
|
||||
metadata.env.artifactRepository = 'http://foo/bar'
|
||||
metadata.validate()
|
||||
assertEquals 'http://foo/bar/', metadata.env.artifactRepository
|
||||
}
|
||||
|
||||
@Test
|
||||
void getDefaultNoDefault() {
|
||||
List elements = []
|
||||
elements << createJavaVersion('one', false) << createJavaVersion('two', false)
|
||||
assertEquals 'three', InitializrMetadata.getDefault(elements, 'three')
|
||||
assertEquals 'one', InitializrMetadata.getDefault(elements)
|
||||
}
|
||||
|
||||
@Test
|
||||
void getDefaultWithDefault() {
|
||||
void getDefaultEmpty() {
|
||||
List elements = []
|
||||
assertNull InitializrMetadata.getDefault(elements)
|
||||
}
|
||||
|
||||
@Test
|
||||
void getDefault() {
|
||||
List elements = []
|
||||
elements << createJavaVersion('one', false) << createJavaVersion('two', true)
|
||||
assertEquals 'two', InitializrMetadata.getDefault(elements, 'three')
|
||||
assertEquals 'two', InitializrMetadata.getDefault(elements)
|
||||
}
|
||||
|
||||
private static ProjectRequest doCreateProjectRequest(InitializrMetadata metadata) {
|
||||
|
@@ -31,7 +31,7 @@ class ProjectGeneratorTests {
|
||||
@Before
|
||||
void setup() {
|
||||
InitializrMetadata metadata = InitializrMetadataBuilder.withDefaults()
|
||||
.addDependencyGroup('test', 'web', 'security', 'data-jpa', 'aop', 'batch', 'integration').get()
|
||||
.addDependencyGroup('test', 'web', 'security', 'data-jpa', 'aop', 'batch', 'integration').validateAndGet()
|
||||
projectGenerator.metadata = metadata
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ class ProjectGeneratorTests {
|
||||
dependency.facets << 'web'
|
||||
InitializrMetadata metadata = InitializrMetadataBuilder.withDefaults()
|
||||
.addDependencyGroup('core', 'web', 'security', 'data-jpa')
|
||||
.addDependencyGroup('test', dependency).get()
|
||||
.addDependencyGroup('test', dependency).validateAndGet()
|
||||
projectGenerator.metadata = metadata
|
||||
|
||||
ProjectRequest request = createProjectRequest('thymeleaf')
|
||||
@@ -78,7 +78,7 @@ class ProjectGeneratorTests {
|
||||
dependency.facets << 'web'
|
||||
InitializrMetadata metadata = InitializrMetadataBuilder.withDefaults()
|
||||
.addDependencyGroup('core', 'web', 'security', 'data-jpa')
|
||||
.addDependencyGroup('test', dependency).get()
|
||||
.addDependencyGroup('test', dependency).validateAndGet()
|
||||
projectGenerator.metadata = metadata
|
||||
|
||||
ProjectRequest request = createProjectRequest('thymeleaf')
|
||||
|
@@ -35,7 +35,7 @@ class ProjectRequestTests {
|
||||
void resolve() {
|
||||
ProjectRequest request = new ProjectRequest()
|
||||
InitializrMetadata metadata = InitializrMetadataBuilder.withDefaults()
|
||||
.addDependencyGroup('code', 'web', 'security', 'spring-data').get()
|
||||
.addDependencyGroup('code', 'web', 'security', 'spring-data').validateAndGet()
|
||||
|
||||
request.style << 'web' << 'spring-data'
|
||||
request.resolve(metadata)
|
||||
@@ -47,7 +47,7 @@ class ProjectRequestTests {
|
||||
void resolveFullMetadata() {
|
||||
ProjectRequest request = new ProjectRequest()
|
||||
InitializrMetadata metadata = InitializrMetadataBuilder.withDefaults()
|
||||
.addDependencyGroup('code', createDependency('org.foo', 'acme', '1.2.0')).get()
|
||||
.addDependencyGroup('code', createDependency('org.foo', 'acme', '1.2.0')).validateAndGet()
|
||||
request.style << 'org.foo:acme'
|
||||
request.resolve(metadata)
|
||||
assertDependency(request.dependencies.get(0), 'org.foo', 'acme', '1.2.0')
|
||||
@@ -57,7 +57,7 @@ class ProjectRequestTests {
|
||||
void resolveUnknownSimpleIdAsSpringBootStarter() {
|
||||
ProjectRequest request = new ProjectRequest()
|
||||
InitializrMetadata metadata = InitializrMetadataBuilder.withDefaults()
|
||||
.addDependencyGroup('code', 'org.foo:bar').get()
|
||||
.addDependencyGroup('code', 'org.foo:bar').validateAndGet()
|
||||
|
||||
request.style << 'org.foo:bar' << 'foo-bar'
|
||||
request.resolve(metadata)
|
||||
@@ -69,7 +69,7 @@ class ProjectRequestTests {
|
||||
void resolveUnknownDependency() {
|
||||
ProjectRequest request = new ProjectRequest()
|
||||
InitializrMetadata metadata = InitializrMetadataBuilder.withDefaults()
|
||||
.addDependencyGroup('code', 'org.foo:bar').get()
|
||||
.addDependencyGroup('code', 'org.foo:bar').validateAndGet()
|
||||
|
||||
request.style << 'org.foo:acme' // does not exist and
|
||||
|
||||
|
@@ -33,8 +33,12 @@ class InitializrMetadataBuilder {
|
||||
new InitializrMetadataBuilder().addDefaults()
|
||||
}
|
||||
|
||||
InitializrMetadata get() {
|
||||
InitializrMetadata validateAndGet() {
|
||||
metadata.validate()
|
||||
instance()
|
||||
}
|
||||
|
||||
InitializrMetadata instance() {
|
||||
metadata
|
||||
}
|
||||
|
||||
|
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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 org.junit.Test
|
||||
|
||||
import org.springframework.http.HttpEntity
|
||||
import org.springframework.http.HttpStatus
|
||||
import org.springframework.test.context.ActiveProfiles
|
||||
|
||||
import static org.junit.Assert.assertEquals
|
||||
|
||||
/**
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
@ActiveProfiles(['test-default', 'test-custom-env'])
|
||||
class MainControllerEnvIntegrationTests extends AbstractMainControllerIntegrationTests {
|
||||
|
||||
@Test
|
||||
void downloadCliWithCustomRepository() {
|
||||
HttpEntity entity = restTemplate.getForEntity(createUrl('/spring'), HttpEntity.class)
|
||||
assertEquals HttpStatus.FOUND, entity.getStatusCode()
|
||||
assertEquals new URI('https://repo.spring.io/lib-release/org/springframework/boot/spring-boot-cli/1.1.5.RELEASE' +
|
||||
'/spring-boot-cli-1.1.5.RELEASE-bin.zip'), entity.getHeaders().getLocation()
|
||||
}
|
||||
|
||||
}
|
@@ -62,6 +62,34 @@ class MainControllerIntegrationTests extends AbstractMainControllerIntegrationTe
|
||||
.isGradleProject()
|
||||
}
|
||||
|
||||
@Test
|
||||
void downloadCli() {
|
||||
assertSpringCliRedirect('/spring', 'zip')
|
||||
}
|
||||
|
||||
@Test
|
||||
void downloadCliAsZip() {
|
||||
assertSpringCliRedirect('/spring.zip', 'zip')
|
||||
}
|
||||
|
||||
@Test
|
||||
void downloadCliAsTarGz() {
|
||||
assertSpringCliRedirect('/spring.tar.gz', 'tar.gz')
|
||||
}
|
||||
|
||||
@Test
|
||||
void downloadCliAsTgz() {
|
||||
assertSpringCliRedirect('/spring.tgz', 'tar.gz')
|
||||
}
|
||||
|
||||
private void assertSpringCliRedirect(String context, String extension) {
|
||||
ResponseEntity<?> entity = restTemplate.getForEntity(createUrl(context), ResponseEntity.class)
|
||||
assertEquals HttpStatus.FOUND, entity.getStatusCode()
|
||||
assertEquals new URI('https://repo.spring.io/release/org/springframework/boot/spring-boot-cli/1.1.5.RELEASE' +
|
||||
'/spring-boot-cli-1.1.5.RELEASE-bin.'+extension), entity.getHeaders().getLocation()
|
||||
|
||||
}
|
||||
|
||||
@Test // Test that the current output is exactly what we expect
|
||||
void validateCurrentProjectMetadata() {
|
||||
String json = restTemplate.getForObject(createUrl('/'), String.class)
|
||||
|
@@ -0,0 +1,3 @@
|
||||
initializr:
|
||||
env:
|
||||
artifactRepository: https://repo.spring.io/lib-release
|
@@ -114,6 +114,11 @@
|
||||
"version": "0.0.1-SNAPSHOT",
|
||||
"name": "demo",
|
||||
"description": "Demo project for Spring Boot",
|
||||
"packageName": "demo"
|
||||
"packageName": "demo",
|
||||
"type": "starter.zip",
|
||||
"packaging": "jar",
|
||||
"javaVersion": "1.7",
|
||||
"language": "java",
|
||||
"bootVersion": "1.1.5.RELEASE"
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user