blob: e8c096047f5f101f58589d218b8737c10bd77b43 [file] [log] [blame]
// Copyright (c) 2020, the R8 project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.utils;
import java.util.Objects;
public class SemanticVersion {
public static SemanticVersion parse(String version) {
int majorEnd = version.indexOf('.');
if (majorEnd <= 0) {
throw new IllegalArgumentException("Invalid semantic version: " + version);
}
int minorEnd = version.indexOf('.', majorEnd + 1);
if (minorEnd <= majorEnd + 1) {
throw new IllegalArgumentException("Invalid semantic version: " + version);
}
int patchEnd = version.indexOf('-', minorEnd + 1);
int prereleaseEnd = -1;
if (patchEnd == -1) {
patchEnd = version.length();
} else {
if (patchEnd <= minorEnd + 1) {
throw new IllegalArgumentException("Invalid semantic version: " + version);
}
prereleaseEnd = version.length();
}
int major;
int minor;
int patch;
String prerelease;
try {
major = Integer.parseInt(version.substring(0, majorEnd));
minor = Integer.parseInt(version.substring(majorEnd + 1, minorEnd));
patch = Integer.parseInt(version.substring(minorEnd + 1, patchEnd));
prerelease = prereleaseEnd < 0 ? null : version.substring(patchEnd + 1, prereleaseEnd);
} catch (NumberFormatException e) {
throw new IllegalArgumentException("Invalid semantic version: " + version, e);
}
return create(major, minor, patch, prerelease);
}
private final int major;
private final int minor;
private final int patch;
private final String prerelease;
private SemanticVersion(int major, int minor, int patch, String prerelease) {
this.major = major;
this.minor = minor;
this.patch = patch;
this.prerelease = prerelease;
}
public static SemanticVersion create(int major, int minor, int patch) {
return create(major, minor, patch, null);
}
public static SemanticVersion create(int major, int minor, int patch, String prerelease) {
return new SemanticVersion(major, minor, patch, prerelease);
}
public int getMajor() {
return major;
}
public int getMinor() {
return minor;
}
public int getPatch() {
return patch;
}
public boolean isNewerOrEqual(SemanticVersion other) {
if (major != other.major) {
return major > other.major;
}
if (minor != other.minor) {
return minor > other.minor;
}
return patch >= other.patch;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof SemanticVersion)) {
return false;
}
SemanticVersion other = (SemanticVersion) obj;
return major == other.major
&& minor == other.minor
&& patch == other.patch
&& Objects.equals(prerelease, other.prerelease);
}
@Override
public int hashCode() {
return Objects.hash(major, minor, patch, prerelease);
}
@Override
public String toString() {
return "" + major + "." + minor + "." + patch + (prerelease != null ? "-" + prerelease : "");
}
}