mirror of
https://gitee.com/dcren/initializr.git
synced 2025-09-18 17:48:14 +08:00
Add support for SemVer and CalVer versions
This commit improves the version parser to handle qualifiers that are separated by either a `.` or a `-`. This makes the parsing of `1.2.0-RC1` or `2020.0.0-M1` possible. Closes gh-1083
This commit is contained in:
@@ -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.
|
||||
@@ -44,7 +44,7 @@ class SpringBootVersionRepositoriesBuildCustomizer implements BuildCustomizer<Bu
|
||||
@Override
|
||||
public void customize(Build build) {
|
||||
build.repositories().add("maven-central");
|
||||
String qualifier = this.springBootVersion.getQualifier().getQualifier();
|
||||
String qualifier = this.springBootVersion.getQualifier().getId();
|
||||
if (!"RELEASE".equals(qualifier)) {
|
||||
addMilestoneRepository(build);
|
||||
if ("BUILD-SNAPSHOT".equals(qualifier)) {
|
||||
|
@@ -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.
|
||||
@@ -21,6 +21,8 @@ import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.StringJoiner;
|
||||
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
@@ -190,9 +192,15 @@ public final class Version implements Serializable, Comparable<Version> {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.major + "." + this.minor + "." + this.patch + ((this.qualifier != null)
|
||||
? "." + this.qualifier.qualifier + ((this.qualifier.version != null) ? this.qualifier.version : "")
|
||||
: "");
|
||||
StringBuilder sb = new StringBuilder().append(this.major).append(".").append(this.minor).append(".")
|
||||
.append(this.patch);
|
||||
if (this.qualifier != null) {
|
||||
sb.append(this.qualifier.getSeparator()).append(this.qualifier.getId());
|
||||
if (this.qualifier.getVersion() != null) {
|
||||
sb.append(this.qualifier.getVersion());
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -200,74 +208,56 @@ public final class Version implements Serializable, Comparable<Version> {
|
||||
*/
|
||||
public static class Qualifier implements Serializable {
|
||||
|
||||
public Qualifier(String qualifier) {
|
||||
this.qualifier = qualifier;
|
||||
private final String id;
|
||||
|
||||
private final Integer version;
|
||||
|
||||
private final String separator;
|
||||
|
||||
public Qualifier(String id) {
|
||||
this(id, null, ".");
|
||||
}
|
||||
|
||||
private String qualifier;
|
||||
|
||||
private Integer version;
|
||||
|
||||
public String getQualifier() {
|
||||
return this.qualifier;
|
||||
public Qualifier(String id, Integer version, String separator) {
|
||||
this.id = id;
|
||||
this.version = version;
|
||||
this.separator = separator;
|
||||
}
|
||||
|
||||
public void setQualifier(String qualifier) {
|
||||
this.qualifier = qualifier;
|
||||
public String getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public Integer getVersion() {
|
||||
return this.version;
|
||||
}
|
||||
|
||||
public void setVersion(Integer version) {
|
||||
this.version = version;
|
||||
public String getSeparator() {
|
||||
return this.separator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
Qualifier other = (Qualifier) obj;
|
||||
if (this.qualifier == null) {
|
||||
if (other.qualifier != null) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (!this.qualifier.equals(other.qualifier)) {
|
||||
return false;
|
||||
}
|
||||
if (this.version == null) {
|
||||
if (other.version != null) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (!this.version.equals(other.version)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
Qualifier qualifier = (Qualifier) o;
|
||||
return this.id.equals(qualifier.id) && Objects.equals(this.version, qualifier.version)
|
||||
&& Objects.equals(this.separator, qualifier.separator);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((this.qualifier == null) ? 0 : this.qualifier.hashCode());
|
||||
result = prime * result + ((this.version == null) ? 0 : this.version.hashCode());
|
||||
return result;
|
||||
return Objects.hash(this.id, this.version, this.separator);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Qualifier [" + ((this.qualifier != null) ? "qualifier=" + this.qualifier + ", " : "")
|
||||
+ ((this.version != null) ? "version=" + this.version : "") + "]";
|
||||
return new StringJoiner(", ", Qualifier.class.getSimpleName() + "[", "]").add("id='" + this.id + "'")
|
||||
.add("version=" + this.version).add("separator='" + this.separator + "'").toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -275,11 +265,12 @@ public final class Version implements Serializable, Comparable<Version> {
|
||||
private static class VersionQualifierComparator implements Comparator<Qualifier> {
|
||||
|
||||
static final String RELEASE = "RELEASE";
|
||||
static final String SNAPSHOT = "BUILD-SNAPSHOT";
|
||||
static final String BUILD_SNAPSHOT = "BUILD-SNAPSHOT";
|
||||
static final String SNAPSHOT = "SNAPSHOT";
|
||||
static final String MILESTONE = "M";
|
||||
static final String RC = "RC";
|
||||
|
||||
static final List<String> KNOWN_QUALIFIERS = Arrays.asList(MILESTONE, RC, SNAPSHOT, RELEASE);
|
||||
static final List<String> KNOWN_QUALIFIERS = Arrays.asList(MILESTONE, RC, BUILD_SNAPSHOT, SNAPSHOT, RELEASE);
|
||||
|
||||
@Override
|
||||
public int compare(Qualifier o1, Qualifier o2) {
|
||||
@@ -297,12 +288,12 @@ public final class Version implements Serializable, Comparable<Version> {
|
||||
}
|
||||
|
||||
private static int compareQualifier(Qualifier first, Qualifier second) {
|
||||
int firstIndex = getQualifierIndex(first.qualifier);
|
||||
int secondIndex = getQualifierIndex(second.qualifier);
|
||||
int firstIndex = getQualifierIndex(first.getId());
|
||||
int secondIndex = getQualifierIndex(second.getId());
|
||||
|
||||
// Unknown qualifier, alphabetic ordering
|
||||
if (firstIndex == -1 && secondIndex == -1) {
|
||||
return first.qualifier.compareTo(second.qualifier);
|
||||
return first.getId().compareTo(second.getId());
|
||||
}
|
||||
else {
|
||||
return Integer.compare(firstIndex, secondIndex);
|
||||
|
@@ -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.
|
||||
@@ -48,7 +48,7 @@ public class VersionParser {
|
||||
public static final VersionParser DEFAULT = new VersionParser(Collections.emptyList());
|
||||
|
||||
private static final Pattern VERSION_REGEX = Pattern
|
||||
.compile("^(\\d+)\\.(\\d+|x)\\.(\\d+|x)(?:\\.([^0-9]+)(\\d+)?)?$");
|
||||
.compile("^(\\d+)\\.(\\d+|x)\\.(\\d+|x)(?:([.|-])([^0-9]+)(\\d+)?)?$");
|
||||
|
||||
private static final Pattern RANGE_REGEX = Pattern.compile("(\\(|\\[)(.*),(.*)(\\)|\\])");
|
||||
|
||||
@@ -71,20 +71,12 @@ public class VersionParser {
|
||||
Matcher matcher = VERSION_REGEX.matcher(text.trim());
|
||||
if (!matcher.matches()) {
|
||||
throw new InvalidVersionException("Could not determine version based on '" + text + "': version format "
|
||||
+ "is Major.Minor.Patch.Qualifier " + "(e.g. 1.0.5.RELEASE)");
|
||||
+ "is Major.Minor.Patch and an optional Qualifier " + "(e.g. 1.0.5.RELEASE)");
|
||||
}
|
||||
Integer major = Integer.valueOf(matcher.group(1));
|
||||
String minor = matcher.group(2);
|
||||
String patch = matcher.group(3);
|
||||
Qualifier qualifier = null;
|
||||
String qualifierId = matcher.group(4);
|
||||
if (StringUtils.hasText(qualifierId)) {
|
||||
qualifier = new Version.Qualifier(qualifierId);
|
||||
String o = matcher.group(5);
|
||||
if (o != null) {
|
||||
qualifier.setVersion(Integer.valueOf(o));
|
||||
}
|
||||
}
|
||||
Qualifier qualifier = parseQualifier(matcher);
|
||||
if ("x".equals(minor) || "x".equals(patch)) {
|
||||
Integer minorInt = ("x".equals(minor) ? null : Integer.parseInt(minor));
|
||||
Version latest = findLatestVersion(major, minorInt, qualifier);
|
||||
@@ -99,6 +91,17 @@ public class VersionParser {
|
||||
}
|
||||
}
|
||||
|
||||
private Qualifier parseQualifier(Matcher matcher) {
|
||||
String qualifierSeparator = matcher.group(4);
|
||||
String qualifierId = matcher.group(5);
|
||||
if (StringUtils.hasText(qualifierSeparator) && StringUtils.hasText(qualifierId)) {
|
||||
String versionString = matcher.group(6);
|
||||
return new Qualifier(qualifierId, (versionString != null) ? Integer.valueOf(versionString) : null,
|
||||
qualifierSeparator);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse safely the specified string representation of a {@link Version}.
|
||||
* <p>
|
||||
|
@@ -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,23 +35,35 @@ class VersionParserTests {
|
||||
private VersionParser parser = new VersionParser(Collections.emptyList());
|
||||
|
||||
@Test
|
||||
void noQualifierString() {
|
||||
void versionWithNoQualifier() {
|
||||
Version version = this.parser.parse("1.2.0");
|
||||
assertThat(version.toString()).isEqualTo("1.2.0");
|
||||
}
|
||||
|
||||
@Test
|
||||
void withQualifierString() {
|
||||
void versionWithQualifierAndDotSeparator() {
|
||||
Version version = this.parser.parse("1.2.0.RELEASE");
|
||||
assertThat(version.toString()).isEqualTo("1.2.0.RELEASE");
|
||||
}
|
||||
|
||||
@Test
|
||||
void withQualifierAndVersionString() {
|
||||
void versionWithQualifierAndDashSeparator() {
|
||||
Version version = this.parser.parse("1.2.0-SNAPSHOT");
|
||||
assertThat(version.toString()).isEqualTo("1.2.0-SNAPSHOT");
|
||||
}
|
||||
|
||||
@Test
|
||||
void versionWithQualifierVersionAndDotSeparator() {
|
||||
Version version = this.parser.parse("1.2.0.RC2");
|
||||
assertThat(version.toString()).isEqualTo("1.2.0.RC2");
|
||||
}
|
||||
|
||||
@Test
|
||||
void versionWithQualifierVersionAndDashSeparator() {
|
||||
Version version = this.parser.parse("1.2.0-M3");
|
||||
assertThat(version.toString()).isEqualTo("1.2.0-M3");
|
||||
}
|
||||
|
||||
@Test
|
||||
void parseInvalidVersion() {
|
||||
assertThatExceptionOfType(InvalidVersionException.class).isThrownBy(() -> this.parser.parse("foo"));
|
||||
|
@@ -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,6 +17,9 @@
|
||||
package io.spring.initializr.generator.version;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -123,6 +126,33 @@ class VersionTests {
|
||||
assertThat(parse("1.2.0.BUILD-SNAPSHOT")).isLessThan(parse("1.2.0.RELEASE"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void orderVersionSchemeWithQualifiedVersions() {
|
||||
List<String> sortedVersions = Stream
|
||||
.of("2.3.0.BUILD-SNAPSHOT", "2.3.0.RC1", "2.3.0.M2", "2.3.0.M1", "2.3.0.RELEASE", "2.3.0.RC2")
|
||||
.map(this::parse).sorted().map(Version::toString).collect(Collectors.toList());
|
||||
assertThat(sortedVersions).containsExactly("2.3.0.M1", "2.3.0.M2", "2.3.0.RC1", "2.3.0.RC2",
|
||||
"2.3.0.BUILD-SNAPSHOT", "2.3.0.RELEASE");
|
||||
}
|
||||
|
||||
@Test
|
||||
void orderVersionSchemeWithSemVer() {
|
||||
List<String> sortedVersions = Stream
|
||||
.of("2.3.0-SNAPSHOT", "2.3.0-RC1", "2.3.0-M2", "2.3.0-M1", "2.3.0", "2.3.0-RC2").map(this::parse)
|
||||
.sorted().map(Version::toString).collect(Collectors.toList());
|
||||
assertThat(sortedVersions).containsExactly("2.3.0-M1", "2.3.0-M2", "2.3.0-RC1", "2.3.0-RC2", "2.3.0-SNAPSHOT",
|
||||
"2.3.0");
|
||||
}
|
||||
|
||||
@Test
|
||||
void orderVersionSchemeWithCalVer() {
|
||||
List<String> sortedVersions = Stream
|
||||
.of("2020.0.0-SNAPSHOT", "2020.0.0-RC1", "2020.0.0-M2", "2020.0.0-M1", "2020.0.0", "2020.0.0-RC2")
|
||||
.map(this::parse).sorted().map(Version::toString).collect(Collectors.toList());
|
||||
assertThat(sortedVersions).containsExactly("2020.0.0-M1", "2020.0.0-M2", "2020.0.0-RC1", "2020.0.0-RC2",
|
||||
"2020.0.0-SNAPSHOT", "2020.0.0");
|
||||
}
|
||||
|
||||
private Version parse(String text) {
|
||||
return this.parser.parse(text);
|
||||
}
|
||||
|
Reference in New Issue
Block a user