mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Platform: build numbers: support multi-component build numbers
This commit is contained in:
@@ -23,63 +23,71 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author max
|
||||
*/
|
||||
public class BuildNumber implements Comparable<BuildNumber> {
|
||||
public enum Format { HISTORIC, BRANCH_BASED, YEAR_BASED }
|
||||
|
||||
private static final String BUILD_NUMBER = "__BUILD_NUMBER__";
|
||||
private static final String STAR = "*";
|
||||
private static final String SNAPSHOT = "SNAPSHOT";
|
||||
private static final String FALLBACK_VERSION = "999.SNAPSHOT";
|
||||
private static final String FALLBACK_VERSION = "2999.1.SNAPSHOT";
|
||||
|
||||
private static class Holder {
|
||||
private static final int TOP_BASELINE_VERSION = fromFile().getBaselineVersion();
|
||||
private static final BuildNumber CURRENT_VERSION = fromFile();
|
||||
}
|
||||
|
||||
private final String myProductCode;
|
||||
private final int myBaselineVersion;
|
||||
private final int myBuildNumber;
|
||||
private final String myAttemptInfo;
|
||||
|
||||
@NotNull private final String myProductCode;
|
||||
@NotNull private final Format myFormat;
|
||||
private final int[] myComponents;
|
||||
|
||||
public BuildNumber(@NotNull String productCode, int baselineVersion, int buildNumber) {
|
||||
this(productCode, baselineVersion, buildNumber, null);
|
||||
this(productCode, Format.BRANCH_BASED, baselineVersion, buildNumber);
|
||||
}
|
||||
|
||||
public BuildNumber(@NotNull String productCode, int baselineVersion, int buildNumber, @Nullable String attemptInfo) {
|
||||
BuildNumber(@NotNull String productCode, @NotNull Format format, int... components) {
|
||||
myProductCode = productCode;
|
||||
myBaselineVersion = baselineVersion;
|
||||
myBuildNumber = buildNumber;
|
||||
myAttemptInfo = StringUtil.isEmpty(attemptInfo) ? null : attemptInfo;
|
||||
myFormat = format;
|
||||
myComponents = components;
|
||||
}
|
||||
|
||||
public String asString() {
|
||||
return asString(true, false);
|
||||
return asString(true, true);
|
||||
}
|
||||
|
||||
public String asStringWithAllDetails() {
|
||||
return asString(true, true);
|
||||
}
|
||||
|
||||
public String asStringWithoutProductCode() {
|
||||
return asString(false, true);
|
||||
}
|
||||
|
||||
public String asStringWithoutProductCodeAndSnapshot() {
|
||||
return asString(false, false);
|
||||
}
|
||||
|
||||
private String asString(boolean includeProductCode, boolean withBuildAttempt) {
|
||||
private String asString(boolean includeProductCode, boolean withSnapshotMarker) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
||||
if (includeProductCode && !StringUtil.isEmpty(myProductCode)) {
|
||||
builder.append(myProductCode).append('-');
|
||||
}
|
||||
|
||||
builder.append(myBaselineVersion).append('.');
|
||||
|
||||
if (myBuildNumber != Integer.MAX_VALUE) {
|
||||
builder.append(myBuildNumber);
|
||||
}
|
||||
else {
|
||||
builder.append(SNAPSHOT);
|
||||
}
|
||||
|
||||
if (withBuildAttempt && myAttemptInfo != null) {
|
||||
builder.append('.').append(myAttemptInfo);
|
||||
for (int each : myComponents) {
|
||||
if (each != Integer.MAX_VALUE) {
|
||||
builder.append(each);
|
||||
}
|
||||
else if (withSnapshotMarker) {
|
||||
builder.append(SNAPSHOT);
|
||||
}
|
||||
builder.append('.');
|
||||
}
|
||||
if (builder.charAt(builder.length() - 1) == '.') builder.setLength(builder.length() - 1);
|
||||
|
||||
return builder.toString();
|
||||
}
|
||||
@@ -91,9 +99,9 @@ public class BuildNumber implements Comparable<BuildNumber> {
|
||||
public static BuildNumber fromString(String version, @Nullable String name) {
|
||||
if (version == null) return null;
|
||||
|
||||
if (BUILD_NUMBER.equals(version)) {
|
||||
if (BUILD_NUMBER.equals(version) || SNAPSHOT.equals(version)) {
|
||||
final String productCode = name != null ? name : "";
|
||||
return new BuildNumber(productCode, Holder.TOP_BASELINE_VERSION, Integer.MAX_VALUE);
|
||||
return new BuildNumber(productCode, Holder.CURRENT_VERSION.getFormat(), Holder.CURRENT_VERSION.myComponents);
|
||||
}
|
||||
|
||||
String code = version;
|
||||
@@ -110,38 +118,57 @@ public class BuildNumber implements Comparable<BuildNumber> {
|
||||
int baselineVersionSeparator = code.indexOf('.');
|
||||
int baselineVersion;
|
||||
int buildNumber;
|
||||
String attemptInfo = null;
|
||||
|
||||
if (baselineVersionSeparator > 0) {
|
||||
String baselineVersionString = code.substring(0, baselineVersionSeparator);
|
||||
if (baselineVersionString.trim().isEmpty()) return null;
|
||||
try {
|
||||
String baselineVersionString = code.substring(0, baselineVersionSeparator);
|
||||
if (baselineVersionString.trim().isEmpty()) return null;
|
||||
baselineVersion = Integer.parseInt(baselineVersionString);
|
||||
code = code.substring(baselineVersionSeparator + 1);
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
throw new RuntimeException("Invalid version number: " + version + "; plugin name: " + name);
|
||||
}
|
||||
|
||||
int minorBuildSeparator = code.indexOf('.'); // allow <BuildNumber>.<BuildAttemptNumber> skipping BuildAttemptNumber
|
||||
if (minorBuildSeparator > 0) {
|
||||
attemptInfo = code.substring(minorBuildSeparator + 1);
|
||||
code = code.substring(0, minorBuildSeparator);
|
||||
if (baselineVersion >= 2016) {
|
||||
List<String> stringComponents = StringUtil.split(code, ".");
|
||||
int[] intComponents = new int[stringComponents.size()];
|
||||
for (int i = 0; i < stringComponents.size(); i++) {
|
||||
intComponents[i] = parseBuildNumber(version, stringComponents.get(i), name);
|
||||
}
|
||||
|
||||
return new BuildNumber(productCode, Format.YEAR_BASED, intComponents);
|
||||
}
|
||||
else {
|
||||
code = code.substring(baselineVersionSeparator + 1);
|
||||
|
||||
int minorBuildSeparator = code.indexOf('.'); // allow <BuildNumber>.<BuildAttemptNumber> skipping BuildAttemptNumber
|
||||
|
||||
Integer attemptInfo = null;
|
||||
if (minorBuildSeparator > 0) {
|
||||
attemptInfo = parseBuildNumber(version, code.substring(minorBuildSeparator + 1), name);
|
||||
code = code.substring(0, minorBuildSeparator);
|
||||
}
|
||||
buildNumber = parseBuildNumber(version, code, name);
|
||||
|
||||
if (attemptInfo != null) {
|
||||
return new BuildNumber(productCode, Format.BRANCH_BASED, baselineVersion, buildNumber, attemptInfo);
|
||||
}
|
||||
else {
|
||||
return new BuildNumber(productCode, Format.BRANCH_BASED, baselineVersion, buildNumber);
|
||||
}
|
||||
}
|
||||
buildNumber = parseBuildNumber(version, code, name);
|
||||
}
|
||||
else {
|
||||
buildNumber = parseBuildNumber(version, code, name);
|
||||
|
||||
if (buildNumber <= 2000) {
|
||||
// it's probably a baseline, not a build number
|
||||
return new BuildNumber(productCode, buildNumber, 0, null);
|
||||
return new BuildNumber(productCode, Format.BRANCH_BASED, buildNumber, 0);
|
||||
}
|
||||
|
||||
|
||||
baselineVersion = getBaseLineForHistoricBuilds(buildNumber);
|
||||
return new BuildNumber(productCode, Format.HISTORIC, baselineVersion, buildNumber);
|
||||
}
|
||||
|
||||
return new BuildNumber(productCode, baselineVersion, buildNumber, attemptInfo);
|
||||
}
|
||||
|
||||
private static int parseBuildNumber(String version, String code, String name) {
|
||||
@@ -181,21 +208,44 @@ public class BuildNumber implements Comparable<BuildNumber> {
|
||||
|
||||
@Override
|
||||
public int compareTo(@NotNull BuildNumber o) {
|
||||
if (myBaselineVersion == o.myBaselineVersion) return myBuildNumber - o.myBuildNumber;
|
||||
return myBaselineVersion - o.myBaselineVersion;
|
||||
for (int i = 0; i < Math.min(myComponents.length, o.myComponents.length); i++) {
|
||||
int result = myComponents[i] - o.myComponents[i];
|
||||
if (result != 0) return result;
|
||||
|
||||
if (myComponents[i] == Integer.MAX_VALUE) return 0; // anything after first SNAPSHOT doesn't really matter
|
||||
}
|
||||
return myComponents.length - o.myComponents.length;
|
||||
}
|
||||
|
||||
public int compareToWithVariableLength(@NotNull BuildNumber o) {
|
||||
for (int i = 0; i < Math.min(myComponents.length, o.myComponents.length); i++) {
|
||||
int result = myComponents[i] - o.myComponents[i];
|
||||
if (result != 0) return result;
|
||||
|
||||
if (myComponents[i] == Integer.MAX_VALUE) return 0; // anything after first SNAPSHOT doesn't really matter
|
||||
}
|
||||
return myComponents.length - o.myComponents.length;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@NotNull
|
||||
public String getProductCode() {
|
||||
return myProductCode;
|
||||
}
|
||||
|
||||
public int getBaselineVersion() {
|
||||
return myBaselineVersion;
|
||||
return myFormat == Format.YEAR_BASED ? (myComponents[0] * 10 + myComponents[1]) : myComponents[0];
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public int getBuildNumber() {
|
||||
return myBuildNumber;
|
||||
return myFormat == Format.YEAR_BASED ? -1 : myComponents[1];
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Format getFormat() {
|
||||
return myFormat;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -205,10 +255,9 @@ public class BuildNumber implements Comparable<BuildNumber> {
|
||||
|
||||
BuildNumber that = (BuildNumber)o;
|
||||
|
||||
if (myBaselineVersion != that.myBaselineVersion) return false;
|
||||
if (myBuildNumber != that.myBuildNumber) return false;
|
||||
if (myFormat != that.myFormat) return false;
|
||||
if (!myProductCode.equals(that.myProductCode)) return false;
|
||||
if (!Comparing.equal(myAttemptInfo, that.myAttemptInfo)) return false;
|
||||
if (!Arrays.equals(myComponents, that.myComponents)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -216,18 +265,13 @@ public class BuildNumber implements Comparable<BuildNumber> {
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = myProductCode.hashCode();
|
||||
result = 31 * result + myBaselineVersion;
|
||||
result = 31 * result + myBuildNumber;
|
||||
if (myAttemptInfo != null) result = 31 * result + myAttemptInfo.hashCode();
|
||||
result = 31 * result + Arrays.hashCode(myComponents);
|
||||
result = 31 * result + myFormat.hashCode();
|
||||
return result;
|
||||
}
|
||||
|
||||
// See http://www.jetbrains.net/confluence/display/IDEADEV/Build+Number+Ranges for historic build ranges
|
||||
private static int getBaseLineForHistoricBuilds(int bn) {
|
||||
if (bn == Integer.MAX_VALUE) {
|
||||
return Holder.TOP_BASELINE_VERSION; // SNAPSHOTS
|
||||
}
|
||||
|
||||
if (bn >= 10000) {
|
||||
return 88; // Maia, 9x builds
|
||||
}
|
||||
@@ -276,10 +320,9 @@ public class BuildNumber implements Comparable<BuildNumber> {
|
||||
}
|
||||
|
||||
public boolean isSnapshot() {
|
||||
return myBuildNumber == Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
public String asStringWithAllDetails() {
|
||||
return asString(true, true);
|
||||
for (int each : myComponents) {
|
||||
if (each == Integer.MAX_VALUE) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,21 +19,82 @@ import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* @author max
|
||||
*/
|
||||
public class BuildNumberTest {
|
||||
@Test
|
||||
public void historicBuild() {
|
||||
assertEquals(new BuildNumber("", 75, 7512), BuildNumber.fromString("7512"));
|
||||
assertEquals(new BuildNumber("", BuildNumber.Format.HISTORIC, 75, 7512), BuildNumber.fromString("7512"));
|
||||
assertEquals("75.7512", BuildNumber.fromString("7512").asString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void branchBasedBuild() throws Exception {
|
||||
assertParsed(BuildNumber.fromString("145"), 145, 0, "145.0");
|
||||
assertParsed(BuildNumber.fromString("145.1"), 145, 1, "145.1");
|
||||
assertParsed(BuildNumber.fromString("145.1.2"), 145, 1, "145.1.2");
|
||||
assertParsed(BuildNumber.fromString("IU-145.1.2"), 145, 1, "IU-145.1.2");
|
||||
assertParsed(BuildNumber.fromString("IU-145.SNAPSHOT"), 145, Integer.MAX_VALUE, "IU-145.SNAPSHOT");
|
||||
assertParsed(BuildNumber.fromString("IU-145.1.SNAPSHOT"), 145, 1, "IU-145.1.SNAPSHOT");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void yearBasedBuild() throws Exception {
|
||||
assertParsed(BuildNumber.fromString("2016.1.2"), 20161, -1, "2016.1.2");
|
||||
assertParsed(BuildNumber.fromString("IU-2016.1.2"), 20161, -1, "IU-2016.1.2");
|
||||
assertParsed(BuildNumber.fromString("2016.1.2.3"), 20161, -1, "2016.1.2.3");
|
||||
assertParsed(BuildNumber.fromString("IU-2016.1.2.3"), 20161, -1, "IU-2016.1.2.3");
|
||||
assertParsed(BuildNumber.fromString("2016.1.2.3.4"), 20161, -1, "2016.1.2.3.4");
|
||||
assertParsed(BuildNumber.fromString("IU-2016.1.2.3.4"), 20161, -1, "IU-2016.1.2.3.4");
|
||||
|
||||
assertParsed(BuildNumber.fromString("IU-2016.1.SNAPSHOT"), 20161, -1, "IU-2016.1.SNAPSHOT");
|
||||
assertParsed(BuildNumber.fromString("IU-2016.1.SNAPSHOT.1"), 20161, -1, "IU-2016.1.SNAPSHOT.1");
|
||||
}
|
||||
|
||||
private static void assertParsed(BuildNumber n, int expectedBaseline, int expectedBuildNumber, String asString) {
|
||||
assertEquals(expectedBaseline, n.getBaselineVersion());
|
||||
assertEquals(expectedBuildNumber, n.getBuildNumber());
|
||||
assertEquals(asString, n.asString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void comparingYearBasedVersion() throws Exception {
|
||||
assertTrue(BuildNumber.fromString("2016.1").compareTo(BuildNumber.fromString("2016.1")) == 0);
|
||||
assertTrue(BuildNumber.fromString("2016.1.1").compareTo(BuildNumber.fromString("2016.1.1")) == 0);
|
||||
assertTrue(BuildNumber.fromString("2016.1.1.1").compareTo(BuildNumber.fromString("2016.1.1.1")) == 0);
|
||||
|
||||
assertTrue(BuildNumber.fromString("2016.1").compareTo(BuildNumber.fromString("2016.1.1")) < 0);
|
||||
assertTrue(BuildNumber.fromString("2016.1").compareTo(BuildNumber.fromString("2016.1.1.1")) < 0);
|
||||
assertTrue(BuildNumber.fromString("2016.1.1").compareTo(BuildNumber.fromString("2016.1.1.1")) < 0);
|
||||
|
||||
assertTrue(BuildNumber.fromString("2016.1").compareTo(BuildNumber.fromString("2016.2")) < 0);
|
||||
assertTrue(BuildNumber.fromString("2016.1").compareTo(BuildNumber.fromString("2016.2.1")) < 0);
|
||||
assertTrue(BuildNumber.fromString("2016.1.1").compareTo(BuildNumber.fromString("2016.2")) < 0);
|
||||
assertTrue(BuildNumber.fromString("2016.1.1").compareTo(BuildNumber.fromString("2016.2.1")) < 0);
|
||||
|
||||
assertTrue(BuildNumber.fromString("146.1").compareTo(BuildNumber.fromString("2016.1")) < 0);
|
||||
assertTrue(BuildNumber.fromString("146.9.9").compareTo(BuildNumber.fromString("2016.1")) < 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isSnapshot() {
|
||||
assertTrue(BuildNumber.fromString("SNAPSHOT").isSnapshot());
|
||||
assertTrue(BuildNumber.fromString("__BUILD_NUMBER__").isSnapshot());
|
||||
assertTrue(BuildNumber.fromString("IU-90.SNAPSHOT").isSnapshot());
|
||||
assertTrue(BuildNumber.fromString("IC-90.*").isSnapshot());
|
||||
assertFalse(BuildNumber.fromString("90.9999999").isSnapshot());
|
||||
|
||||
assertFalse(BuildNumber.fromString("2016.1").isSnapshot());
|
||||
assertTrue(BuildNumber.fromString("2016.1.SNAPSHOT").isSnapshot());
|
||||
assertTrue(BuildNumber.fromString("2016.1.SNAPSHOT.1").isSnapshot());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void devSnapshotVersion() throws Exception {
|
||||
BuildNumber b = BuildNumber.fromString("__BUILD_NUMBER__");
|
||||
assertTrue(b.asString(), b.getBaselineVersion() >= 2016);
|
||||
assertEquals(b.asString(), -1, b.getBuildNumber());
|
||||
assertTrue(b.isSnapshot());
|
||||
|
||||
assertEquals(BuildNumber.fromString("__BUILD_NUMBER__"), BuildNumber.fromString("SNAPSHOT"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -43,5 +104,26 @@ public class BuildNumberTest {
|
||||
assertTrue(BuildNumber.fromString("IU-90.SNAPSHOT").compareTo(BuildNumber.fromString("RM-100.12345")) < 0);
|
||||
assertTrue(BuildNumber.fromString("IU-90.SNAPSHOT").compareTo(BuildNumber.fromString("RM-100.SNAPSHOT")) < 0);
|
||||
assertTrue(BuildNumber.fromString("IU-90.SNAPSHOT").compareTo(BuildNumber.fromString("RM-90.SNAPSHOT")) == 0);
|
||||
|
||||
assertTrue(BuildNumber.fromString("2016.1.SNAPSHOT").compareTo(BuildNumber.fromString("2016.1.1")) > 0);
|
||||
assertTrue(BuildNumber.fromString("2016.1.SNAPSHOT").compareTo(BuildNumber.fromString("2016.1.SNAPSHOT")) == 0);
|
||||
assertTrue(BuildNumber.fromString("2016.1.1.SNAPSHOT").compareTo(BuildNumber.fromString("2016.1.1.1")) > 0);
|
||||
assertTrue(BuildNumber.fromString("2016.1.1.SNAPSHOT").compareTo(BuildNumber.fromString("2016.1.1.SNAPSHOT")) == 0);
|
||||
assertTrue(BuildNumber.fromString("2016.1.SNAPSHOT.1").compareTo(BuildNumber.fromString("2016.1.1.1")) > 0);
|
||||
assertTrue(BuildNumber.fromString("2016.1.SNAPSHOT.1").compareTo(BuildNumber.fromString("2016.1.1.SNAPSHOT")) > 0);
|
||||
assertTrue(BuildNumber.fromString("2016.1.SNAPSHOT.1").compareTo(BuildNumber.fromString("2016.1.SNAPSHOT.SNAPSHOT")) == 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void fallbackVersion() throws Exception {
|
||||
assertParsed(BuildNumber.fallback(), 29991, -1, "2999.1.SNAPSHOT");
|
||||
assertEquals(BuildNumber.Format.YEAR_BASED, BuildNumber.fallback().getFormat());
|
||||
assertTrue(BuildNumber.fallback().isSnapshot());
|
||||
|
||||
assertTrue(BuildNumber.fallback().compareTo(BuildNumber.fromString("7512")) > 0);
|
||||
assertTrue(BuildNumber.fallback().compareTo(BuildNumber.fromString("145")) > 0);
|
||||
assertTrue(BuildNumber.fallback().compareTo(BuildNumber.fromString("145.12")) > 0);
|
||||
assertTrue(BuildNumber.fallback().compareTo(BuildNumber.fromString("2016.1")) > 0);
|
||||
assertTrue(BuildNumber.fallback().compareTo(BuildNumber.fromString("2016.1.2")) > 0);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user