mirror of
https://gitee.com/dcren/initializr.git
synced 2026-02-26 05:32:58 +08:00
Merge branch 'gh-1092'
Closes gh-1092
This commit is contained in:
@@ -542,21 +542,30 @@ it. The versions are *not* applied to the dependency itself, but rather used to
|
||||
the dependency, or modify it, when different versions of Spring Boot are selected for the
|
||||
generated project.
|
||||
|
||||
A typical version is composed of four parts: a major revision, a minor revision, a patch
|
||||
revision and a qualifier. Qualifiers are ordered as follows:
|
||||
A version is composed of four parts: a major revision, a minor revision, a patch
|
||||
revision and an optional qualifier. Spring Initializr supports two version formats:
|
||||
|
||||
* `V1` is the original format where the qualifier is separated from the version by a dot.
|
||||
It also uses well-defined qualifiers for snapshots (`BUILD-SNAPSHOT`) and General
|
||||
Availability (`RELEASE`).
|
||||
* `V2` is an improved format that is SemVer compliant, and therefore uses a dash to
|
||||
separate the qualifier. There is no qualifier for GAs.
|
||||
|
||||
Speaking of qualifiers, they are ordered as follows:
|
||||
|
||||
* `M` for milestones (e.g. `2.0.0.M1` is the first milestone of the upcoming 2.0.0
|
||||
release): can be seen as "beta" release
|
||||
* `RC` for release candidates (e.g. `2.0.0.RC2` is the second release candidate of
|
||||
* `RC` for release candidates (e.g. `2.0.0-RC2` is the second release candidate of
|
||||
upcoming 2.0.0 release)
|
||||
* `RELEASE` for general availability (e.g. `2.0.0.RELEASE` is 2.0.0 proper)
|
||||
* `BUILD-SNAPSHOT` for development build (`2.1.0.BUILD-SNAPSHOT` represents the latest
|
||||
available development build of the upcoming 2.1.0 release).
|
||||
|
||||
TIP: snapshots are in a bit special in that scheme as they always represents the "latest
|
||||
state" of a release. `M1` represents the most oldest version for a given major, minor and
|
||||
patch revisions.
|
||||
available development build of the upcoming 2.1.0 release). For the `V2` format, it is
|
||||
simply `SNAPSHOT`, i.e. `2.1.0-SNAPSHOT`.
|
||||
* `RELEASE` for general availability (e.g. `2.0.0.RELEASE` is 2.0.0 proper)
|
||||
|
||||
TIP: snapshots are in a bit special in that scheme as they always represent the "latest
|
||||
state" of a release. `M1` represents the oldest version for a given major, minor and
|
||||
patch revisions, and it can therefore be safely used when referring to the "first" release
|
||||
in that line.
|
||||
|
||||
A version range has a lower and an upper bound, and if the bound is inclusive it is
|
||||
denoted as a square bracket (`[` or `]`), otherwise it is exclusive and denoted by a
|
||||
@@ -572,7 +581,7 @@ an hard-coded version. For instance, `1.4.x.BUILD-SNAPSHOT` is the latest snapsh
|
||||
of the 1.4.x line. For instance, if you want to restrict a dependency from `1.1.0.RELEASE`
|
||||
to the latest stable release of the 1.3.x line, you'd use `[1.1.0.RELEASE,1.3.x.RELEASE]`.
|
||||
|
||||
Snapshots are naturally ordered higher than released versions, so if you are looking to
|
||||
Snapshots are naturally the most recent version of a given line, so if you are looking to
|
||||
match a dependency to only the latest snapshots of Spring Boot, you could use a version
|
||||
range of `1.5.x.BUILD-SNAPSHOT` (assuming 1.5 was the latest).
|
||||
|
||||
@@ -580,7 +589,8 @@ TIP: Remember to quote the values of a version range in YAML configuration files
|
||||
double quotes "").
|
||||
|
||||
See below in the section on <<howto-link-boot-version,linking versions>> for more examples
|
||||
and idioms.
|
||||
and idioms. See also how the <<howto-platform-version-format,platform version format>> can
|
||||
be configured.
|
||||
|
||||
|
||||
|
||||
@@ -1017,6 +1027,30 @@ These dependencies, by default, will be available only for Spring Boot versions
|
||||
|
||||
|
||||
|
||||
[[howto-platform-version-format]]
|
||||
=== Configure platform version format
|
||||
Spring Initializr supports two formats: `V1` is the original format defined by metadata
|
||||
up to `2.1`. `V2` is the SemVer format provided alongside `V1` as of metadata `2.2`. In
|
||||
order to serve backward compatible content, the version range for each format should be
|
||||
configured so that translations can happen accordingly.
|
||||
|
||||
Let's assume that an instance only supports `2.0.0` and later and the platform version is
|
||||
using the original format up to `2.4.0` (excluded). As of `2.4.0`, the improved, SemVer
|
||||
format is used. The following configures the instance to adapt version format
|
||||
automatically:
|
||||
|
||||
[source,yaml,indent=0]
|
||||
----
|
||||
initializr:
|
||||
env:
|
||||
platform:
|
||||
compatibility-range: "2.0.0.RELEASE"
|
||||
v1-format-compatibility-range: "[2.0.0.RELEASE,2.4.0-M1)"
|
||||
v2-format-compatibility-range: "2.4.0-M1"
|
||||
----
|
||||
|
||||
|
||||
|
||||
[[create-instance-advanced-config]]
|
||||
== Advanced configuration
|
||||
|
||||
|
||||
@@ -13,10 +13,16 @@ sent to the service. A good structure for a user agent is `clientId/clientVersio
|
||||
== Service Capabilities
|
||||
Any third party client can retrieve the capabilities of the service by issuing a
|
||||
`GET` on the root URL using the following `Accept` header:
|
||||
`application/vnd.initializr.v2.1+json`. Please note that the metadata may evolve in a
|
||||
`application/vnd.initializr.v2.2+json`. Please note that the metadata may evolve in a
|
||||
non backward compatible way in the future so adding this header ensures the service
|
||||
returns the metadata format you expect.
|
||||
|
||||
The following versions are supported:
|
||||
|
||||
* `v2` initial version, with support of V1 version format only
|
||||
* `v2.1` support compatibility range and dependencies links
|
||||
* `v2.2` (current) support for V1 and V2 version formats.
|
||||
|
||||
This is an example output for a service running at `https://start.spring.io`:
|
||||
|
||||
.request
|
||||
|
||||
@@ -110,7 +110,7 @@ include::{test-examples}/stub/ClientApplicationTests.java[tag=test]
|
||||
|
||||
Then you have a server that returns the stub of the JSON metadata
|
||||
(`metadataWithCurrentAcceptHeader.json`) when you send it a header
|
||||
`Accept:application/vnd.initializr.v2.1+json` (as recommended).
|
||||
`Accept:application/vnd.initializr.v2.2+json` (as recommended).
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ import io.spring.initializr.metadata.Dependency;
|
||||
import io.spring.initializr.metadata.DependencyGroup;
|
||||
import io.spring.initializr.metadata.InitializrConfiguration.Env.Kotlin;
|
||||
import io.spring.initializr.metadata.InitializrConfiguration.Env.Maven.ParentPom;
|
||||
import io.spring.initializr.metadata.InitializrConfiguration.Platform;
|
||||
import io.spring.initializr.metadata.InitializrMetadata;
|
||||
import io.spring.initializr.metadata.InitializrMetadataBuilder;
|
||||
import io.spring.initializr.metadata.Repository;
|
||||
@@ -188,7 +189,16 @@ public class InitializrMetadataTestBuilder {
|
||||
|
||||
public InitializrMetadataTestBuilder setPlatformCompatibilityRange(String platformCompatibilityRange) {
|
||||
this.builder.withCustomizer(
|
||||
(it) -> it.getConfiguration().getEnv().setPlatformCompatibilityRange(platformCompatibilityRange));
|
||||
(it) -> it.getConfiguration().getEnv().getPlatform().setCompatibilityRange(platformCompatibilityRange));
|
||||
return this;
|
||||
}
|
||||
|
||||
public InitializrMetadataTestBuilder setPlatformVersionFormatCompatibilityRange(String v1Range, String v2Range) {
|
||||
this.builder.withCustomizer((it) -> {
|
||||
Platform platform = it.getConfiguration().getEnv().getPlatform();
|
||||
platform.setV1FormatCompatibilityRange(v1Range);
|
||||
platform.setV2FormatCompatibilityRange(v2Range);
|
||||
});
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@@ -23,19 +23,25 @@ import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.StringJoiner;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Define the version number of a module. A typical version is represented as
|
||||
* {@code MAJOR.MINOR.PATCH.QUALIFIER} where the qualifier can have an extra version.
|
||||
* Define a version. A typical version is represented as
|
||||
* {@code MAJOR.MINOR.PATCH[QUALIFIER]} where the qualifier is optional and can have an
|
||||
* extra version.
|
||||
* <p>
|
||||
* For example: {@code 1.2.0.RC1} is the first release candidate of 1.2.0 and
|
||||
* {@code 1.5.0.M4} is the fourth milestone of 1.5.0. The special {@code RELEASE}
|
||||
* qualifier indicates a final release (a.k.a. GA)
|
||||
* {@code 1.5.0-M4} is the fourth milestone of 1.5.0. The special {@code RELEASE}
|
||||
* qualifier indicates a final release (a.k.a. GA).
|
||||
* <p>
|
||||
* The main purpose of parsing a version is to compare it with another version, see
|
||||
* {@link Comparable}.
|
||||
* Two formats are currently supported, {@link Format#V1} that uses a dot to separate the
|
||||
* qualifier from the version itself and {@link Format#V2} that is SemVer compliant (and
|
||||
* therefore uses a dash to separate the qualifier).
|
||||
* <p>
|
||||
* The main purpose of parsing a version is to compare it with another version.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
@@ -54,11 +60,68 @@ public final class Version implements Serializable, Comparable<Version> {
|
||||
|
||||
private final Qualifier qualifier;
|
||||
|
||||
private final Format format;
|
||||
|
||||
public Version(Integer major, Integer minor, Integer patch, Qualifier qualifier) {
|
||||
this.major = major;
|
||||
this.minor = minor;
|
||||
this.patch = patch;
|
||||
this.qualifier = qualifier;
|
||||
this.format = determineFormat(qualifier);
|
||||
}
|
||||
|
||||
private static Format determineFormat(Qualifier qualifier) {
|
||||
if (qualifier == null) {
|
||||
return Format.V2;
|
||||
}
|
||||
return (qualifier.getSeparator().equals(".")) ? Format.V1 : Format.V2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format this version to the specified {@link Format}.
|
||||
* @param format the format to use
|
||||
* @return a version compliant with the specified format.
|
||||
*/
|
||||
public Version format(Format format) {
|
||||
Assert.notNull(format, () -> "Format must not be null");
|
||||
if (this.format == format) {
|
||||
return this;
|
||||
}
|
||||
if (format == Format.V1) {
|
||||
Qualifier qualifier = formatQualifier(".", this::toV1Qualifier);
|
||||
return new Version(this.major, this.minor, this.patch, qualifier);
|
||||
}
|
||||
Qualifier qualifier = formatQualifier("-", this::toV2Qualifier);
|
||||
return new Version(this.major, this.minor, this.patch, qualifier);
|
||||
}
|
||||
|
||||
private Qualifier formatQualifier(String newSeparator, Function<String, String> idTransformer) {
|
||||
String originalQualifier = (this.qualifier != null) ? this.qualifier.getId() : null;
|
||||
String newId = idTransformer.apply(originalQualifier);
|
||||
if (newId != null) {
|
||||
return new Qualifier(newId, (this.qualifier != null) ? this.qualifier.getVersion() : null, newSeparator);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private String toV1Qualifier(String id) {
|
||||
if ("SNAPSHOT".equals(id)) {
|
||||
return "BUILD-SNAPSHOT";
|
||||
}
|
||||
if (id == null) {
|
||||
return "RELEASE";
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
private String toV2Qualifier(String id) {
|
||||
if ("BUILD-SNAPSHOT".equals(id)) {
|
||||
return "SNAPSHOT";
|
||||
}
|
||||
if ("RELEASE".equals(id)) {
|
||||
return null;
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
public Integer getMajor() {
|
||||
@@ -77,6 +140,10 @@ public final class Version implements Serializable, Comparable<Version> {
|
||||
return this.qualifier;
|
||||
}
|
||||
|
||||
public Format getFormat() {
|
||||
return this.format;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the string representation of a {@link Version}. Throws an
|
||||
* {@link InvalidVersionException} if the version could not be parsed.
|
||||
@@ -262,6 +329,26 @@ public final class Version implements Serializable, Comparable<Version> {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Define the supported version format.
|
||||
*/
|
||||
public enum Format {
|
||||
|
||||
/**
|
||||
* Original version format, i.e. {@code Major.Minor.Patch.Qualifier} using
|
||||
* {@code BUILD-SNAPSHOT} as the qualifier for snapshots and {@code RELEASE} for
|
||||
* GAs.
|
||||
*/
|
||||
V1,
|
||||
|
||||
/**
|
||||
* SemVer-compliant format, i.e. {@code Major.Minor.Patch-Qualifier} using
|
||||
* {@code SNAPSHOT} as the qualifier for snapshots and no qualifier for GAs.
|
||||
*/
|
||||
V2;
|
||||
|
||||
}
|
||||
|
||||
private static class VersionQualifierComparator implements Comparator<Qualifier> {
|
||||
|
||||
static final String RELEASE = "RELEASE";
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2020 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,6 +16,8 @@
|
||||
|
||||
package io.spring.initializr.generator.version;
|
||||
|
||||
import io.spring.initializr.generator.version.Version.Format;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
@@ -27,9 +29,8 @@ import org.springframework.util.Assert;
|
||||
* <ul>
|
||||
* <li>"[1.2.0.RELEASE,1.3.0.RELEASE)" version 1.2.0 and any version after this, up to,
|
||||
* but not including, version 1.3.0.</li>
|
||||
* <li>"(2.0.0.RELEASE,3.2.0.RELEASE]" any version after 2.0.0 up to and including version
|
||||
* 3.2.0.</li>
|
||||
* <li>"1.4.5.RELEASE", version 1.4.5 and all later versions.</li>
|
||||
* <li>"(2.0.0,3.2.0]" any version after 2.0.0 up to and including version 3.2.0.</li>
|
||||
* <li>"2.5.0-M1", the first milestone of 2.5.0 and any version after that.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
@@ -83,6 +84,17 @@ public class VersionRange {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format this version range to the specified {@link Format}.
|
||||
* @param format the version format to use
|
||||
* @return a version range whose boundaries are compliant with the specified format.
|
||||
*/
|
||||
public VersionRange format(Format format) {
|
||||
Version lower = this.lowerVersion.format(format);
|
||||
Version higher = (this.higherVersion != null) ? this.higherVersion.format(format) : null;
|
||||
return new VersionRange(lower, this.lowerInclusive, higher, this.higherInclusive);
|
||||
}
|
||||
|
||||
public Version getLowerVersion() {
|
||||
return this.lowerVersion;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2020 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.
|
||||
@@ -19,12 +19,15 @@ package io.spring.initializr.generator.version;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
|
||||
import io.spring.initializr.generator.version.Version.Format;
|
||||
import org.assertj.core.api.Condition;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link VersionRange}.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
class VersionRangeTests {
|
||||
@@ -148,6 +151,34 @@ class VersionRangeTests {
|
||||
assertThat(range.toRangeString()).isEqualTo("(1.3.5.RELEASE,1.5.5.RELEASE)");
|
||||
}
|
||||
|
||||
@Test
|
||||
void formatLowerOnlyV1toV2() {
|
||||
VersionRange range = parse("1.2.0.RELEASE").format(Format.V2);
|
||||
assertThat(range.toRangeString()).isEqualTo("1.2.0");
|
||||
}
|
||||
|
||||
@Test
|
||||
void formatV1toV2() {
|
||||
VersionRange range = parse("[1.2.0.RELEASE,1.3.0.M1)").format(Format.V2);
|
||||
assertThat(range.toRangeString()).isEqualTo("[1.2.0,1.3.0-M1)");
|
||||
}
|
||||
|
||||
@Test
|
||||
void formatLowerOnlyV2toV1() {
|
||||
VersionRange range = parse("1.2.0").format(Format.V1);
|
||||
assertThat(range.toRangeString()).isEqualTo("1.2.0.RELEASE");
|
||||
}
|
||||
|
||||
@Test
|
||||
void formatV2toV1() {
|
||||
VersionRange range = parse("[1.2.0,1.3.0-M1)").format(Format.V1);
|
||||
assertThat(range.toRangeString()).isEqualTo("[1.2.0.RELEASE,1.3.0.M1)");
|
||||
}
|
||||
|
||||
private static VersionRange parse(String text) {
|
||||
return new VersionParser(Collections.emptyList()).parseRange(text);
|
||||
}
|
||||
|
||||
private static Condition<String> match(String range) {
|
||||
return match(range, new VersionParser(Collections.emptyList()));
|
||||
}
|
||||
|
||||
@@ -21,11 +21,14 @@ import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import io.spring.initializr.generator.version.Version.Format;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link Version}.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
class VersionTests {
|
||||
@@ -153,6 +156,54 @@ class VersionTests {
|
||||
"2020.0.0-SNAPSHOT", "2020.0.0");
|
||||
}
|
||||
|
||||
@Test
|
||||
void formatV1toV1() {
|
||||
Version version = Version.parse("1.2.0.RELEASE");
|
||||
assertThat(version.format(Format.V1)).isSameAs(version);
|
||||
}
|
||||
|
||||
@Test
|
||||
void formatV1SnapshotToV2() {
|
||||
Version version = Version.parse("1.2.0.BUILD-SNAPSHOT");
|
||||
assertThat(version.format(Format.V2)).hasToString("1.2.0-SNAPSHOT");
|
||||
}
|
||||
|
||||
@Test
|
||||
void formatV1GAToV2() {
|
||||
Version version = Version.parse("1.2.0.RELEASE");
|
||||
assertThat(version.format(Format.V2)).hasToString("1.2.0");
|
||||
}
|
||||
|
||||
@Test
|
||||
void formatNoQualifierToV1() {
|
||||
Version version = Version.parse("1.2.0");
|
||||
assertThat(version.format(Format.V1)).hasToString("1.2.0.RELEASE");
|
||||
}
|
||||
|
||||
@Test
|
||||
void formatV2toV2() {
|
||||
Version version = Version.parse("1.2.0-RC1");
|
||||
assertThat(version.format(Format.V2)).isSameAs(version);
|
||||
}
|
||||
|
||||
@Test
|
||||
void formatV2SnapshotToV1() {
|
||||
Version version = Version.parse("1.2.0-SNAPSHOT");
|
||||
assertThat(version.format(Format.V1)).hasToString("1.2.0.BUILD-SNAPSHOT");
|
||||
}
|
||||
|
||||
@Test
|
||||
void formatV2GAToV1() {
|
||||
Version version = Version.parse("1.2.0");
|
||||
assertThat(version.format(Format.V1)).hasToString("1.2.0.RELEASE");
|
||||
}
|
||||
|
||||
@Test
|
||||
void formatNoQualifierToV2() {
|
||||
Version version = Version.parse("1.2.0");
|
||||
assertThat(version.format(Format.V2)).hasToString("1.2.0");
|
||||
}
|
||||
|
||||
private Version parse(String text) {
|
||||
return this.parser.parse(text);
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ import javax.lang.model.SourceVersion;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import io.spring.initializr.generator.version.InvalidVersionException;
|
||||
import io.spring.initializr.generator.version.Version;
|
||||
import io.spring.initializr.generator.version.Version.Format;
|
||||
import io.spring.initializr.generator.version.VersionParser;
|
||||
import io.spring.initializr.generator.version.VersionRange;
|
||||
|
||||
@@ -210,16 +211,6 @@ public class InitializrConfiguration {
|
||||
*/
|
||||
private boolean forceSsl;
|
||||
|
||||
/**
|
||||
* Compatibility range of supported platform versions. Requesting metadata or
|
||||
* project generation with a platform version that does not match this range is
|
||||
* not supported.
|
||||
*/
|
||||
private String platformCompatibilityRange;
|
||||
|
||||
@JsonIgnore
|
||||
private VersionRange compatibilityRange;
|
||||
|
||||
/**
|
||||
* The "BillOfMaterials" that are referenced in this instance, identified by an
|
||||
* arbitrary identifier that can be used in the dependencies definition.
|
||||
@@ -250,6 +241,12 @@ public class InitializrConfiguration {
|
||||
@NestedConfigurationProperty
|
||||
private final Maven maven = new Maven();
|
||||
|
||||
/**
|
||||
* Platform-specific settings.
|
||||
*/
|
||||
@NestedConfigurationProperty
|
||||
private final Platform platform = new Platform();
|
||||
|
||||
public Env() {
|
||||
try {
|
||||
this.repositories.put("spring-snapshots",
|
||||
@@ -310,14 +307,6 @@ public class InitializrConfiguration {
|
||||
this.forceSsl = forceSsl;
|
||||
}
|
||||
|
||||
public String getPlatformCompatibilityRange() {
|
||||
return this.platformCompatibilityRange;
|
||||
}
|
||||
|
||||
public void setPlatformCompatibilityRange(String platformCompatibilityRange) {
|
||||
this.platformCompatibilityRange = platformCompatibilityRange;
|
||||
}
|
||||
|
||||
public String getArtifactRepository() {
|
||||
return this.artifactRepository;
|
||||
}
|
||||
@@ -342,6 +331,10 @@ public class InitializrConfiguration {
|
||||
return this.maven;
|
||||
}
|
||||
|
||||
public Platform getPlatform() {
|
||||
return this.platform;
|
||||
}
|
||||
|
||||
public void setArtifactRepository(String artifactRepository) {
|
||||
if (!artifactRepository.endsWith("/")) {
|
||||
artifactRepository = artifactRepository + "/";
|
||||
@@ -359,8 +352,7 @@ public class InitializrConfiguration {
|
||||
public void updateCompatibilityRange(VersionParser versionParser) {
|
||||
this.getBoms().values().forEach((it) -> it.updateCompatibilityRange(versionParser));
|
||||
this.getKotlin().updateCompatibilityRange(versionParser);
|
||||
this.compatibilityRange = (this.platformCompatibilityRange != null)
|
||||
? versionParser.parseRange(this.platformCompatibilityRange) : null;
|
||||
this.getPlatform().updateCompatibilityRange(versionParser);
|
||||
}
|
||||
|
||||
public void merge(Env other) {
|
||||
@@ -370,29 +362,14 @@ public class InitializrConfiguration {
|
||||
this.fallbackApplicationName = other.fallbackApplicationName;
|
||||
this.invalidApplicationNames = other.invalidApplicationNames;
|
||||
this.forceSsl = other.forceSsl;
|
||||
this.platformCompatibilityRange = other.platformCompatibilityRange;
|
||||
this.compatibilityRange = other.compatibilityRange;
|
||||
this.gradle.merge(other.gradle);
|
||||
this.kotlin.merge(other.kotlin);
|
||||
this.maven.merge(other.maven);
|
||||
this.platform.merge(other.platform);
|
||||
other.boms.forEach(this.boms::putIfAbsent);
|
||||
other.repositories.forEach(this.repositories::putIfAbsent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify whether the specified {@linkplain Version platform version} is
|
||||
* supported.
|
||||
* @param platformVersion the platform version to check
|
||||
* @return {@code true} if this version is supported, {@code false} otherwise
|
||||
*/
|
||||
public boolean isCompatiblePlatformVersion(Version platformVersion) {
|
||||
return (this.compatibilityRange == null || this.compatibilityRange.match(platformVersion));
|
||||
}
|
||||
|
||||
public String determinePlatformCompatibilityRangeRequirement() {
|
||||
return this.compatibilityRange.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gradle details.
|
||||
*/
|
||||
@@ -662,4 +639,112 @@ public class InitializrConfiguration {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Platform-specific settings.
|
||||
*/
|
||||
public static class Platform {
|
||||
|
||||
/**
|
||||
* Compatibility range of supported platform versions. Requesting metadata or
|
||||
* project generation with a platform version that does not match this range is
|
||||
* not supported.
|
||||
*/
|
||||
private String compatibilityRange;
|
||||
|
||||
@JsonIgnore
|
||||
private VersionRange range;
|
||||
|
||||
/**
|
||||
* Compatibility range of platform versions using the first version format.
|
||||
*/
|
||||
private String v1FormatCompatibilityRange;
|
||||
|
||||
@JsonIgnore
|
||||
private VersionRange v1FormatRange;
|
||||
|
||||
/**
|
||||
* Compatibility range of platform versions using the second version format.
|
||||
*/
|
||||
private String v2FormatCompatibilityRange;
|
||||
|
||||
@JsonIgnore
|
||||
private VersionRange v2FormatRange;
|
||||
|
||||
public void updateCompatibilityRange(VersionParser versionParser) {
|
||||
this.range = (this.compatibilityRange != null) ? versionParser.parseRange(this.compatibilityRange) : null;
|
||||
this.v1FormatRange = (this.v1FormatCompatibilityRange != null)
|
||||
? versionParser.parseRange(this.v1FormatCompatibilityRange) : null;
|
||||
this.v2FormatRange = (this.v2FormatCompatibilityRange != null)
|
||||
? versionParser.parseRange(this.v2FormatCompatibilityRange) : null;
|
||||
}
|
||||
|
||||
private void merge(Platform other) {
|
||||
this.compatibilityRange = other.compatibilityRange;
|
||||
this.range = other.range;
|
||||
this.v1FormatCompatibilityRange = other.v1FormatCompatibilityRange;
|
||||
this.v1FormatRange = other.v1FormatRange;
|
||||
this.v2FormatCompatibilityRange = other.v2FormatCompatibilityRange;
|
||||
this.v2FormatRange = other.v2FormatRange;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify whether the specified {@linkplain Version platform version} is
|
||||
* supported.
|
||||
* @param platformVersion the platform version to check
|
||||
* @return {@code true} if this version is supported, {@code false} otherwise
|
||||
*/
|
||||
public boolean isCompatibleVersion(Version platformVersion) {
|
||||
return (this.range == null || this.range.match(platformVersion));
|
||||
}
|
||||
|
||||
public String determineCompatibilityRangeRequirement() {
|
||||
return this.range.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Format the expected {@link Version platform version}.
|
||||
* @param platformVersion a platform version
|
||||
* @return a platform version in the suitable format
|
||||
*/
|
||||
public Version formatPlatformVersion(Version platformVersion) {
|
||||
Format format = getExpectedVersionFormat(platformVersion);
|
||||
return platformVersion.format(format);
|
||||
}
|
||||
|
||||
private Format getExpectedVersionFormat(Version version) {
|
||||
if (this.v2FormatRange != null && this.v2FormatRange.match(version)) {
|
||||
return Format.V2;
|
||||
}
|
||||
if (this.v1FormatRange != null && this.v1FormatRange.match(version)) {
|
||||
return Format.V1;
|
||||
}
|
||||
return version.getFormat();
|
||||
}
|
||||
|
||||
public String getCompatibilityRange() {
|
||||
return this.compatibilityRange;
|
||||
}
|
||||
|
||||
public void setCompatibilityRange(String compatibilityRange) {
|
||||
this.compatibilityRange = compatibilityRange;
|
||||
}
|
||||
|
||||
public String getV1FormatCompatibilityRange() {
|
||||
return this.v1FormatCompatibilityRange;
|
||||
}
|
||||
|
||||
public void setV1FormatCompatibilityRange(String v1FormatCompatibilityRange) {
|
||||
this.v1FormatCompatibilityRange = v1FormatCompatibilityRange;
|
||||
}
|
||||
|
||||
public String getV2FormatCompatibilityRange() {
|
||||
return this.v2FormatCompatibilityRange;
|
||||
}
|
||||
|
||||
public void setV2FormatCompatibilityRange(String v2FormatCompatibilityRange) {
|
||||
this.v2FormatCompatibilityRange = v2FormatCompatibilityRange;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -38,9 +38,11 @@ import io.spring.initializr.web.controller.DefaultProjectGenerationController;
|
||||
import io.spring.initializr.web.controller.ProjectGenerationController;
|
||||
import io.spring.initializr.web.controller.ProjectMetadataController;
|
||||
import io.spring.initializr.web.controller.SpringCliDistributionController;
|
||||
import io.spring.initializr.web.project.DefaultProjectRequestPlatformVersionTransformer;
|
||||
import io.spring.initializr.web.project.DefaultProjectRequestToDescriptionConverter;
|
||||
import io.spring.initializr.web.project.ProjectGenerationInvoker;
|
||||
import io.spring.initializr.web.project.ProjectRequest;
|
||||
import io.spring.initializr.web.project.ProjectRequestPlatformVersionTransformer;
|
||||
import io.spring.initializr.web.support.DefaultDependencyMetadataProvider;
|
||||
import io.spring.initializr.web.support.DefaultInitializrMetadataProvider;
|
||||
import io.spring.initializr.web.support.DefaultInitializrMetadataUpdateStrategy;
|
||||
@@ -144,9 +146,12 @@ public class InitializrAutoConfiguration {
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
ProjectGenerationController<ProjectRequest> projectGenerationController(
|
||||
InitializrMetadataProvider metadataProvider, ApplicationContext applicationContext) {
|
||||
InitializrMetadataProvider metadataProvider,
|
||||
ObjectProvider<ProjectRequestPlatformVersionTransformer> platformVersionTransformer,
|
||||
ApplicationContext applicationContext) {
|
||||
ProjectGenerationInvoker<ProjectRequest> projectGenerationInvoker = new ProjectGenerationInvoker<>(
|
||||
applicationContext, new DefaultProjectRequestToDescriptionConverter());
|
||||
applicationContext, new DefaultProjectRequestToDescriptionConverter(platformVersionTransformer
|
||||
.getIfAvailable(DefaultProjectRequestPlatformVersionTransformer::new)));
|
||||
return new DefaultProjectGenerationController(metadataProvider, projectGenerationInvoker);
|
||||
}
|
||||
|
||||
|
||||
@@ -24,13 +24,14 @@ import javax.servlet.http.HttpServletResponse;
|
||||
import io.spring.initializr.generator.version.Version;
|
||||
import io.spring.initializr.metadata.DependencyMetadata;
|
||||
import io.spring.initializr.metadata.DependencyMetadataProvider;
|
||||
import io.spring.initializr.metadata.InitializrConfiguration.Env;
|
||||
import io.spring.initializr.metadata.InitializrConfiguration.Platform;
|
||||
import io.spring.initializr.metadata.InitializrMetadata;
|
||||
import io.spring.initializr.metadata.InitializrMetadataProvider;
|
||||
import io.spring.initializr.metadata.InvalidInitializrMetadataException;
|
||||
import io.spring.initializr.web.mapper.DependencyMetadataV21JsonMapper;
|
||||
import io.spring.initializr.web.mapper.InitializrMetadataJsonMapper;
|
||||
import io.spring.initializr.web.mapper.InitializrMetadataV21JsonMapper;
|
||||
import io.spring.initializr.web.mapper.InitializrMetadataV22JsonMapper;
|
||||
import io.spring.initializr.web.mapper.InitializrMetadataV2JsonMapper;
|
||||
import io.spring.initializr.web.mapper.InitializrMetadataVersion;
|
||||
import io.spring.initializr.web.project.InvalidProjectRequestException;
|
||||
@@ -77,6 +78,11 @@ public class ProjectMetadataController extends AbstractMetadataController {
|
||||
return serviceCapabilitiesFor(InitializrMetadataVersion.V2_1, HAL_JSON_CONTENT_TYPE);
|
||||
}
|
||||
|
||||
@RequestMapping(path = { "/", "/metadata/client" }, produces = { "application/vnd.initializr.v2.2+json" })
|
||||
public ResponseEntity<String> serviceCapabilitiesV22() {
|
||||
return serviceCapabilitiesFor(InitializrMetadataVersion.V2_2);
|
||||
}
|
||||
|
||||
@RequestMapping(path = { "/", "/metadata/client" },
|
||||
produces = { "application/vnd.initializr.v2.1+json", "application/json" })
|
||||
public ResponseEntity<String> serviceCapabilitiesV21() {
|
||||
@@ -120,10 +126,10 @@ public class ProjectMetadataController extends AbstractMetadataController {
|
||||
InitializrMetadata metadata = this.metadataProvider.get();
|
||||
Version v = (bootVersion != null) ? Version.parse(bootVersion)
|
||||
: Version.parse(metadata.getBootVersions().getDefault().getId());
|
||||
Env env = metadata.getConfiguration().getEnv();
|
||||
if (!env.isCompatiblePlatformVersion(v)) {
|
||||
Platform platform = metadata.getConfiguration().getEnv().getPlatform();
|
||||
if (!platform.isCompatibleVersion(v)) {
|
||||
throw new InvalidProjectRequestException("Invalid Spring Boot version '" + bootVersion
|
||||
+ "', Spring Boot compatibility range is " + env.determinePlatformCompatibilityRangeRequirement());
|
||||
+ "', Spring Boot compatibility range is " + platform.determineCompatibilityRangeRequirement());
|
||||
}
|
||||
DependencyMetadata dependencyMetadata = this.dependencyMetadataProvider.get(metadata, v);
|
||||
String content = new DependencyMetadataV21JsonMapper().write(dependencyMetadata);
|
||||
@@ -147,8 +153,10 @@ public class ProjectMetadataController extends AbstractMetadataController {
|
||||
switch (version) {
|
||||
case V2:
|
||||
return new InitializrMetadataV2JsonMapper();
|
||||
default:
|
||||
case V2_1:
|
||||
return new InitializrMetadataV21JsonMapper();
|
||||
default:
|
||||
return new InitializrMetadataV22JsonMapper();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2020 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.
|
||||
@@ -19,6 +19,8 @@ package io.spring.initializr.web.mapper;
|
||||
import java.util.List;
|
||||
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import io.spring.initializr.generator.version.Version.Format;
|
||||
import io.spring.initializr.generator.version.VersionRange;
|
||||
import io.spring.initializr.metadata.Dependency;
|
||||
import io.spring.initializr.metadata.Type;
|
||||
|
||||
@@ -55,8 +57,8 @@ public class InitializrMetadataV21JsonMapper extends InitializrMetadataV2JsonMap
|
||||
@Override
|
||||
protected ObjectNode mapDependency(Dependency dependency) {
|
||||
ObjectNode content = mapValue(dependency);
|
||||
if (dependency.getCompatibilityRange() != null) {
|
||||
content.put("versionRange", dependency.getCompatibilityRange());
|
||||
if (dependency.getRange() != null) {
|
||||
content.put("versionRange", formatVersionRange(dependency.getRange()));
|
||||
}
|
||||
if (dependency.getLinks() != null && !dependency.getLinks().isEmpty()) {
|
||||
content.set("_links", LinkMapper.mapLinks(dependency.getLinks()));
|
||||
@@ -64,6 +66,10 @@ public class InitializrMetadataV21JsonMapper extends InitializrMetadataV2JsonMap
|
||||
return content;
|
||||
}
|
||||
|
||||
protected String formatVersionRange(VersionRange versionRange) {
|
||||
return versionRange.format(Format.V1).toRangeString();
|
||||
}
|
||||
|
||||
private ObjectNode dependenciesLink(String appUrl) {
|
||||
String uri = (appUrl != null) ? appUrl + "/dependencies" : "/dependencies";
|
||||
UriTemplate uriTemplate = UriTemplate.of(uri, this.dependenciesVariables);
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2012-2020 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
|
||||
*
|
||||
* https://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.mapper;
|
||||
|
||||
import io.spring.initializr.generator.version.Version;
|
||||
import io.spring.initializr.generator.version.VersionRange;
|
||||
|
||||
/**
|
||||
* A {@link InitializrMetadataJsonMapper} handling the metadata format for v2.2
|
||||
* <p>
|
||||
* Version 2.2 adds support for {@linkplain Version.Format#V2 SemVer version format}. Any
|
||||
* previous version formats versions to {@link Version.Format#V1}.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
public class InitializrMetadataV22JsonMapper extends InitializrMetadataV21JsonMapper {
|
||||
|
||||
@Override
|
||||
protected String formatVersion(String versionId) {
|
||||
return versionId;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String formatVersionRange(VersionRange versionRange) {
|
||||
return versionRange.toRangeString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2020 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.
|
||||
@@ -17,12 +17,16 @@
|
||||
package io.spring.initializr.web.mapper;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.node.ArrayNode;
|
||||
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import io.spring.initializr.generator.version.Version;
|
||||
import io.spring.initializr.generator.version.Version.Format;
|
||||
import io.spring.initializr.generator.version.VersionParser;
|
||||
import io.spring.initializr.metadata.DefaultMetadataElement;
|
||||
import io.spring.initializr.metadata.DependenciesCapability;
|
||||
import io.spring.initializr.metadata.Dependency;
|
||||
@@ -79,7 +83,7 @@ public class InitializrMetadataV2JsonMapper implements InitializrMetadataJsonMap
|
||||
singleSelect(delegate, metadata.getPackagings());
|
||||
singleSelect(delegate, metadata.getJavaVersions());
|
||||
singleSelect(delegate, metadata.getLanguages());
|
||||
singleSelect(delegate, metadata.getBootVersions());
|
||||
singleSelect(delegate, metadata.getBootVersions(), this::mapVersionMetadata);
|
||||
text(delegate, metadata.getGroupId());
|
||||
text(delegate, metadata.getArtifactId());
|
||||
text(delegate, metadata.getVersion());
|
||||
@@ -133,6 +137,11 @@ public class InitializrMetadataV2JsonMapper implements InitializrMetadataJsonMap
|
||||
}
|
||||
|
||||
protected void singleSelect(ObjectNode parent, SingleSelectCapability capability) {
|
||||
singleSelect(parent, capability, this::mapValue);
|
||||
}
|
||||
|
||||
protected void singleSelect(ObjectNode parent, SingleSelectCapability capability,
|
||||
Function<MetadataElement, ObjectNode> valueMapper) {
|
||||
ObjectNode single = nodeFactory.objectNode();
|
||||
single.put("type", capability.getType().getName());
|
||||
DefaultMetadataElement defaultType = capability.getDefault();
|
||||
@@ -140,7 +149,7 @@ public class InitializrMetadataV2JsonMapper implements InitializrMetadataJsonMap
|
||||
single.put("default", defaultType.getId());
|
||||
}
|
||||
ArrayNode values = nodeFactory.arrayNode();
|
||||
values.addAll(capability.getContent().stream().map(this::mapValue).collect(Collectors.toList()));
|
||||
values.addAll(capability.getContent().stream().map(valueMapper).collect(Collectors.toList()));
|
||||
single.set("values", values);
|
||||
parent.set(capability.getId(), single);
|
||||
}
|
||||
@@ -189,6 +198,18 @@ public class InitializrMetadataV2JsonMapper implements InitializrMetadataJsonMap
|
||||
return result;
|
||||
}
|
||||
|
||||
private ObjectNode mapVersionMetadata(MetadataElement value) {
|
||||
ObjectNode result = nodeFactory.objectNode();
|
||||
result.put("id", formatVersion(value.getId()));
|
||||
result.put("name", value.getName());
|
||||
return result;
|
||||
}
|
||||
|
||||
protected String formatVersion(String versionId) {
|
||||
Version version = VersionParser.DEFAULT.safeParse(versionId);
|
||||
return (version != null) ? version.format(Format.V1).toString() : versionId;
|
||||
}
|
||||
|
||||
protected ObjectNode mapValue(MetadataElement value) {
|
||||
ObjectNode result = nodeFactory.objectNode();
|
||||
result.put("id", value.getId());
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2020 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.
|
||||
@@ -35,7 +35,12 @@ public enum InitializrMetadataVersion {
|
||||
* versions are compatible with it. Also provide a separate "dependencies" endpoint to
|
||||
* query dependencies metadata.
|
||||
*/
|
||||
V2_1("application/vnd.initializr.v2.1+json");
|
||||
V2_1("application/vnd.initializr.v2.1+json"),
|
||||
|
||||
/**
|
||||
* Add support for SemVer compliant version format.
|
||||
*/
|
||||
V2_2("application/vnd.initializr.v2.2+json");
|
||||
|
||||
private final MediaType mediaType;
|
||||
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2012-2020 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
|
||||
*
|
||||
* https://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.project;
|
||||
|
||||
import io.spring.initializr.generator.version.Version;
|
||||
import io.spring.initializr.metadata.InitializrMetadata;
|
||||
|
||||
/**
|
||||
* A default {@link DefaultProjectRequestPlatformVersionTransformer} that uses configured
|
||||
* ranges to format the version if necessary.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
public class DefaultProjectRequestPlatformVersionTransformer implements ProjectRequestPlatformVersionTransformer {
|
||||
|
||||
@Override
|
||||
public Version transform(Version platformVersion, InitializrMetadata metadata) {
|
||||
return metadata.getConfiguration().getEnv().getPlatform().formatPlatformVersion(platformVersion);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -27,22 +27,38 @@ import io.spring.initializr.generator.project.ProjectDescription;
|
||||
import io.spring.initializr.generator.version.Version;
|
||||
import io.spring.initializr.metadata.DefaultMetadataElement;
|
||||
import io.spring.initializr.metadata.Dependency;
|
||||
import io.spring.initializr.metadata.InitializrConfiguration.Env;
|
||||
import io.spring.initializr.metadata.InitializrConfiguration.Platform;
|
||||
import io.spring.initializr.metadata.InitializrMetadata;
|
||||
import io.spring.initializr.metadata.Type;
|
||||
import io.spring.initializr.metadata.support.MetadataBuildItemMapper;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* A default {@link ProjectRequestToDescriptionConverter} implementation that uses the
|
||||
* {@link InitializrMetadata metadata} to set default values for missing attributes if
|
||||
* necessary.
|
||||
* necessary. Transparently transform the platform version if necessary using a
|
||||
* {@link ProjectRequestPlatformVersionTransformer}.
|
||||
*
|
||||
* @author Madhura Bhave
|
||||
* @author HaiTao Zhang
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
public class DefaultProjectRequestToDescriptionConverter
|
||||
implements ProjectRequestToDescriptionConverter<ProjectRequest> {
|
||||
|
||||
private final ProjectRequestPlatformVersionTransformer platformVersionTransformer;
|
||||
|
||||
public DefaultProjectRequestToDescriptionConverter() {
|
||||
this((version, metadata) -> version);
|
||||
}
|
||||
|
||||
public DefaultProjectRequestToDescriptionConverter(
|
||||
ProjectRequestPlatformVersionTransformer platformVersionTransformer) {
|
||||
Assert.notNull(platformVersionTransformer, "PlatformVersionTransformer must not be null");
|
||||
this.platformVersionTransformer = platformVersionTransformer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProjectDescription convert(ProjectRequest request, InitializrMetadata metadata) {
|
||||
MutableProjectDescription description = new MutableProjectDescription();
|
||||
@@ -60,9 +76,9 @@ public class DefaultProjectRequestToDescriptionConverter
|
||||
*/
|
||||
public void convert(ProjectRequest request, MutableProjectDescription description, InitializrMetadata metadata) {
|
||||
validate(request, metadata);
|
||||
String springBootVersion = getSpringBootVersion(request, metadata);
|
||||
List<Dependency> resolvedDependencies = getResolvedDependencies(request, springBootVersion, metadata);
|
||||
validateDependencyRange(springBootVersion, resolvedDependencies);
|
||||
Version platformVersion = getPlatformVersion(request, metadata);
|
||||
List<Dependency> resolvedDependencies = getResolvedDependencies(request, platformVersion, metadata);
|
||||
validateDependencyRange(platformVersion, resolvedDependencies);
|
||||
|
||||
description.setApplicationName(request.getApplicationName());
|
||||
description.setArtifactId(request.getArtifactId());
|
||||
@@ -74,26 +90,26 @@ public class DefaultProjectRequestToDescriptionConverter
|
||||
description.setName(request.getName());
|
||||
description.setPackageName(request.getPackageName());
|
||||
description.setPackaging(Packaging.forId(request.getPackaging()));
|
||||
description.setPlatformVersion(Version.parse(springBootVersion));
|
||||
description.setPlatformVersion(platformVersion);
|
||||
description.setVersion(request.getVersion());
|
||||
resolvedDependencies.forEach((dependency) -> description.addDependency(dependency.getId(),
|
||||
MetadataBuildItemMapper.toDependency(dependency)));
|
||||
}
|
||||
|
||||
private void validate(ProjectRequest request, InitializrMetadata metadata) {
|
||||
validateSpringBootVersion(request, metadata);
|
||||
validatePlatformVersion(request, metadata);
|
||||
validateType(request.getType(), metadata);
|
||||
validateLanguage(request.getLanguage(), metadata);
|
||||
validatePackaging(request.getPackaging(), metadata);
|
||||
validateDependencies(request, metadata);
|
||||
}
|
||||
|
||||
private void validateSpringBootVersion(ProjectRequest request, InitializrMetadata metadata) {
|
||||
Version bootVersion = Version.safeParse(request.getBootVersion());
|
||||
Env env = metadata.getConfiguration().getEnv();
|
||||
if (bootVersion != null && !env.isCompatiblePlatformVersion(bootVersion)) {
|
||||
throw new InvalidProjectRequestException("Invalid Spring Boot version '" + bootVersion
|
||||
+ "', Spring Boot compatibility range is " + env.determinePlatformCompatibilityRangeRequirement());
|
||||
private void validatePlatformVersion(ProjectRequest request, InitializrMetadata metadata) {
|
||||
Version platformVersion = Version.safeParse(request.getBootVersion());
|
||||
Platform platform = metadata.getConfiguration().getEnv().getPlatform();
|
||||
if (platformVersion != null && !platform.isCompatibleVersion(platformVersion)) {
|
||||
throw new InvalidProjectRequestException("Invalid Spring Boot version '" + platformVersion
|
||||
+ "', Spring Boot compatibility range is " + platform.determineCompatibilityRangeRequirement());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,11 +155,11 @@ public class DefaultProjectRequestToDescriptionConverter
|
||||
});
|
||||
}
|
||||
|
||||
private void validateDependencyRange(String springBootVersion, List<Dependency> resolvedDependencies) {
|
||||
private void validateDependencyRange(Version platformVersion, List<Dependency> resolvedDependencies) {
|
||||
resolvedDependencies.forEach((dep) -> {
|
||||
if (!dep.match(Version.parse(springBootVersion))) {
|
||||
throw new InvalidProjectRequestException("Dependency '" + dep.getId() + "' is not compatible "
|
||||
+ "with Spring Boot " + springBootVersion);
|
||||
if (!dep.match(platformVersion)) {
|
||||
throw new InvalidProjectRequestException(
|
||||
"Dependency '" + dep.getId() + "' is not compatible " + "with Spring Boot " + platformVersion);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -153,18 +169,19 @@ public class DefaultProjectRequestToDescriptionConverter
|
||||
return BuildSystem.forId(typeFromMetadata.getTags().get("build"));
|
||||
}
|
||||
|
||||
private String getSpringBootVersion(ProjectRequest request, InitializrMetadata metadata) {
|
||||
return (request.getBootVersion() != null) ? request.getBootVersion()
|
||||
private Version getPlatformVersion(ProjectRequest request, InitializrMetadata metadata) {
|
||||
String versionText = (request.getBootVersion() != null) ? request.getBootVersion()
|
||||
: metadata.getBootVersions().getDefault().getId();
|
||||
Version version = Version.parse(versionText);
|
||||
return this.platformVersionTransformer.transform(version, metadata);
|
||||
}
|
||||
|
||||
private List<Dependency> getResolvedDependencies(ProjectRequest request, String springBootVersion,
|
||||
private List<Dependency> getResolvedDependencies(ProjectRequest request, Version platformVersion,
|
||||
InitializrMetadata metadata) {
|
||||
List<String> depIds = request.getDependencies();
|
||||
Version requestedVersion = Version.parse(springBootVersion);
|
||||
return depIds.stream().map((it) -> {
|
||||
Dependency dependency = metadata.getDependencies().get(it);
|
||||
return dependency.resolve(requestedVersion);
|
||||
return dependency.resolve(platformVersion);
|
||||
}).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2012-2020 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
|
||||
*
|
||||
* https://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.project;
|
||||
|
||||
import io.spring.initializr.generator.version.Version;
|
||||
import io.spring.initializr.metadata.InitializrMetadata;
|
||||
|
||||
/**
|
||||
* Strategy interface to transform the platform version of a {@link ProjectRequest}.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface ProjectRequestPlatformVersionTransformer {
|
||||
|
||||
/**
|
||||
* Transform the platform version of a {@link ProjectRequest} if necessary.
|
||||
* @param platformVersion the candidate platform version
|
||||
* @param metadata the metadata instance to use
|
||||
* @return the platform version to use
|
||||
*/
|
||||
Version transform(Version platformVersion, InitializrMetadata metadata);
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2020 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.
|
||||
@@ -72,7 +72,9 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
@SpringBootTest(classes = Config.class)
|
||||
public abstract class AbstractInitializrIntegrationTests {
|
||||
|
||||
protected static final MediaType CURRENT_METADATA_MEDIA_TYPE = InitializrMetadataVersion.V2_1.getMediaType();
|
||||
protected static final MediaType DEFAULT_METADATA_MEDIA_TYPE = InitializrMetadataVersion.V2_1.getMediaType();
|
||||
|
||||
protected static final MediaType CURRENT_METADATA_MEDIA_TYPE = InitializrMetadataVersion.V2_2.getMediaType();
|
||||
|
||||
private static final ObjectMapper objectMapper = new ObjectMapper();
|
||||
|
||||
@@ -125,14 +127,23 @@ public abstract class AbstractInitializrIntegrationTests {
|
||||
}
|
||||
}
|
||||
|
||||
protected void validateCurrentMetadata(ResponseEntity<String> response) {
|
||||
validateContentType(response, CURRENT_METADATA_MEDIA_TYPE);
|
||||
validateCurrentMetadata(response.getBody());
|
||||
protected void validateDefaultMetadata(ResponseEntity<String> response) {
|
||||
validateContentType(response, DEFAULT_METADATA_MEDIA_TYPE);
|
||||
validateMetadata(response.getBody(), "2.1.0");
|
||||
}
|
||||
|
||||
protected void validateCurrentMetadata(String json) {
|
||||
protected void validateCurrentMetadata(ResponseEntity<String> response) {
|
||||
validateContentType(response, CURRENT_METADATA_MEDIA_TYPE);
|
||||
validateMetadata(response.getBody(), "2.2.0");
|
||||
}
|
||||
|
||||
protected void validateDefaultMetadata(String json) {
|
||||
validateMetadata(json, "2.1.0");
|
||||
}
|
||||
|
||||
protected void validateMetadata(String json, String version) {
|
||||
try {
|
||||
JSONObject expected = readMetadataJson("2.1.0");
|
||||
JSONObject expected = readMetadataJson(version);
|
||||
JSONAssert.assertEquals(expected, new JSONObject(json), JSONCompareMode.STRICT);
|
||||
}
|
||||
catch (JSONException ex) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2020 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.
|
||||
@@ -45,8 +45,8 @@ public class CommandLineMetadataControllerIntegrationTests extends AbstractIniti
|
||||
// make sure curl can still receive metadata with json
|
||||
void curlWithAcceptHeaderJson() {
|
||||
ResponseEntity<String> response = invokeHome("curl/1.2.4", "application/json");
|
||||
validateContentType(response, AbstractInitializrIntegrationTests.CURRENT_METADATA_MEDIA_TYPE);
|
||||
validateCurrentMetadata(response.getBody());
|
||||
validateContentType(response, AbstractInitializrIntegrationTests.DEFAULT_METADATA_MEDIA_TYPE);
|
||||
validateDefaultMetadata(response.getBody());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -65,8 +65,8 @@ public class CommandLineMetadataControllerIntegrationTests extends AbstractIniti
|
||||
// make sure curl can still receive metadata with json
|
||||
void httpieWithAcceptHeaderJson() {
|
||||
ResponseEntity<String> response = invokeHome("HTTPie/0.8.0", "application/json");
|
||||
validateContentType(response, AbstractInitializrIntegrationTests.CURRENT_METADATA_MEDIA_TYPE);
|
||||
validateCurrentMetadata(response.getBody());
|
||||
validateContentType(response, AbstractInitializrIntegrationTests.DEFAULT_METADATA_MEDIA_TYPE);
|
||||
validateDefaultMetadata(response.getBody());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -84,8 +84,8 @@ public class CommandLineMetadataControllerIntegrationTests extends AbstractIniti
|
||||
@Test
|
||||
void springBootCliReceivesJsonByDefault() {
|
||||
ResponseEntity<String> response = invokeHome("SpringBootCli/1.2.0", "*/*");
|
||||
validateContentType(response, AbstractInitializrIntegrationTests.CURRENT_METADATA_MEDIA_TYPE);
|
||||
validateCurrentMetadata(response.getBody());
|
||||
validateContentType(response, AbstractInitializrIntegrationTests.DEFAULT_METADATA_MEDIA_TYPE);
|
||||
validateDefaultMetadata(response.getBody());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2020 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.
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2012-2020 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
|
||||
*
|
||||
* https://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.controller;
|
||||
|
||||
import io.spring.initializr.generator.test.project.ProjectStructure;
|
||||
import io.spring.initializr.web.AbstractInitializrControllerIntegrationTests;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link ProjectGenerationController} with a custom platform
|
||||
* version compatibility range.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
@ActiveProfiles("test-default")
|
||||
@TestPropertySource(properties = "initializr.env.platform.v2-format-compatibility-range=2.4.0-M1")
|
||||
class ProjectGenerationControllerCustomVersionTransformerIntegrationTests
|
||||
extends AbstractInitializrControllerIntegrationTests {
|
||||
|
||||
@Test
|
||||
void projectGenerationInvokeProjectRequestVersionTransformer() {
|
||||
ProjectStructure project = downloadZip("/starter.zip?bootVersion=2.4.0.RELEASE");
|
||||
assertThat(project).mavenBuild().hasParent("org.springframework.boot", "spring-boot-starter-parent", "2.4.0");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2020 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.
|
||||
@@ -84,24 +84,24 @@ class ProjectMetadataControllerCustomDefaultsIntegrationTests extends AbstractFu
|
||||
@Test
|
||||
void metadataClientEndpoint() {
|
||||
ResponseEntity<String> response = execute("/metadata/client", String.class, null, "application/json");
|
||||
validateCurrentMetadata(response);
|
||||
validateDefaultMetadata(response);
|
||||
}
|
||||
|
||||
@Test
|
||||
void noBootVersion() throws JSONException {
|
||||
ResponseEntity<String> response = execute("/dependencies", String.class, null, "application/json");
|
||||
assertThat(response.getHeaders().getFirst(HttpHeaders.ETAG)).isNotNull();
|
||||
validateContentType(response, CURRENT_METADATA_MEDIA_TYPE);
|
||||
validateContentType(response, DEFAULT_METADATA_MEDIA_TYPE);
|
||||
validateDependenciesOutput("2.1.4", response.getBody());
|
||||
}
|
||||
|
||||
@Test
|
||||
void filteredDependencies() throws JSONException {
|
||||
ResponseEntity<String> response = execute("/dependencies?bootVersion=2.2.1.RELEASE", String.class, null,
|
||||
ResponseEntity<String> response = execute("/dependencies?bootVersion=2.4.1.RELEASE", String.class, null,
|
||||
"application/json");
|
||||
assertThat(response.getHeaders().getFirst(HttpHeaders.ETAG)).isNotNull();
|
||||
validateContentType(response, CURRENT_METADATA_MEDIA_TYPE);
|
||||
validateDependenciesOutput("2.2.1", response.getBody());
|
||||
validateContentType(response, DEFAULT_METADATA_MEDIA_TYPE);
|
||||
validateDependenciesOutput("2.4.1", response.getBody());
|
||||
}
|
||||
|
||||
protected void validateDependenciesOutput(String version, String actual) throws JSONException {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2020 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.
|
||||
@@ -43,7 +43,7 @@ public class ProjectMetadataControllerIntegrationTests extends AbstractInitializ
|
||||
void metadataWithNoAcceptHeader() {
|
||||
// rest template sets application/json by default
|
||||
ResponseEntity<String> response = invokeHome(null, "*/*");
|
||||
validateCurrentMetadata(response);
|
||||
validateDefaultMetadata(response);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -60,6 +60,18 @@ public class ProjectMetadataControllerIntegrationTests extends AbstractInitializ
|
||||
validateMetadata(response, InitializrMetadataVersion.V2.getMediaType(), "2.0.0", JSONCompareMode.STRICT);
|
||||
}
|
||||
|
||||
@Test
|
||||
void metadataWithV21AcceptHeader() {
|
||||
ResponseEntity<String> response = invokeHome(null, "application/vnd.initializr.v2.1+json");
|
||||
validateMetadata(response, InitializrMetadataVersion.V2_1.getMediaType(), "2.1.0", JSONCompareMode.STRICT);
|
||||
}
|
||||
|
||||
@Test
|
||||
void metadataWithV22AcceptHeader() {
|
||||
ResponseEntity<String> response = invokeHome(null, "application/vnd.initializr.v2.2+json");
|
||||
validateMetadata(response, InitializrMetadataVersion.V2_2.getMediaType(), "2.2.0", JSONCompareMode.STRICT);
|
||||
}
|
||||
|
||||
@Test
|
||||
void metadataWithInvalidPlatformVersion() {
|
||||
try {
|
||||
@@ -76,18 +88,18 @@ public class ProjectMetadataControllerIntegrationTests extends AbstractInitializ
|
||||
void metadataWithCurrentAcceptHeader() {
|
||||
getRequests().setFields("_links.maven-project", "dependencies.values[0]", "type.values[0]",
|
||||
"javaVersion.values[0]", "packaging.values[0]", "bootVersion.values[0]", "language.values[0]");
|
||||
ResponseEntity<String> response = invokeHome(null, "application/vnd.initializr.v2.1+json");
|
||||
ResponseEntity<String> response = invokeHome(null, "application/vnd.initializr.v2.2+json");
|
||||
assertThat(response.getHeaders().getFirst(HttpHeaders.ETAG)).isNotNull();
|
||||
validateContentType(response, AbstractInitializrIntegrationTests.CURRENT_METADATA_MEDIA_TYPE);
|
||||
validateCurrentMetadata(response.getBody());
|
||||
validateMetadata(response.getBody(), "2.2.0");
|
||||
}
|
||||
|
||||
@Test
|
||||
void metadataWithSeveralAcceptHeader() {
|
||||
ResponseEntity<String> response = invokeHome(null, "application/vnd.initializr.v2.1+json",
|
||||
ResponseEntity<String> response = invokeHome(null, "application/vnd.initializr.v2.2+json",
|
||||
"application/vnd.initializr.v2+json");
|
||||
validateContentType(response, AbstractInitializrIntegrationTests.CURRENT_METADATA_MEDIA_TYPE);
|
||||
validateCurrentMetadata(response.getBody());
|
||||
validateCurrentMetadata(response);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -95,7 +107,7 @@ public class ProjectMetadataControllerIntegrationTests extends AbstractInitializ
|
||||
ResponseEntity<String> response = invokeHome(null, "application/hal+json");
|
||||
assertThat(response.getHeaders().getFirst(HttpHeaders.ETAG)).isNotNull();
|
||||
validateContentType(response, ProjectMetadataController.HAL_JSON_CONTENT_TYPE);
|
||||
validateCurrentMetadata(response.getBody());
|
||||
validateDefaultMetadata(response.getBody());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -117,13 +129,13 @@ public class ProjectMetadataControllerIntegrationTests extends AbstractInitializ
|
||||
@Test
|
||||
void unknownAgentReceivesJsonByDefault() {
|
||||
ResponseEntity<String> response = invokeHome("foo/1.0", "*/*");
|
||||
validateCurrentMetadata(response);
|
||||
validateDefaultMetadata(response);
|
||||
}
|
||||
|
||||
@Test
|
||||
// Test that the current output is exactly what we expect
|
||||
void validateCurrentProjectMetadata() {
|
||||
validateCurrentMetadata(getMetadataJson());
|
||||
validateDefaultMetadata(getMetadataJson());
|
||||
}
|
||||
|
||||
private String getMetadataJson() {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2020 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.
|
||||
@@ -18,8 +18,10 @@ package io.spring.initializr.web.mapper;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import io.spring.initializr.generator.test.InitializrMetadataTestBuilder;
|
||||
import io.spring.initializr.metadata.Dependency;
|
||||
import io.spring.initializr.metadata.InitializrMetadata;
|
||||
@@ -29,13 +31,15 @@ import org.junit.jupiter.api.Test;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link InitializrMetadataV21JsonMapper}.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
class InitializrMetadataJsonMapperTests {
|
||||
class InitializrMetadataV21JsonMapperTests {
|
||||
|
||||
private static final ObjectMapper objectMapper = new ObjectMapper();
|
||||
|
||||
private final InitializrMetadataJsonMapper jsonMapper = new InitializrMetadataV21JsonMapper();
|
||||
private final InitializrMetadataV21JsonMapper jsonMapper = new InitializrMetadataV21JsonMapper();
|
||||
|
||||
@Test
|
||||
void withNoAppUrl() throws IOException {
|
||||
@@ -74,6 +78,42 @@ class InitializrMetadataJsonMapperTests {
|
||||
assertThat(second).isGreaterThan(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void versionRangesUsingSemVerUseBackwardCompatibleFormat() {
|
||||
Dependency dependency = Dependency.withId("test");
|
||||
dependency.setCompatibilityRange("[1.1.1-RC1,1.2.0-M1)");
|
||||
dependency.resolve();
|
||||
ObjectNode node = this.jsonMapper.mapDependency(dependency);
|
||||
assertThat(node.get("versionRange").textValue()).isEqualTo("[1.1.1.RC1,1.2.0.M1)");
|
||||
}
|
||||
|
||||
@Test
|
||||
void versionRangesUsingSemVerSnapshotReplacedByBackwardCompatibleSnapshotQualifier() {
|
||||
Dependency dependency = Dependency.withId("test");
|
||||
dependency.setCompatibilityRange("1.2.0-SNAPSHOT");
|
||||
dependency.resolve();
|
||||
ObjectNode node = this.jsonMapper.mapDependency(dependency);
|
||||
assertThat(node.get("versionRange").textValue()).isEqualTo("1.2.0.BUILD-SNAPSHOT");
|
||||
}
|
||||
|
||||
@Test
|
||||
void platformVersionUsingSemVerUseBackwardCompatibleFormat() throws JsonProcessingException {
|
||||
InitializrMetadata metadata = new InitializrMetadataTestBuilder().addBootVersion("2.5.0-SNAPSHOT", false)
|
||||
.addBootVersion("2.5.0-M2", false).addBootVersion("2.4.2", true).build();
|
||||
String json = this.jsonMapper.write(metadata, null);
|
||||
JsonNode result = objectMapper.readTree(json);
|
||||
JsonNode versions = result.get("bootVersion").get("values");
|
||||
assertThat(versions).hasSize(3);
|
||||
assertVersionMetadata(versions.get(0), "2.5.0.BUILD-SNAPSHOT", "2.5.0-SNAPSHOT");
|
||||
assertVersionMetadata(versions.get(1), "2.5.0.M2", "2.5.0-M2");
|
||||
assertVersionMetadata(versions.get(2), "2.4.2.RELEASE", "2.4.2");
|
||||
}
|
||||
|
||||
private void assertVersionMetadata(JsonNode node, String id, String name) {
|
||||
assertThat(node.get("id").textValue()).isEqualTo(id);
|
||||
assertThat(node.get("name").textValue()).isEqualTo(name);
|
||||
}
|
||||
|
||||
private Object get(JsonNode result, String path) {
|
||||
String[] nodes = path.split("\\.");
|
||||
for (int i = 0; i < nodes.length - 1; i++) {
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright 2012-2020 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
|
||||
*
|
||||
* https://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.mapper;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import io.spring.initializr.generator.test.InitializrMetadataTestBuilder;
|
||||
import io.spring.initializr.metadata.Dependency;
|
||||
import io.spring.initializr.metadata.InitializrMetadata;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link InitializrMetadataV22JsonMapper}.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
class InitializrMetadataV22JsonMapperTests {
|
||||
|
||||
private static final ObjectMapper objectMapper = new ObjectMapper();
|
||||
|
||||
private final InitializrMetadataV22JsonMapper jsonMapper = new InitializrMetadataV22JsonMapper();
|
||||
|
||||
@Test
|
||||
void versionRangesUsingSemVerIsNotChanged() {
|
||||
Dependency dependency = Dependency.withId("test");
|
||||
dependency.setCompatibilityRange("[1.1.1-RC1,1.2.0-M1)");
|
||||
dependency.resolve();
|
||||
ObjectNode node = this.jsonMapper.mapDependency(dependency);
|
||||
assertThat(node.get("versionRange").textValue()).isEqualTo("[1.1.1-RC1,1.2.0-M1)");
|
||||
}
|
||||
|
||||
@Test
|
||||
void versionRangesUsingSemVerSnapshotIsNotChanged() {
|
||||
Dependency dependency = Dependency.withId("test");
|
||||
dependency.setCompatibilityRange("1.2.0-SNAPSHOT");
|
||||
dependency.resolve();
|
||||
ObjectNode node = this.jsonMapper.mapDependency(dependency);
|
||||
assertThat(node.get("versionRange").textValue()).isEqualTo("1.2.0-SNAPSHOT");
|
||||
}
|
||||
|
||||
@Test
|
||||
void platformVersionUsingSemVerUIsNotChanged() throws JsonProcessingException {
|
||||
InitializrMetadata metadata = new InitializrMetadataTestBuilder().addBootVersion("2.5.0-SNAPSHOT", false)
|
||||
.addBootVersion("2.5.0-M2", false).addBootVersion("2.4.2", true).build();
|
||||
String json = this.jsonMapper.write(metadata, null);
|
||||
JsonNode result = objectMapper.readTree(json);
|
||||
JsonNode versions = result.get("bootVersion").get("values");
|
||||
assertThat(versions).hasSize(3);
|
||||
assertVersionMetadata(versions.get(0), "2.5.0-SNAPSHOT", "2.5.0-SNAPSHOT");
|
||||
assertVersionMetadata(versions.get(1), "2.5.0-M2", "2.5.0-M2");
|
||||
assertVersionMetadata(versions.get(2), "2.4.2", "2.4.2");
|
||||
}
|
||||
|
||||
private void assertVersionMetadata(JsonNode node, String id, String name) {
|
||||
assertThat(node.get("id").textValue()).isEqualTo(id);
|
||||
assertThat(node.get("name").textValue()).isEqualTo(name);
|
||||
}
|
||||
|
||||
private Object get(JsonNode result, String path) {
|
||||
String[] nodes = path.split("\\.");
|
||||
for (int i = 0; i < nodes.length - 1; i++) {
|
||||
String node = nodes[i];
|
||||
result = result.path(node);
|
||||
}
|
||||
return result.get(nodes[nodes.length - 1]).textValue();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright 2012-2020 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
|
||||
*
|
||||
* https://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.project;
|
||||
|
||||
import io.spring.initializr.generator.test.InitializrMetadataTestBuilder;
|
||||
import io.spring.initializr.generator.version.Version;
|
||||
import io.spring.initializr.metadata.InitializrMetadata;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link DefaultProjectRequestPlatformVersionTransformer}.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
class DefaultProjectRequestPlatformVersionTransformerTests {
|
||||
|
||||
private final DefaultProjectRequestPlatformVersionTransformer transformer = new DefaultProjectRequestPlatformVersionTransformer();
|
||||
|
||||
@Test
|
||||
void formatV1WhenV2IsExpected() {
|
||||
InitializrMetadata metadata = InitializrMetadataTestBuilder.withDefaults()
|
||||
.setPlatformVersionFormatCompatibilityRange("[2.0.0.RELEASE,2.4.0-M1)", "2.4.0-M1").build();
|
||||
assertThat(this.transformer.transform(Version.parse("2.4.0.RELEASE"), metadata)).hasToString("2.4.0");
|
||||
}
|
||||
|
||||
@Test
|
||||
void formatV1WhenV1IsExpected() {
|
||||
InitializrMetadata metadata = InitializrMetadataTestBuilder.withDefaults()
|
||||
.setPlatformVersionFormatCompatibilityRange("[2.0.0.RELEASE,2.4.0-M1)", "2.4.0-M1").build();
|
||||
Version version = Version.parse("2.2.0.RELEASE");
|
||||
assertThat(this.transformer.transform(version, metadata)).isSameAs(version);
|
||||
}
|
||||
|
||||
@Test
|
||||
void formatV2WhenV1IsExpected() {
|
||||
InitializrMetadata metadata = InitializrMetadataTestBuilder.withDefaults()
|
||||
.setPlatformVersionFormatCompatibilityRange("[2.0.0.RELEASE,2.4.0-M1)", "2.4.0-M1").build();
|
||||
assertThat(this.transformer.transform(Version.parse("2.3.0-SNAPSHOT"), metadata))
|
||||
.hasToString("2.3.0.BUILD-SNAPSHOT");
|
||||
}
|
||||
|
||||
@Test
|
||||
void formatV2WhenV2IsExpected() {
|
||||
InitializrMetadata metadata = InitializrMetadataTestBuilder.withDefaults()
|
||||
.setPlatformVersionFormatCompatibilityRange("[2.0.0.RELEASE,2.4.0-M1)", "2.4.0-M1").build();
|
||||
Version version = Version.parse("2.4.0");
|
||||
assertThat(this.transformer.transform(version, metadata)).isSameAs(version);
|
||||
}
|
||||
|
||||
@Test
|
||||
void formatV1WhenNoRangeIsConfigured() {
|
||||
InitializrMetadata metadata = InitializrMetadataTestBuilder.withDefaults().build();
|
||||
Version version = Version.parse("2.4.0.RELEASE");
|
||||
assertThat(this.transformer.transform(version, metadata)).isSameAs(version);
|
||||
}
|
||||
|
||||
@Test
|
||||
void formatV2WhenNoRangeIsConfigured() {
|
||||
InitializrMetadata metadata = InitializrMetadataTestBuilder.withDefaults().build();
|
||||
Version version = Version.parse("2.2.0-SNAPSHOT");
|
||||
assertThat(this.transformer.transform(version, metadata)).isSameAs(version);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2020 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.
|
||||
@@ -30,6 +30,9 @@ import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
/**
|
||||
* Tests for {@link DefaultProjectRequestToDescriptionConverter}.
|
||||
@@ -74,6 +77,19 @@ class DefaultProjectRequestToDescriptionConverterTests {
|
||||
.isEqualTo(Version.parse("1.5.9.RELEASE"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void convertShouldCallProjectRequestVersionTransformer() {
|
||||
ProjectRequestPlatformVersionTransformer transformer = mock(ProjectRequestPlatformVersionTransformer.class);
|
||||
Version v1Format = Version.parse("2.4.0.RELEASE");
|
||||
given(transformer.transform(v1Format, this.metadata)).willReturn(Version.parse("2.4.0"));
|
||||
ProjectRequest request = createProjectRequest();
|
||||
request.setBootVersion("2.4.0.RELEASE");
|
||||
ProjectDescription description = new DefaultProjectRequestToDescriptionConverter(transformer).convert(request,
|
||||
this.metadata);
|
||||
assertThat(description.getPlatformVersion()).hasToString("2.4.0");
|
||||
verify(transformer).transform(v1Format, this.metadata);
|
||||
}
|
||||
|
||||
@Test
|
||||
void convertWhenSpringBootVersionInvalidShouldThrowException() {
|
||||
this.metadata = InitializrMetadataTestBuilder.withDefaults()
|
||||
|
||||
@@ -5,6 +5,7 @@ initializr:
|
||||
fallbackApplicationName: FooBarApplication
|
||||
invalidApplicationNames:
|
||||
- InvalidApplication
|
||||
platform-compatibility-range: "2.0.0.RELEASE"
|
||||
kotlin:
|
||||
default-version: 1.0.0-beta-2423
|
||||
default-version: 1.0.0-beta-2423
|
||||
platform:
|
||||
compatibility-range: "2.0.0.RELEASE"
|
||||
|
||||
@@ -90,7 +90,7 @@ initializr:
|
||||
id: org.acme:bur
|
||||
version: 2.1.0
|
||||
scope: test
|
||||
compatibilityRange: "[2.1.4.RELEASE,2.2.0.BUILD-SNAPSHOT)"
|
||||
compatibilityRange: "[2.1.4.RELEASE,2.4.0-SNAPSHOT)"
|
||||
- name: My API
|
||||
id : my-api
|
||||
groupId: org.acme
|
||||
@@ -152,7 +152,7 @@ initializr:
|
||||
default: false
|
||||
bootVersions:
|
||||
- name : Latest SNAPSHOT
|
||||
id: 2.2.0.BUILD-SNAPSHOT
|
||||
id: 2.4.0-SNAPSHOT
|
||||
default: false
|
||||
- name: 2.1.4
|
||||
id: 2.1.4.RELEASE
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
"content": [
|
||||
{
|
||||
"default": false,
|
||||
"id": "2.2.0.BUILD-SNAPSHOT",
|
||||
"id": "2.4.0-SNAPSHOT",
|
||||
"name": "Latest SNAPSHOT"
|
||||
},
|
||||
{
|
||||
@@ -33,7 +33,6 @@
|
||||
"artifactRepository": "https://repo.spring.io/release/",
|
||||
"fallbackApplicationName": "Application",
|
||||
"forceSsl": false,
|
||||
"platformCompatibilityRange": null,
|
||||
"gradle": {
|
||||
"dependencyManagementPluginVersion": "1.0.0.RELEASE"
|
||||
},
|
||||
@@ -58,6 +57,11 @@
|
||||
"includeSpringBootBom": false
|
||||
}
|
||||
},
|
||||
"platform": {
|
||||
"compatibilityRange": null,
|
||||
"v1FormatCompatibilityRange": null,
|
||||
"v2FormatCompatibilityRange": null
|
||||
},
|
||||
"googleAnalyticsTrackingCode": null,
|
||||
"invalidApplicationNames": [
|
||||
"SpringApplication",
|
||||
@@ -230,7 +234,7 @@
|
||||
"name": "Bur",
|
||||
"scope": "test",
|
||||
"version": "2.1.0",
|
||||
"compatibilityRange": "[2.1.4.RELEASE,2.2.0.BUILD-SNAPSHOT)"
|
||||
"compatibilityRange": "[2.1.4.RELEASE,2.4.0-SNAPSHOT)"
|
||||
},
|
||||
{
|
||||
"starter": true,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"bootVersion": "2.2.1.RELEASE",
|
||||
"bootVersion": "2.4.1.RELEASE",
|
||||
"repositories": {
|
||||
"my-api-repo-2": {
|
||||
"name": "repo2",
|
||||
@@ -154,7 +154,7 @@
|
||||
"default": "2.1.4.RELEASE",
|
||||
"values": [
|
||||
{
|
||||
"id": "2.2.0.BUILD-SNAPSHOT",
|
||||
"id": "2.4.0.BUILD-SNAPSHOT",
|
||||
"name": "Latest SNAPSHOT"
|
||||
},
|
||||
{
|
||||
|
||||
@@ -154,7 +154,7 @@
|
||||
"default": "2.1.4.RELEASE",
|
||||
"values": [
|
||||
{
|
||||
"id": "2.2.0.BUILD-SNAPSHOT",
|
||||
"id": "2.4.0.BUILD-SNAPSHOT",
|
||||
"name": "Latest SNAPSHOT"
|
||||
},
|
||||
{
|
||||
|
||||
@@ -85,7 +85,7 @@
|
||||
{
|
||||
"id": "org.acme:bur",
|
||||
"name": "Bur",
|
||||
"versionRange": "[2.1.4.RELEASE,2.2.0.BUILD-SNAPSHOT)"
|
||||
"versionRange": "[2.1.4.RELEASE,2.4.0.BUILD-SNAPSHOT)"
|
||||
},
|
||||
{
|
||||
"id": "my-api",
|
||||
@@ -192,7 +192,7 @@
|
||||
"default": "2.1.4.RELEASE",
|
||||
"values": [
|
||||
{
|
||||
"id": "2.2.0.BUILD-SNAPSHOT",
|
||||
"id": "2.4.0.BUILD-SNAPSHOT",
|
||||
"name": "Latest SNAPSHOT"
|
||||
},
|
||||
{
|
||||
|
||||
@@ -85,7 +85,7 @@
|
||||
{
|
||||
"id": "org.acme:bur",
|
||||
"name": "Bur",
|
||||
"versionRange": "[2.1.4.RELEASE,2.2.0.BUILD-SNAPSHOT)"
|
||||
"versionRange": "[2.1.4.RELEASE,2.4.0.BUILD-SNAPSHOT)"
|
||||
},
|
||||
{
|
||||
"id": "my-api",
|
||||
@@ -192,7 +192,7 @@
|
||||
"default": "2.1.4.RELEASE",
|
||||
"values": [
|
||||
{
|
||||
"id": "2.2.0.BUILD-SNAPSHOT",
|
||||
"id": "2.4.0.BUILD-SNAPSHOT",
|
||||
"name": "Latest SNAPSHOT"
|
||||
},
|
||||
{
|
||||
|
||||
@@ -0,0 +1,232 @@
|
||||
{
|
||||
"_links": {
|
||||
"dependencies": {
|
||||
"href": "http://@host@/dependencies{?bootVersion}",
|
||||
"templated": true
|
||||
},
|
||||
"maven-build": {
|
||||
"href": "http://@host@/pom.xml?type=maven-build{&dependencies,packaging,javaVersion,language,bootVersion,groupId,artifactId,version,name,description,packageName}",
|
||||
"templated": true
|
||||
},
|
||||
"maven-project": {
|
||||
"href": "http://@host@/starter.zip?type=maven-project{&dependencies,packaging,javaVersion,language,bootVersion,groupId,artifactId,version,name,description,packageName}",
|
||||
"templated": true
|
||||
},
|
||||
"gradle-build": {
|
||||
"href": "http://@host@/build.gradle?type=gradle-build{&dependencies,packaging,javaVersion,language,bootVersion,groupId,artifactId,version,name,description,packageName}",
|
||||
"templated": true
|
||||
},
|
||||
"gradle-project": {
|
||||
"href": "http://@host@/starter.zip?type=gradle-project{&dependencies,packaging,javaVersion,language,bootVersion,groupId,artifactId,version,name,description,packageName}",
|
||||
"templated": true
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"type": "hierarchical-multi-select",
|
||||
"values": [
|
||||
{
|
||||
"name": "Core",
|
||||
"values": [
|
||||
{
|
||||
"id": "web",
|
||||
"name": "Web",
|
||||
"description": "Web dependency description",
|
||||
"_links": {
|
||||
"guide": {
|
||||
"href": "https://example.com/guide",
|
||||
"title": "Building a RESTful Web Service"
|
||||
},
|
||||
"reference": {
|
||||
"href": "https://example.com/doc"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "security",
|
||||
"name": "Security"
|
||||
},
|
||||
{
|
||||
"id": "data-jpa",
|
||||
"name": "Data JPA"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Other",
|
||||
"values": [
|
||||
{
|
||||
"id": "org.acme:foo",
|
||||
"name": "Foo",
|
||||
"_links": {
|
||||
"guide": [
|
||||
{
|
||||
"href": "https://example.com/guide1"
|
||||
},
|
||||
{
|
||||
"href": "https://example.com/guide2",
|
||||
"title": "Some guide for foo"
|
||||
}
|
||||
],
|
||||
"reference": {
|
||||
"href": "https://example.com/{bootVersion}/doc",
|
||||
"templated": true
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "org.acme:bar",
|
||||
"name": "Bar"
|
||||
},
|
||||
{
|
||||
"id": "org.acme:biz",
|
||||
"name": "Biz",
|
||||
"versionRange": "2.2.0.BUILD-SNAPSHOT"
|
||||
},
|
||||
{
|
||||
"id": "org.acme:bur",
|
||||
"name": "Bur",
|
||||
"versionRange": "[2.1.4.RELEASE,2.4.0-SNAPSHOT)"
|
||||
},
|
||||
{
|
||||
"id": "my-api",
|
||||
"name": "My API"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"type": {
|
||||
"type": "action",
|
||||
"default": "maven-project",
|
||||
"values": [
|
||||
{
|
||||
"id": "maven-build",
|
||||
"name": "Maven POM",
|
||||
"action": "/pom.xml",
|
||||
"tags": {
|
||||
"build": "maven",
|
||||
"format": "build"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "maven-project",
|
||||
"name": "Maven Project",
|
||||
"action": "/starter.zip",
|
||||
"tags": {
|
||||
"build": "maven",
|
||||
"format": "project"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "gradle-build",
|
||||
"name": "Gradle Config",
|
||||
"action": "/build.gradle",
|
||||
"tags": {
|
||||
"build": "gradle",
|
||||
"format": "build"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "gradle-project",
|
||||
"name": "Gradle Project",
|
||||
"action": "/starter.zip",
|
||||
"tags": {
|
||||
"build": "gradle",
|
||||
"format": "project"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"packaging": {
|
||||
"type": "single-select",
|
||||
"default": "jar",
|
||||
"values": [
|
||||
{
|
||||
"id": "jar",
|
||||
"name": "Jar"
|
||||
},
|
||||
{
|
||||
"id": "war",
|
||||
"name": "War"
|
||||
}
|
||||
]
|
||||
},
|
||||
"javaVersion": {
|
||||
"type": "single-select",
|
||||
"default": "1.8",
|
||||
"values": [
|
||||
{
|
||||
"id": "1.6",
|
||||
"name": "1.6"
|
||||
},
|
||||
{
|
||||
"id": "1.7",
|
||||
"name": "1.7"
|
||||
},
|
||||
{
|
||||
"id": "1.8",
|
||||
"name": "1.8"
|
||||
}
|
||||
]
|
||||
},
|
||||
"language": {
|
||||
"type": "single-select",
|
||||
"default": "java",
|
||||
"values": [
|
||||
{
|
||||
"id": "groovy",
|
||||
"name": "Groovy"
|
||||
},
|
||||
{
|
||||
"id": "java",
|
||||
"name": "Java"
|
||||
},
|
||||
{
|
||||
"id": "kotlin",
|
||||
"name": "Kotlin"
|
||||
}
|
||||
]
|
||||
},
|
||||
"bootVersion": {
|
||||
"type": "single-select",
|
||||
"default": "2.1.4.RELEASE",
|
||||
"values": [
|
||||
{
|
||||
"id": "2.4.0-SNAPSHOT",
|
||||
"name": "Latest SNAPSHOT"
|
||||
},
|
||||
{
|
||||
"id": "2.1.4.RELEASE",
|
||||
"name": "2.1.4"
|
||||
},
|
||||
{
|
||||
"id": "1.5.17.RELEASE",
|
||||
"name": "1.5.17"
|
||||
}
|
||||
]
|
||||
},
|
||||
"groupId": {
|
||||
"type": "text",
|
||||
"default": "com.example"
|
||||
},
|
||||
"artifactId": {
|
||||
"type": "text",
|
||||
"default": "demo"
|
||||
},
|
||||
"version": {
|
||||
"type": "text",
|
||||
"default": "0.0.1-SNAPSHOT"
|
||||
},
|
||||
"name": {
|
||||
"type": "text",
|
||||
"default": "demo"
|
||||
},
|
||||
"description": {
|
||||
"type": "text",
|
||||
"default": "Demo project for Spring Boot"
|
||||
},
|
||||
"packageName": {
|
||||
"type": "text",
|
||||
"default": "com.example.demo"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user