mirror of
https://gitee.com/dcren/initializr.git
synced 2025-07-15 23:13:30 +08:00
Improve support for version token
This commit fixes the use of version token with Gradle. The standard format with maven is "foo-bar.version" while Gradle uses "fooBarVersion". The former format does not work with Gradle as it attempts to interpret "-" as an operation. A `VersionProperty` now defines a standard structure for the property and allow to derive a camel cased version. That way, Maven still uses the standard format while Gradle generates a consistent "fooBarVersion" property. Closes gh-396
This commit is contained in:
parent
aff85819a9
commit
fae8769748
@ -20,6 +20,8 @@ import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import io.spring.initializr.util.VersionProperty;
|
||||
|
||||
/**
|
||||
* Build properties associated to a project request.
|
||||
*
|
||||
@ -41,7 +43,7 @@ public class BuildProperties {
|
||||
/**
|
||||
* Version properties. Shared between the two build systems.
|
||||
*/
|
||||
private final TreeMap<String, Supplier<String>> versions = new TreeMap<>();
|
||||
private final TreeMap<VersionProperty, Supplier<String>> versions = new TreeMap<>();
|
||||
|
||||
public Map<String, Supplier<String>> getMaven() {
|
||||
return maven;
|
||||
@ -51,7 +53,7 @@ public class BuildProperties {
|
||||
return gradle;
|
||||
}
|
||||
|
||||
public Map<String, Supplier<String>> getVersions() {
|
||||
public Map<VersionProperty, Supplier<String>> getVersions() {
|
||||
return versions;
|
||||
}
|
||||
|
||||
|
@ -25,6 +25,7 @@ import java.nio.charset.Charset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -39,6 +40,7 @@ import io.spring.initializr.metadata.InitializrMetadataProvider;
|
||||
import io.spring.initializr.metadata.MetadataElement;
|
||||
import io.spring.initializr.util.TemplateRenderer;
|
||||
import io.spring.initializr.util.Version;
|
||||
import io.spring.initializr.util.VersionProperty;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@ -361,11 +363,9 @@ public class ProjectGenerator {
|
||||
model.put("hasRepositories", true);
|
||||
}
|
||||
|
||||
List<BillOfMaterials> resolvedBoms = request.getBoms().values().stream()
|
||||
.sorted(Comparator.comparing(BillOfMaterials::getOrder))
|
||||
.collect(Collectors.toList());
|
||||
List<Map<String,String>> resolvedBoms = buildResolvedBoms(request);
|
||||
model.put("resolvedBoms", resolvedBoms);
|
||||
ArrayList<BillOfMaterials> reversedBoms = new ArrayList<>(resolvedBoms);
|
||||
ArrayList<Map<String,String>> reversedBoms = new ArrayList<>(resolvedBoms);
|
||||
Collections.reverse(reversedBoms);
|
||||
model.put("reversedBoms", reversedBoms);
|
||||
|
||||
@ -390,7 +390,7 @@ public class ProjectGenerator {
|
||||
Map<String, String> versions = new LinkedHashMap<>();
|
||||
model.put("buildPropertiesVersions", versions.entrySet());
|
||||
request.getBuildProperties().getVersions().forEach((k, v) ->
|
||||
versions.put(k, v.get()));
|
||||
versions.put(computeVersionProperty(request,k), v.get()));
|
||||
Map<String, String> gradle = new LinkedHashMap<>();
|
||||
model.put("buildPropertiesGradle", gradle.entrySet());
|
||||
request.getBuildProperties().getGradle().forEach((k, v) ->
|
||||
@ -455,6 +455,31 @@ public class ProjectGenerator {
|
||||
return model;
|
||||
}
|
||||
|
||||
private List<Map<String,String>> buildResolvedBoms(ProjectRequest request) {
|
||||
return request.getBoms().values().stream()
|
||||
.sorted(Comparator.comparing(BillOfMaterials::getOrder))
|
||||
.map(bom -> toBomModel(request, bom))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private Map<String,String> toBomModel(ProjectRequest request, BillOfMaterials bom) {
|
||||
Map<String, String> model = new HashMap<>();
|
||||
model.put("groupId", bom.getGroupId());
|
||||
model.put("artifactId", bom.getArtifactId());
|
||||
model.put("versionToken", (bom.getVersionProperty() != null
|
||||
? "${" + computeVersionProperty(request, bom.getVersionProperty()) + "}"
|
||||
: bom.getVersion()));
|
||||
return model;
|
||||
}
|
||||
|
||||
private String computeVersionProperty(ProjectRequest request,
|
||||
VersionProperty property) {
|
||||
if (isGradleBuild(request)) {
|
||||
return property.toCamelCaseFormat();
|
||||
}
|
||||
return property.toStandardFormat();
|
||||
}
|
||||
|
||||
protected void setupTestModel(ProjectRequest request, Map<String, Object> model) {
|
||||
String imports = "";
|
||||
String testAnnotations = "";
|
||||
|
@ -29,6 +29,7 @@ import io.spring.initializr.metadata.InitializrMetadata;
|
||||
import io.spring.initializr.metadata.Repository;
|
||||
import io.spring.initializr.metadata.Type;
|
||||
import io.spring.initializr.util.Version;
|
||||
import io.spring.initializr.util.VersionProperty;
|
||||
|
||||
import org.springframework.beans.BeanWrapperImpl;
|
||||
import org.springframework.util.StringUtils;
|
||||
@ -226,10 +227,11 @@ public class ProjectRequest extends BasicProjectRequest {
|
||||
buildProperties.getMaven().put("project.build.sourceEncoding", () -> "UTF-8");
|
||||
buildProperties.getMaven().put("project.reporting.outputEncoding",
|
||||
() -> "UTF-8");
|
||||
buildProperties.getVersions().put("java.version", this::getJavaVersion);
|
||||
buildProperties.getVersions().put(new VersionProperty("java.version"),
|
||||
this::getJavaVersion);
|
||||
if ("kotlin".equals(getLanguage())) {
|
||||
buildProperties.getVersions().put("kotlin.version", () -> metadata
|
||||
.getConfiguration().getEnv().getKotlin().getVersion());
|
||||
buildProperties.getVersions().put(new VersionProperty("kotlin.version"),
|
||||
() -> metadata.getConfiguration().getEnv().getKotlin().getVersion());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import io.spring.initializr.util.InvalidVersionException;
|
||||
import io.spring.initializr.util.Version;
|
||||
import io.spring.initializr.util.VersionParser;
|
||||
import io.spring.initializr.util.VersionProperty;
|
||||
import io.spring.initializr.util.VersionRange;
|
||||
|
||||
/**
|
||||
@ -39,7 +40,7 @@ public class BillOfMaterials {
|
||||
private String groupId;
|
||||
private String artifactId;
|
||||
private String version;
|
||||
private String versionProperty;
|
||||
private VersionProperty versionProperty;
|
||||
private Integer order = Integer.MAX_VALUE;
|
||||
private List<String> additionalBoms = new ArrayList<>();
|
||||
private List<String> repositories = new ArrayList<>();
|
||||
@ -86,18 +87,22 @@ public class BillOfMaterials {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the property to use to externalize the version of the BOM. When this is set,
|
||||
* a version property is automatically added rather than setting the version in the
|
||||
* bom declaration itself.
|
||||
* Return the {@link VersionProperty} to use to externalize the version of the BOM.
|
||||
* When this is set, a version property is automatically added rather than setting
|
||||
* the version in the bom declaration itself.
|
||||
*/
|
||||
public String getVersionProperty() {
|
||||
public VersionProperty getVersionProperty() {
|
||||
return versionProperty;
|
||||
}
|
||||
|
||||
public void setVersionProperty(String versionProperty) {
|
||||
public void setVersionProperty(VersionProperty versionProperty) {
|
||||
this.versionProperty = versionProperty;
|
||||
}
|
||||
|
||||
public void setVersionProperty(String versionPropertyName) {
|
||||
setVersionProperty(new VersionProperty(versionPropertyName));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the relative order of this BOM where lower values have higher priority. The
|
||||
* default value is {@code Integer.MAX_VALUE}, indicating lowest priority. The Spring
|
||||
@ -139,16 +144,6 @@ public class BillOfMaterials {
|
||||
return mappings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the version placeholder to use for this instance. If a version property
|
||||
* is defined, this returns the reference for the property. Otherwise this returns the
|
||||
* plain {@link #version}
|
||||
*/
|
||||
@JsonIgnore
|
||||
public String getVersionToken() {
|
||||
return (versionProperty != null ? "${" + versionProperty + "}" : version);
|
||||
}
|
||||
|
||||
public void validate() {
|
||||
if (version == null && mappings.isEmpty()) {
|
||||
throw new InvalidInitializrMetadataException(
|
||||
|
@ -23,6 +23,7 @@ import java.util.stream.Collectors;
|
||||
|
||||
import io.spring.initializr.util.Version;
|
||||
import io.spring.initializr.util.VersionParser;
|
||||
import io.spring.initializr.util.VersionProperty;
|
||||
|
||||
/**
|
||||
* Meta-data used to generate a project.
|
||||
@ -236,7 +237,7 @@ public class InitializrMetadata {
|
||||
public BillOfMaterials createSpringBootBom(String bootVersion, String versionProperty) {
|
||||
BillOfMaterials bom = BillOfMaterials.create("org.springframework.boot",
|
||||
"spring-boot-dependencies", bootVersion);
|
||||
bom.setVersionProperty(versionProperty);
|
||||
bom.setVersionProperty(new VersionProperty(versionProperty));
|
||||
bom.setOrder(100);
|
||||
return bom;
|
||||
}
|
||||
|
@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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 java.io.Serializable;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Represents a valid property for a version. A property must be lower case and
|
||||
* can define a dot or an hyphen to separate words. For instance, "foo-acme.version",
|
||||
* "foo.acme.version" or "foo-acme-version" are valid properties.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
public class VersionProperty implements Serializable, Comparable<VersionProperty> {
|
||||
|
||||
private static final List<Character> SUPPORTED_CHARS = Arrays.asList('.', '-');
|
||||
|
||||
private final String property;
|
||||
|
||||
public VersionProperty(String property) {
|
||||
this.property = validateFormat(property);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a camel cased representation of this instance.
|
||||
*/
|
||||
public String toCamelCaseFormat() {
|
||||
String[] tokens = this.property.split("\\-|\\.");
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < tokens.length; i++) {
|
||||
String part = tokens[i];
|
||||
if (i > 0) {
|
||||
part = StringUtils.capitalize(part);
|
||||
}
|
||||
sb.append(part);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public String toStandardFormat() {
|
||||
return this.property;
|
||||
}
|
||||
|
||||
|
||||
private static String validateFormat(String property) {
|
||||
for (char c : property.toCharArray()) {
|
||||
if (Character.isUpperCase(c)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Invalid property '" + property + "', must not contain upper case");
|
||||
}
|
||||
if (!Character.isLetterOrDigit(c) && !SUPPORTED_CHARS.contains(c)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Unsupported character '" + c + "' for '" + property + "'");
|
||||
}
|
||||
}
|
||||
return property;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(VersionProperty o) {
|
||||
return this.property.compareTo(o.property);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.property;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
VersionProperty that = (VersionProperty) o;
|
||||
|
||||
return property.equals(that.property);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return property.hashCode();
|
||||
}
|
||||
|
||||
}
|
@ -67,9 +67,11 @@ configurations {
|
||||
{{/providedDependencies}}
|
||||
|
||||
{{^buildPropertiesVersions.empty}}
|
||||
{{#buildPropertiesVersions}}
|
||||
ext['{{key}}'] = '{{value}}'
|
||||
ext {
|
||||
{{#buildPropertiesVersions}}
|
||||
{{key}} = '{{value}}'
|
||||
{{/buildPropertiesVersions}}
|
||||
}
|
||||
|
||||
{{/buildPropertiesVersions.empty}}
|
||||
dependencies {
|
||||
|
@ -21,6 +21,7 @@ import io.spring.initializr.metadata.Dependency;
|
||||
import io.spring.initializr.metadata.InitializrMetadata;
|
||||
import io.spring.initializr.test.generator.ProjectAssert;
|
||||
import io.spring.initializr.test.metadata.InitializrMetadataTestBuilder;
|
||||
import io.spring.initializr.util.VersionProperty;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
@ -102,10 +103,10 @@ public class ProjectGeneratorBuildTests extends AbstractProjectGeneratorTests {
|
||||
@Test
|
||||
public void versionOverride() {
|
||||
ProjectRequest request = createProjectRequest("web");
|
||||
request.getBuildProperties().getVersions().put("spring-foo.version",
|
||||
() -> "0.1.0.RELEASE");
|
||||
request.getBuildProperties().getVersions().put("spring-bar.version",
|
||||
() -> "0.2.0.RELEASE");
|
||||
request.getBuildProperties().getVersions().put(
|
||||
new VersionProperty("spring-foo.version"), () -> "0.1.0.RELEASE");
|
||||
request.getBuildProperties().getVersions().put(
|
||||
new VersionProperty("spring-bar.version"), () -> "0.2.0.RELEASE");
|
||||
ProjectAssert project = generateProject(request);
|
||||
project.sourceCodeAssert(fileName).equalsTo(new ClassPathResource(
|
||||
"project/" + build + "/version-override-" + assertFileName));
|
||||
|
@ -23,6 +23,7 @@ import io.spring.initializr.metadata.Dependency;
|
||||
import io.spring.initializr.metadata.InitializrMetadata;
|
||||
import io.spring.initializr.test.generator.ProjectAssert;
|
||||
import io.spring.initializr.test.metadata.InitializrMetadataTestBuilder;
|
||||
import io.spring.initializr.util.VersionProperty;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
@ -689,7 +690,8 @@ public class ProjectGeneratorTests extends AbstractProjectGeneratorTests {
|
||||
public void buildPropertiesMaven() {
|
||||
ProjectRequest request = createProjectRequest("web");
|
||||
request.getBuildProperties().getMaven().put("name", () -> "test");
|
||||
request.getBuildProperties().getVersions().put("foo.version", () -> "1.2.3");
|
||||
request.getBuildProperties().getVersions().put(
|
||||
new VersionProperty("foo.version"), () -> "1.2.3");
|
||||
request.getBuildProperties().getGradle().put("ignore.property", () -> "yes");
|
||||
|
||||
generateMavenPom(request).hasProperty("name", "test")
|
||||
@ -700,11 +702,13 @@ public class ProjectGeneratorTests extends AbstractProjectGeneratorTests {
|
||||
public void buildPropertiesGradle() {
|
||||
ProjectRequest request = createProjectRequest("web");
|
||||
request.getBuildProperties().getGradle().put("name", () -> "test");
|
||||
request.getBuildProperties().getVersions().put("foo.version", () -> "1.2.3");
|
||||
request.getBuildProperties().getVersions().put(
|
||||
new VersionProperty("foo.version"), () -> "1.2.3");
|
||||
request.getBuildProperties().getMaven().put("ignore.property", () -> "yes");
|
||||
|
||||
generateGradleBuild(request).contains("name = 'test'")
|
||||
.contains("ext['foo.version'] = '1.2.3'")
|
||||
.contains("ext {")
|
||||
.contains("fooVersion = '1.2.3'")
|
||||
.doesNotContain("ignore.property");
|
||||
}
|
||||
|
||||
|
@ -24,6 +24,7 @@ import java.util.Map;
|
||||
|
||||
import io.spring.initializr.metadata.InitializrMetadata;
|
||||
import io.spring.initializr.test.metadata.InitializrMetadataTestBuilder;
|
||||
import io.spring.initializr.util.VersionProperty;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
@ -57,7 +58,7 @@ public class ProjectRequestResolverTests {
|
||||
ProjectRequest request = resolve(createMavenProjectRequest(), postProcessors);
|
||||
assertEquals("1.2", request.getJavaVersion());
|
||||
assertEquals("1.2", request.getBuildProperties().getVersions()
|
||||
.get("java.version").get());
|
||||
.get(new VersionProperty("java.version")).get());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -59,7 +59,8 @@ public class BillOfMaterialsTests {
|
||||
assertThat(resolved.getGroupId(), equalTo("com.example"));
|
||||
assertThat(resolved.getArtifactId(), equalTo("bom"));
|
||||
assertThat(resolved.getVersion(), equalTo("1.1.0"));
|
||||
assertThat(resolved.getVersionProperty(), equalTo("bom.version"));
|
||||
assertThat(resolved.getVersionProperty().toStandardFormat(),
|
||||
equalTo("bom.version"));
|
||||
assertThat(resolved.getRepositories().size(), equalTo(1));
|
||||
assertThat(resolved.getRepositories().get(0), equalTo("repo-main"));
|
||||
assertThat(resolved.getAdditionalBoms().size(), equalTo(1));
|
||||
@ -98,7 +99,8 @@ public class BillOfMaterialsTests {
|
||||
assertThat(resolved.getGroupId(), equalTo("com.example"));
|
||||
assertThat(resolved.getArtifactId(), equalTo("bom"));
|
||||
assertThat(resolved.getVersion(), equalTo("1.1.0"));
|
||||
assertThat(resolved.getVersionProperty(), equalTo("example.version"));
|
||||
assertThat(resolved.getVersionProperty().toStandardFormat(),
|
||||
equalTo("example.version"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link VersionProperty}.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
public class VersionPropertyTests {
|
||||
|
||||
@Rule
|
||||
public ExpectedException thrown = ExpectedException.none();
|
||||
|
||||
@Test
|
||||
public void testStandardProperty() {
|
||||
assertThat(new VersionProperty("spring-boot.version")
|
||||
.toStandardFormat()).isEqualTo("spring-boot.version");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCamelCaseProperty() {
|
||||
assertThat(new VersionProperty("spring-boot.version")
|
||||
.toCamelCaseFormat()).isEqualTo("springBootVersion");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStandardPropertyWithNoSeparator() {
|
||||
assertThat(new VersionProperty("springbootversion")
|
||||
.toStandardFormat()).isEqualTo("springbootversion");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCamelCasePropertyWithNoSeparator() {
|
||||
assertThat(new VersionProperty("springbootversion")
|
||||
.toCamelCaseFormat()).isEqualTo("springbootversion");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInvalidPropertyUpperCase() {
|
||||
this.thrown.expect(IllegalArgumentException.class);
|
||||
this.thrown.expectMessage("upper case");
|
||||
new VersionProperty("Spring-boot.version");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInvalidPropertyIllegalCharacter() {
|
||||
this.thrown.expect(IllegalArgumentException.class);
|
||||
this.thrown.expectMessage("Unsupported character");
|
||||
new VersionProperty("spring-boot_version");
|
||||
}
|
||||
|
||||
}
|
@ -24,7 +24,9 @@ repositories {
|
||||
}
|
||||
|
||||
|
||||
ext['foo.version'] = '1.3.3'
|
||||
ext {
|
||||
fooVersion = '1.3.3'
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile('org.acme:foo')
|
||||
@ -33,6 +35,6 @@ dependencies {
|
||||
|
||||
dependencyManagement {
|
||||
imports {
|
||||
mavenBom "org.acme:foo-bom:${foo.version}"
|
||||
mavenBom "org.acme:foo-bom:${fooVersion}"
|
||||
}
|
||||
}
|
||||
|
@ -24,8 +24,10 @@ repositories {
|
||||
}
|
||||
|
||||
|
||||
ext['spring-bar.version'] = '0.2.0.RELEASE'
|
||||
ext['spring-foo.version'] = '0.1.0.RELEASE'
|
||||
ext {
|
||||
springBarVersion = '0.2.0.RELEASE'
|
||||
springFooVersion = '0.1.0.RELEASE'
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile('org.springframework.boot:spring-boot-starter-web')
|
||||
|
Loading…
Reference in New Issue
Block a user