#144 - Add Calver type.

This commit is contained in:
Mark Paluch
2020-04-30 11:01:35 +02:00
parent 7eb0a23ab2
commit 44517c9680
4 changed files with 454 additions and 3 deletions

View File

@@ -0,0 +1,219 @@
package org.springframework.data.release.model;
import lombok.Getter;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
* Value object to represent a Calver version consisting of year, minor, micro and modifier parts.
*
* @author Mark Paluch
*/
@Getter
public class Calver implements Comparable<Calver> {
private static final Pattern PATTERN = Pattern
.compile("(\\d{4})\\.(\\d+)\\.(\\d+)(-((SR\\d+)|(RC\\d+)|(M\\d+)|(SNAPSHOT)))?");
private final int year;
private final int minor;
private final int micro;
private final Iteration modifier;
private Calver(int year, int minor, int micro, Iteration modifier) {
this.year = year;
this.minor = minor;
this.micro = micro;
this.modifier = modifier;
}
/**
* Parses the given string representation of a version into a {@link Calver} object.
*
* @param version must not be {@literal null} or empty.
* @return
*/
public static Calver parse(String version) {
Assert.hasText(version, "Version must not be null or empty!");
Matcher matcher = PATTERN.matcher(version);
Assert.isTrue(matcher.find(), "Version does not match CalVer");
int year = Integer.parseInt(matcher.group(1));
int minor = Integer.parseInt(matcher.group(2));
int micro = Integer.parseInt(matcher.group(3));
String modifier = matcher.group(5);
Iteration iteration;
if (modifier == null) {
iteration = Iteration.GA;
} else if (modifier.equals("SNAPSHOT")) {
iteration = new Iteration("SNAPSHOT", null);
} else {
iteration = Iteration.valueOf(modifier);
}
return new Calver(year, minor, micro, iteration);
}
/**
* Returns whether the current {@link Calver} is greater (newer) than the given one.
*
* @param version
* @return
*/
public boolean isGreaterThan(Calver version) {
return compareTo(version) > 0;
}
/**
* Returns whether the current {@link Calver} is greater (newer) or the same as the given one.
*
* @param version
* @return
*/
public boolean isGreaterThanOrEqualTo(Calver version) {
return compareTo(version) >= 0;
}
/**
* Returns whether the current {@link Calver} is the same as the given one.
*
* @param version
* @return
*/
public boolean is(Calver version) {
return equals(version);
}
/**
* Returns whether the current {@link Calver} is less (older) than the given one.
*
* @param version
* @return
*/
public boolean isLessThan(Calver version) {
return compareTo(version) < 0;
}
/**
* Returns whether the current {@link Calver} is less (older) or equal to the current one.
*
* @param version
* @return
*/
public boolean isLessThanOrEqualTo(Calver version) {
return compareTo(version) <= 0;
}
public Calver nextMinor() {
return new Calver(this.year, this.minor + 1, 0, modifier);
}
public Calver nextBugfix() {
return new Calver(this.year, this.minor, this.micro + 1, modifier);
}
public Calver withBugfix(int bugfix) {
return new Calver(this.year, this.minor, bugfix, modifier);
}
public Calver withModifier(Iteration modifier) {
return new Calver(this.year, this.minor, this.micro, modifier);
}
/*
* (non-Javadoc)
* @see java.lang.Comparable#compareTo(java.lang.Object)
*/
public int compareTo(Calver that) {
if (that == null) {
return 1;
}
if (year != that.year) {
return year - that.year;
}
if (minor != that.minor) {
return minor - that.minor;
}
if (micro != that.micro) {
return micro - that.micro;
}
if (modifier != that.modifier) {
if (modifier == null && that.modifier == null) {
return 0;
}
if (modifier != null && that.modifier == null) {
return modifier.compareTo(Iteration.GA);
}
if (modifier == null && that.modifier != null) {
return Iteration.GA.compareTo(modifier);
}
return modifier.compareTo(that.modifier);
}
return 0;
}
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (!(o instanceof Calver))
return false;
Calver calver = (Calver) o;
if (year != calver.year)
return false;
if (minor != calver.minor)
return false;
if (micro != calver.micro)
return false;
return modifier.equals(calver.modifier);
}
@Override
public int hashCode() {
int result = year;
result = 31 * result + minor;
result = 31 * result + micro;
result = 31 * result + modifier.hashCode();
return result;
}
/*
* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
List<Integer> digits = new ArrayList<>();
digits.add(year);
digits.add(minor);
digits.add(micro);
String raw = StringUtils.collectionToDelimitedString(digits, ".");
if (!Iteration.GA.equals(this.modifier)) {
return String.format("%s-%s", raw, this.modifier.getName());
}
return raw;
}
}

View File

@@ -18,7 +18,10 @@ package org.springframework.data.release.model;
import lombok.NonNull;
import lombok.Value;
import java.lang.reflect.Field;
import org.springframework.util.Assert;
import org.springframework.util.ReflectionUtils;
/**
* Value object to represent an individual release train iteration.
@@ -27,7 +30,7 @@ import org.springframework.util.Assert;
* @author Mark Paluch
*/
@Value
public class Iteration {
public class Iteration implements Comparable<Iteration> {
public static final Iteration SR24 = new Iteration("SR23", null);
public static final Iteration SR23 = new Iteration("SR23", SR24);
@@ -54,9 +57,20 @@ public class Iteration {
public static final Iteration SR2 = new Iteration("SR2", SR3);
public static final Iteration SR1 = new Iteration("SR1", SR2);
public static final Iteration GA = new Iteration("GA", SR1);
public static final Iteration RC4 = new Iteration("RC4", GA);
public static final Iteration RC3 = new Iteration("RC3", GA);
public static final Iteration RC2 = new Iteration("RC2", GA);
public static final Iteration RC1 = new Iteration("RC1", GA);
public static final Iteration M5 = new Iteration("M5", RC1);
public static final Iteration M4 = new Iteration("M4", RC1);
public static final Iteration M3 = new Iteration("M3", RC1);
public static final Iteration M2 = new Iteration("M2", RC1);
public static final Iteration M1 = new Iteration("M1", RC1);
private static final int GREATER_THAN = 1;
private static final int LESS_THAN = -GREATER_THAN;
private static final int EQUAL = 0;
/**
* The name of the iteration.
*/
@@ -71,6 +85,24 @@ public class Iteration {
this.next = next;
}
/**
* Lookup {@link Iteration} by its string value.
*
* @param iteration
* @return
* @throws IllegalArgumentException if iteration cannot be resolved.
*/
public static Iteration valueOf(String iteration) {
Field field = ReflectionUtils.findField(Iteration.class, iteration);
if (field == null) {
throw new IllegalArgumentException("Cannot resolve iteration " + iteration);
}
return (Iteration) ReflectionUtils.getField(field, null);
}
public boolean isGAIteration() {
return this.equals(GA);
}
@@ -106,6 +138,27 @@ public class Iteration {
return this.equals(M1);
}
public boolean isMilestone() {
return name.startsWith("M");
}
public boolean isReleaseCandidate() {
return name.startsWith("RC");
}
public int getIterationValue() {
if (isMilestone()) {
return Integer.parseInt(name.substring(1));
}
if (isReleaseCandidate() || isServiceIteration()) {
return Integer.parseInt(name.substring(2));
}
return EQUAL;
}
public int getBugfixValue() {
return name.startsWith("SR") ? Integer.parseInt(name.substring(2)) : 0;
}
@@ -118,4 +171,56 @@ public class Iteration {
public String toString() {
return name;
}
@Override
public int compareTo(Iteration o) {
if (isMilestone()) {
if (o.isMilestone()) {
return Integer.compare(getIterationValue(), o.getIterationValue());
}
return LESS_THAN;
}
if (isReleaseCandidate()) {
if (o.isMilestone()) {
return GREATER_THAN;
}
if (o.isReleaseCandidate()) {
return Integer.compare(getIterationValue(), o.getIterationValue());
}
return LESS_THAN;
}
if (isGAIteration()) {
if (o.isMilestone() || o.isReleaseCandidate()) {
return GREATER_THAN;
}
if (o.isGAIteration()) {
return EQUAL;
}
return LESS_THAN;
}
if (isServiceIteration()) {
if (o.isMilestone() || o.isReleaseCandidate() || o.isGAIteration()) {
return GREATER_THAN;
}
if (o.isServiceIteration()) {
return Integer.compare(getIterationValue(), o.getIterationValue());
}
}
return EQUAL;
}
}

View File

@@ -0,0 +1,78 @@
/*
* Copyright 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.release.model;
import static org.assertj.core.api.Assertions.*;
import org.junit.Test;
/**
* Unit tests for {@link Calver}.
*
* @author Mark Paluch
*/
public class CalverVersionUnitTests {
@Test
public void shouldParseRelease() {
Calver version = Calver.parse("2020.0.1");
assertThat(version.getYear()).isEqualTo(2020);
assertThat(version.getMinor()).isEqualTo(0);
assertThat(version.getMicro()).isEqualTo(1);
}
@Test
public void shouldParseM1Release() {
Calver version = Calver.parse("2020.0.1-M1");
assertThat(version.getYear()).isEqualTo(2020);
assertThat(version.getMinor()).isEqualTo(0);
assertThat(version.getMicro()).isEqualTo(1);
assertThat(version.getModifier()).isEqualTo(Iteration.M1);
}
@Test
public void shouldCompareReleasesCorrectly() {
Calver version = Calver.parse("2020.0.1-RC2");
assertThat(version).isGreaterThan(Calver.parse("2020.0.0-RC2"));
assertThat(version).isLessThan(Calver.parse("2020.0.2-RC2"));
assertThat(version).isLessThan(Calver.parse("2020.1.0-RC2"));
assertThat(version).isLessThan(Calver.parse("2021.0.0-RC2"));
assertThat(version).isGreaterThan(Calver.parse("2020.0.1-RC1"));
assertThat(version).isLessThan(Calver.parse("2020.0.1"));
assertThat(Calver.parse("2020.0.1")).isEqualTo(Calver.parse("2020.0.1"));
assertThat(Calver.parse("2020.0.1")).isLessThan(Calver.parse("2020.0.1-SR1"));
assertThat(Calver.parse("2020.0.1")).isGreaterThan(Calver.parse("2020.0.1-M1"));
}
@Test
public void shouldParseSnapshot() {
Calver version = Calver.parse("2020.0.1-SNAPSHOT");
assertThat(version.getYear()).isEqualTo(2020);
assertThat(version.getMinor()).isEqualTo(0);
assertThat(version.getMicro()).isEqualTo(1);
assertThat(version.getModifier()).isEqualTo(new Iteration("SNAPSHOT", null));
}
}

View File

@@ -15,10 +15,59 @@
*/
package org.springframework.data.release.model;
import static org.assertj.core.api.Assertions.*;
import org.junit.Test;
/**
*
* @author Oliver Gierke
* Unit tests for {@link Iteration}.
*
* @author Mark Paluch
*/
public class IterationUnitTests {
@Test
public void shouldCompareMilestoneIterationsCorrectly() {
assertThat(Iteration.M1).isEqualByComparingTo(Iteration.M1);
assertThat(Iteration.M1).isLessThan(Iteration.RC1);
assertThat(Iteration.M1).isLessThan(Iteration.GA);
assertThat(Iteration.M1).isLessThan(Iteration.SR1);
assertThat(Iteration.M2).isLessThan(Iteration.M3);
assertThat(Iteration.M2).isGreaterThan(Iteration.M1);
}
@Test
public void shouldCompareReleaseCandidateIterationsCorrectly() {
assertThat(Iteration.RC1).isGreaterThan(Iteration.M1);
assertThat(Iteration.RC1).isEqualByComparingTo(Iteration.RC1);
assertThat(Iteration.RC1).isLessThan(Iteration.GA);
assertThat(Iteration.RC1).isLessThan(Iteration.SR1);
assertThat(Iteration.RC2).isLessThan(Iteration.RC3);
assertThat(Iteration.RC2).isGreaterThan(Iteration.RC1);
}
@Test
public void shouldCompareGAIterationsCorrectly() {
assertThat(Iteration.GA).isGreaterThan(Iteration.M1);
assertThat(Iteration.GA).isGreaterThan(Iteration.RC1);
assertThat(Iteration.GA).isEqualByComparingTo(Iteration.GA);
assertThat(Iteration.GA).isLessThan(Iteration.SR1);
}
@Test
public void shouldCompareServiceReleaseIterationsCorrectly() {
assertThat(Iteration.SR1).isGreaterThan(Iteration.M1);
assertThat(Iteration.SR1).isGreaterThan(Iteration.RC1);
assertThat(Iteration.SR1).isGreaterThan(Iteration.GA);
assertThat(Iteration.SR1).isEqualByComparingTo(Iteration.SR1);
assertThat(Iteration.SR2).isLessThan(Iteration.SR3);
assertThat(Iteration.SR2).isGreaterThan(Iteration.SR1);
}
}