mirror of
https://gitee.com/dcren/initializr.git
synced 2026-08-29 03:49:26 +08:00
Auto-updatable version ranges
This commit improves the version format so that the minor and patch elements can hold a special 'x' character besides the version, i.e. `1.x.x.RELEASE` or `2.4.x.BUILD-SNAPSHOT`. A `VersionParser` now takes care to resolve those against a list of known Spring Boot versions. This is particularly useful in version ranges that have to change when the latest Spring Boot versions change. Spring Initializr already auto- udpates itself based on the sagan metadata. When a range is using this feature, it is also automatically updated. It might be hard to track the actual range values on a given instance so an `InfoContributor` is now automatically exposed to list them. Closes gh-328
This commit is contained in:
@@ -112,11 +112,11 @@ class CommandLineHelpGeneratorTests {
|
||||
def second = new Dependency(id: 'second', description: 'second desc', versionRange: ' [1.2.0.RELEASE,1.3.0.M1) ')
|
||||
def metadata = InitializrMetadataTestBuilder.withDefaults().addDependencyGroup("test", first, second).build()
|
||||
String content = generator.generateSpringBootCliCapabilities(metadata, "https://fake-service")
|
||||
assertThat content, containsString('| first | first desc | >= 1.2.0.RELEASE |')
|
||||
assertThat content, containsString('| second | second desc | [1.2.0.RELEASE,1.3.0.M1) |')
|
||||
assertThat content, containsString('| first | first desc | >=1.2.0.RELEASE |')
|
||||
assertThat content, containsString('| second | second desc | >=1.2.0.RELEASE and <1.3.0.M1 |')
|
||||
}
|
||||
|
||||
private assertCommandLineCapabilities(String content) {
|
||||
private static assertCommandLineCapabilities(String content) {
|
||||
assertThat content, containsString("| Rel")
|
||||
assertThat content, containsString("| dependencies")
|
||||
assertThat content, containsString("| applicationName")
|
||||
@@ -124,11 +124,11 @@ class CommandLineHelpGeneratorTests {
|
||||
assertThat content, not(containsString('| Tags'))
|
||||
}
|
||||
|
||||
private static def createDependency(String id, String name) {
|
||||
private static createDependency(String id, String name) {
|
||||
createDependency(id, name, null)
|
||||
}
|
||||
|
||||
private static def createDependency(String id, String name, String description) {
|
||||
private static createDependency(String id, String name, String description) {
|
||||
new Dependency(id: id, name: name, description: description)
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package io.spring.initializr.metadata
|
||||
|
||||
import io.spring.initializr.util.Version
|
||||
import io.spring.initializr.util.VersionParser
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.ExpectedException
|
||||
@@ -108,4 +109,25 @@ class BillOfMaterialsTests {
|
||||
bom.resolve(Version.parse('1.4.1.RELEASE'))
|
||||
}
|
||||
|
||||
@Test
|
||||
void resolveRangeWithVariablePatch() {
|
||||
BillOfMaterials bom = new BillOfMaterials(groupId: 'com.example',
|
||||
artifactId: 'bom', version: '1.0.0')
|
||||
bom.mappings << new BillOfMaterials.Mapping(
|
||||
versionRange: '[1.3.0.RELEASE,1.3.x.RELEASE]', version: '1.1.0')
|
||||
bom.mappings << new BillOfMaterials.Mapping(
|
||||
versionRange: '[1.3.x.BUILD-SNAPSHOT,1.4.0.RELEASE)', version: '1.1.1-SNAPSHOT')
|
||||
bom.validate()
|
||||
|
||||
bom.updateVersionRange(new VersionParser(Arrays.asList(
|
||||
Version.parse("1.3.8.RELEASE"), Version.parse("1.3.9.BUILD-SNAPSHOT"))))
|
||||
assertThat(bom.resolve(Version.parse('1.3.8.RELEASE')).version, equalTo('1.1.0'))
|
||||
assertThat(bom.resolve(Version.parse('1.3.9.RELEASE')).version, equalTo('1.1.1-SNAPSHOT'))
|
||||
|
||||
bom.updateVersionRange(new VersionParser(Arrays.asList(
|
||||
Version.parse("1.3.9.RELEASE"), Version.parse("1.3.10.BUILD-SNAPSHOT"))))
|
||||
assertThat(bom.resolve(Version.parse('1.3.8.RELEASE')).version, equalTo('1.1.0'))
|
||||
assertThat(bom.resolve(Version.parse('1.3.9.RELEASE')).version, equalTo('1.1.0'))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package io.spring.initializr.metadata
|
||||
|
||||
import io.spring.initializr.util.Version
|
||||
import io.spring.initializr.util.VersionParser
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.ExpectedException
|
||||
@@ -201,6 +202,37 @@ class DependencyTests {
|
||||
'org.springframework.boot', 'spring-boot-starter-web', '0.3.0.RELEASE') // default
|
||||
}
|
||||
|
||||
@Test
|
||||
void resolveMatchingVersionWithVariablePatch() {
|
||||
def dependency = new Dependency(id: 'web', description: 'A web dependency', version: '0.3.0.RELEASE',
|
||||
keywords: ['foo', 'bar'], aliases: ['the-web'], facets: ['web'])
|
||||
dependency.mappings << new Dependency.Mapping(
|
||||
versionRange: '[1.1.0.RELEASE, 1.1.x.RELEASE]', version: '0.1.0.RELEASE')
|
||||
dependency.mappings << new Dependency.Mapping(
|
||||
versionRange: '[1.1.x.BUILD-SNAPSHOT, 1.2.0.RELEASE)', version: '0.2.0.RELEASE')
|
||||
dependency.resolve()
|
||||
|
||||
dependency.updateVersionRanges(new VersionParser(Arrays.asList(
|
||||
Version.parse("1.1.5.RELEASE"), Version.parse("1.1.6.BUILD-SNAPSHOT"))))
|
||||
validateResolvedWebDependency(dependency.resolve(Version.parse('1.1.5.RELEASE')),
|
||||
'org.springframework.boot', 'spring-boot-starter-web', '0.1.0.RELEASE')
|
||||
validateResolvedWebDependency(dependency.resolve(Version.parse('1.1.6.BUILD-SNAPSHOT')),
|
||||
'org.springframework.boot', 'spring-boot-starter-web', '0.2.0.RELEASE')
|
||||
validateResolvedWebDependency(dependency.resolve(Version.parse('2.1.3.M1')),
|
||||
'org.springframework.boot', 'spring-boot-starter-web', '0.3.0.RELEASE') // default
|
||||
|
||||
dependency.updateVersionRanges(new VersionParser(Arrays.asList(
|
||||
Version.parse("1.1.6.RELEASE"), Version.parse("1.1.7.BUILD-SNAPSHOT"))))
|
||||
validateResolvedWebDependency(dependency.resolve(Version.parse('1.1.5.RELEASE')),
|
||||
'org.springframework.boot', 'spring-boot-starter-web', '0.1.0.RELEASE')
|
||||
validateResolvedWebDependency(dependency.resolve(Version.parse('1.1.6.RELEASE')),
|
||||
'org.springframework.boot', 'spring-boot-starter-web', '0.1.0.RELEASE')
|
||||
validateResolvedWebDependency(dependency.resolve(Version.parse('1.1.7.BUILD-SNAPSHOT')),
|
||||
'org.springframework.boot', 'spring-boot-starter-web', '0.2.0.RELEASE')
|
||||
validateResolvedWebDependency(dependency.resolve(Version.parse('2.1.3.M1')),
|
||||
'org.springframework.boot', 'spring-boot-starter-web', '0.3.0.RELEASE') // default
|
||||
}
|
||||
|
||||
static void validateResolvedWebDependency(
|
||||
def dependency, def expectedGroupId, def expectedArtifactId, def expectedVersion) {
|
||||
assertEquals expectedVersion, dependency.version
|
||||
|
||||
@@ -17,10 +17,13 @@
|
||||
package io.spring.initializr.metadata
|
||||
|
||||
import io.spring.initializr.test.metadata.InitializrMetadataTestBuilder
|
||||
import io.spring.initializr.util.Version
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.ExpectedException
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat
|
||||
|
||||
/**
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
@@ -146,6 +149,34 @@ class InitializrMetadataTests {
|
||||
builder.build()
|
||||
}
|
||||
|
||||
@Test
|
||||
void updateSpringBootVersions() {
|
||||
def bom = new BillOfMaterials(groupId: 'org.acme', artifactId: 'foo-bom')
|
||||
bom.mappings << new BillOfMaterials.Mapping(versionRange: '[1.3.0.RELEASE,1.3.x.RELEASE]', version: '1.0.0')
|
||||
bom.mappings << new BillOfMaterials.Mapping(versionRange: '1.3.x.BUILD-SNAPSHOT', version: '1.1.0-BUILD-SNAPSHOT')
|
||||
def dependency = new Dependency(id: 'bar')
|
||||
dependency.mappings << new Dependency.Mapping(
|
||||
versionRange: '[1.3.0.RELEASE, 1.3.x.RELEASE]', version: '0.1.0.RELEASE')
|
||||
dependency.mappings << new Dependency.Mapping(
|
||||
versionRange: '1.3.x.BUILD-SNAPSHOT', version: '0.2.0.RELEASE')
|
||||
InitializrMetadata metadata = InitializrMetadataTestBuilder
|
||||
.withDefaults().addDependencyGroup("test", dependency)
|
||||
.addBom('foo-bom', bom).build();
|
||||
|
||||
List<DefaultMetadataElement> bootVersions = Arrays.asList(
|
||||
new DefaultMetadataElement(id: '1.3.6.RELEASE', name: '1.3.6'),
|
||||
new DefaultMetadataElement(id: '1.3.7.BUILD-SNAPSHOT', name: '1.3.7'))
|
||||
metadata.updateSpringBootVersions(bootVersions)
|
||||
assertThat(metadata.configuration.env.boms['foo-bom']
|
||||
.resolve(Version.parse('1.3.6.RELEASE')).version).isEqualTo('1.0.0')
|
||||
assertThat(metadata.configuration.env.boms['foo-bom']
|
||||
.resolve(Version.parse('1.3.7.BUILD-SNAPSHOT')).version).isEqualTo('1.1.0-BUILD-SNAPSHOT')
|
||||
assertThat(metadata.dependencies.get('bar')
|
||||
.resolve(Version.parse('1.3.6.RELEASE')).version).isEqualTo('0.1.0.RELEASE')
|
||||
assertThat(metadata.dependencies.get('bar')
|
||||
.resolve(Version.parse('1.3.7.BUILD-SNAPSHOT')).version).isEqualTo('0.2.0.RELEASE')
|
||||
}
|
||||
|
||||
@Test
|
||||
void invalidParentMissingVersion() {
|
||||
InitializrMetadataTestBuilder builder = InitializrMetadataTestBuilder
|
||||
|
||||
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* Copyright 2012-2016 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.util
|
||||
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.ExpectedException
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat
|
||||
import static org.hamcrest.Matchers.equalTo
|
||||
import static org.hamcrest.Matchers.lessThan
|
||||
import static org.junit.Assert.assertNull
|
||||
|
||||
/**
|
||||
* Tests for {@link VersionParser}.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
class VersionParserTests {
|
||||
|
||||
@Rule
|
||||
public final ExpectedException thrown = ExpectedException.none()
|
||||
|
||||
private VersionParser parser = new VersionParser(Collections.EMPTY_LIST)
|
||||
|
||||
@Test
|
||||
void noQualifierString() {
|
||||
def version = parser.parse('1.2.0')
|
||||
assertThat(version.toString(), equalTo('1.2.0'))
|
||||
}
|
||||
|
||||
@Test
|
||||
void withQualifierString() {
|
||||
def version = parser.parse('1.2.0.RELEASE')
|
||||
assertThat(version.toString(), equalTo('1.2.0.RELEASE'))
|
||||
}
|
||||
|
||||
@Test
|
||||
void withQualifierAndVersionString() {
|
||||
def version = parser.parse('1.2.0.RC2')
|
||||
assertThat(version.toString(), equalTo('1.2.0.RC2'))
|
||||
}
|
||||
|
||||
@Test
|
||||
void parseInvalidVersion() {
|
||||
thrown.expect(InvalidVersionException)
|
||||
parser.parse('foo')
|
||||
}
|
||||
|
||||
@Test
|
||||
void safeParseInvalidVersion() {
|
||||
assertNull parser.safeParse('foo')
|
||||
}
|
||||
|
||||
@Test
|
||||
void parseVersionWithSpaces() {
|
||||
assertThat(parser.parse(' 1.2.0.RC3 '),
|
||||
lessThan(parser.parse('1.3.0.RELEASE')))
|
||||
}
|
||||
|
||||
@Test
|
||||
void parseVariableVersionMatch() {
|
||||
List<Version> currentVersions = Arrays.asList(parser.parse('1.3.8.RELEASE'),
|
||||
parser.parse('1.3.9.BUILD-SNAPSHOT'))
|
||||
parser = new VersionParser(currentVersions)
|
||||
assertThat(parser.parse('1.3.x.BUILD-SNAPSHOT').toString(),
|
||||
equalTo('1.3.9.BUILD-SNAPSHOT'))
|
||||
}
|
||||
|
||||
@Test
|
||||
void parseVariableVersionNoPatchMatch() {
|
||||
List<Version> currentVersions = Arrays.asList(parser.parse('1.3.8.RELEASE'),
|
||||
parser.parse('1.3.9.BUILD-SNAPSHOT'))
|
||||
parser = new VersionParser(currentVersions)
|
||||
assertThat(parser.parse('1.x.x.RELEASE').toString(),
|
||||
equalTo('1.3.8.RELEASE'))
|
||||
}
|
||||
|
||||
@Test
|
||||
void parseVariableVersionNoQualifierMatch() {
|
||||
List<Version> currentVersions = Arrays.asList(parser.parse('1.3.8.RELEASE'),
|
||||
parser.parse('1.4.0.BUILD-SNAPSHOT'))
|
||||
parser = new VersionParser(currentVersions)
|
||||
assertThat(parser.parse('1.4.x').toString(),
|
||||
equalTo('1.4.0.BUILD-SNAPSHOT'))
|
||||
}
|
||||
|
||||
@Test
|
||||
void parseVariableVersionNoMatch() {
|
||||
List<Version> currentVersions = Arrays.asList(parser.parse('1.3.8.RELEASE'),
|
||||
parser.parse('1.3.9.BUILD-SNAPSHOT'))
|
||||
parser = new VersionParser(currentVersions)
|
||||
assertThat(parser.parse('1.4.x.BUILD-SNAPSHOT').toString(),
|
||||
equalTo("1.4.999.BUILD-SNAPSHOT"))
|
||||
}
|
||||
|
||||
@Test
|
||||
void parseVariableVersionNoPatchNoMatch() {
|
||||
List<Version> currentVersions = Arrays.asList(parser.parse('1.3.8.RELEASE'),
|
||||
parser.parse('1.3.9.BUILD-SNAPSHOT'))
|
||||
parser = new VersionParser(currentVersions)
|
||||
assertThat(parser.parse('2.x.x.RELEASE').toString(),
|
||||
equalTo("2.999.999.RELEASE"))
|
||||
}
|
||||
|
||||
@Test
|
||||
void parseVariableVersionNoQualifierNoMatch() {
|
||||
List<Version> currentVersions = Arrays.asList(parser.parse('1.3.8.RELEASE'),
|
||||
parser.parse('1.4.0.BUILD-SNAPSHOT'))
|
||||
parser = new VersionParser(currentVersions)
|
||||
assertThat(parser.parse('1.2.x').toString(), equalTo("1.2.999"))
|
||||
}
|
||||
|
||||
@Test
|
||||
void invalidRange() {
|
||||
thrown.expect(InvalidVersionException)
|
||||
parser.parseRange("foo-bar")
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2015 the original author or authors.
|
||||
* Copyright 2012-2016 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.
|
||||
@@ -83,29 +83,54 @@ class VersionRangeTests {
|
||||
assertThat('1.1.9.RELEASE', not(match('1.2.0.RELEASE')))
|
||||
}
|
||||
|
||||
@Test
|
||||
void invalidRange() {
|
||||
thrown.expect(InvalidVersionException)
|
||||
VersionRange.parse("foo-bar")
|
||||
}
|
||||
|
||||
@Test
|
||||
void rangeWithSpaces() {
|
||||
assertThat('1.2.0.RC3', match('[ 1.2.0.RC1 , 1.2.0.RC5]'))
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void matchLatestVersion() {
|
||||
assertThat('1.2.8.RELEASE', match('[1.2.0.RELEASE,1.2.x.BUILD-SNAPSHOT]',
|
||||
new VersionParser(Arrays.asList(Version.parse('1.2.9.BUILD-SNAPSHOT')))))
|
||||
}
|
||||
|
||||
@Test
|
||||
void matchOverLatestVersion() {
|
||||
assertThat('1.2.10.RELEASE', not(match('[1.2.0.RELEASE,1.2.x.BUILD-SNAPSHOT]',
|
||||
new VersionParser(Arrays.asList(Version.parse('1.2.9.BUILD-SNAPSHOT'))))))
|
||||
}
|
||||
|
||||
@Test
|
||||
void matchAsOfCurrentVersion() {
|
||||
assertThat('1.3.5.RELEASE', match('[1.3.x.RELEASE,1.3.x.BUILD-SNAPSHOT]',
|
||||
new VersionParser(Arrays.asList(Version.parse('1.3.4.RELEASE'),
|
||||
Version.parse('1.3.6.BUILD-SNAPSHOT')))))
|
||||
}
|
||||
|
||||
@Test
|
||||
void matchOverAsOfCurrentVersion() {
|
||||
assertThat('1.3.5.RELEASE', not(match('[1.3.x.RELEASE,1.3.x.BUILD-SNAPSHOT]',
|
||||
new VersionParser(Arrays.asList(Version.parse('1.3.7.RELEASE'),
|
||||
Version.parse('1.3.6.BUILD-SNAPSHOT'))))))
|
||||
}
|
||||
|
||||
private static VersionRangeMatcher match(String range) {
|
||||
new VersionRangeMatcher(range)
|
||||
new VersionRangeMatcher(range, new VersionParser(Collections.EMPTY_LIST))
|
||||
}
|
||||
|
||||
private static VersionRangeMatcher match(String range, VersionParser parser) {
|
||||
new VersionRangeMatcher(range, parser)
|
||||
}
|
||||
|
||||
|
||||
static class VersionRangeMatcher extends BaseMatcher<String> {
|
||||
|
||||
private final VersionRange range;
|
||||
private final VersionParser parser;
|
||||
|
||||
VersionRangeMatcher(String text) {
|
||||
this.range = VersionRange.parse(text)
|
||||
VersionRangeMatcher(String text, VersionParser parser) {
|
||||
this.parser = parser
|
||||
this.range = parser.parseRange(text)
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -113,12 +138,13 @@ class VersionRangeTests {
|
||||
if (!item instanceof String) {
|
||||
return false;
|
||||
}
|
||||
return this.range.match(Version.parse(item))
|
||||
return this.range.match(this.parser.parse((String) item))
|
||||
}
|
||||
|
||||
@Override
|
||||
void describeTo(Description description) {
|
||||
description.appendText(range)
|
||||
description.appendText(range.toString())
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2015 the original author or authors.
|
||||
* Copyright 2012-2016 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.
|
||||
@@ -16,41 +16,20 @@
|
||||
|
||||
package io.spring.initializr.util
|
||||
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.ExpectedException
|
||||
|
||||
import static io.spring.initializr.util.Version.parse
|
||||
import static io.spring.initializr.util.Version.safeParse
|
||||
import static org.hamcrest.MatcherAssert.assertThat
|
||||
import static org.hamcrest.Matchers.*
|
||||
import static org.junit.Assert.assertNull
|
||||
import static org.hamcrest.Matchers.comparesEqualTo
|
||||
import static org.hamcrest.Matchers.equalTo
|
||||
import static org.hamcrest.Matchers.greaterThan
|
||||
import static org.hamcrest.Matchers.lessThan
|
||||
|
||||
/**
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
class VersionTests {
|
||||
|
||||
@Rule
|
||||
public final ExpectedException thrown = ExpectedException.none()
|
||||
|
||||
@Test
|
||||
void noQualifierString() {
|
||||
def version = parse('1.2.0')
|
||||
assertThat(version.toString(), equalTo('1.2.0'))
|
||||
}
|
||||
|
||||
@Test
|
||||
void withQualifierString() {
|
||||
def version = parse('1.2.0.RELEASE')
|
||||
assertThat(version.toString(), equalTo('1.2.0.RELEASE'))
|
||||
}
|
||||
|
||||
@Test
|
||||
void withQualifierAndVersionString() {
|
||||
def version = parse('1.2.0.RC2')
|
||||
assertThat(version.toString(), equalTo('1.2.0.RC2'))
|
||||
}
|
||||
private static final VersionParser parser = new VersionParser(Collections.EMPTY_LIST)
|
||||
|
||||
@Test
|
||||
void equalNoQualifier() {
|
||||
@@ -146,20 +125,9 @@ class VersionTests {
|
||||
assertThat(parse('1.2.0.BUILD-SNAPSHOT'), lessThan(parse('1.2.0.RELEASE')))
|
||||
}
|
||||
|
||||
@Test
|
||||
void parseInvalidVersion() {
|
||||
thrown.expect(InvalidVersionException)
|
||||
parse('foo')
|
||||
}
|
||||
|
||||
@Test
|
||||
void safeParseInvalidVersion() {
|
||||
assertNull safeParse('foo')
|
||||
}
|
||||
|
||||
@Test
|
||||
void parseVersionWithSpaces() {
|
||||
assertThat(parse(' 1.2.0.RC3 '), lessThan(parse('1.3.0.RELEASE')))
|
||||
private static Version parse(String text) {
|
||||
def version = parser.parse(text)
|
||||
version
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user