11package com .dazednconfused .catalauncher .update ;
22
33import java .util .Objects ;
4+ import java .util .regex .Matcher ;
5+ import java .util .regex .Pattern ;
46
57/**
68 * @see <a href="https://stackoverflow.com/a/11024200">https://stackoverflow.com/a/11024200</a>
79 * */
810public class Version implements Comparable <Version > {
911
12+ private static final Pattern VERSION_PATTERN = Pattern .compile ("^(?:prerelease-)?v?([0-9]+(\\ .[0-9]+)*)(?:-(.+))?$" );
13+
1014 private final String semver ;
15+ private final String preReleaseTag ;
16+ private final boolean isPreRelease ;
1117
12- public final String get () {
18+ public String get () {
1319 return this .semver ;
1420 }
1521
22+ public String getPreReleaseTag () {
23+ return this .preReleaseTag ;
24+ }
25+
26+ public boolean isPreRelease () {
27+ return this .isPreRelease ;
28+ }
29+
1630 /**
17- * Constructor.
18- * */
19- public Version (String semver ) {
20- if (semver == null ) {
31+ * Constructs a Version object from a version string.
32+ *
33+ * @param versionString the version string, e.g., "v1.2.3", "prerelease-v1.2.3-alpha", etc.
34+ *
35+ * @throws IllegalArgumentException if the version string is null or does not match the expected format
36+ */
37+ public Version (String versionString ) {
38+ if (versionString == null ) {
2139 throw new IllegalArgumentException ("Version cannot be null" );
2240 }
23- if (!semver .matches ("v?[0-9]+(\\ .[0-9]+)*" )) {
41+ Matcher matcher = VERSION_PATTERN .matcher (versionString );
42+ if (!matcher .matches ()) {
2443 throw new IllegalArgumentException ("Invalid version format" );
25-
26- }
27- if (semver .startsWith ("v" )) {
28- // prune any potential version tags starting with a 'v'
29- semver = semver .substring (1 );
3044 }
31-
32- this .semver = semver ;
45+ this .isPreRelease = versionString .startsWith ("prerelease-" );
46+ this .semver = matcher .group (1 );
47+ this .preReleaseTag = matcher .group (3 );
3348 }
3449
3550 @ Override
3651 public int compareTo (Version that ) {
3752 if (that == null ) {
3853 return 1 ;
3954 }
40- String [] thisParts = this .get () .split ("\\ ." );
41- String [] thatParts = that .get () .split ("\\ ." );
55+ String [] thisParts = this .semver .split ("\\ ." );
56+ String [] thatParts = that .semver .split ("\\ ." );
4257 int length = Math .max (thisParts .length , thatParts .length );
4358 for (int i = 0 ; i < length ; i ++) {
4459 int thisPart = i < thisParts .length ? Integer .parseInt (thisParts [i ]) : 0 ;
@@ -50,6 +65,29 @@ public int compareTo(Version that) {
5065 return 1 ;
5166 }
5267 }
68+
69+ // if base versions are equal, pre-releases are considered lower than releases
70+ if (this .isPreRelease && !that .isPreRelease ) {
71+ return -1 ;
72+ }
73+ if (!this .isPreRelease && that .isPreRelease ) {
74+ return 1 ;
75+ }
76+
77+ // optionally, compare pre-release tags lexicographically if both are pre-releases
78+ if (this .isPreRelease ) {
79+ if (this .preReleaseTag == null && that .preReleaseTag != null ) {
80+ return -1 ;
81+ }
82+ if (this .preReleaseTag != null && that .preReleaseTag == null ) {
83+ return 1 ;
84+ }
85+ if (this .preReleaseTag != null ) {
86+ return this .preReleaseTag .compareTo (that .preReleaseTag );
87+ }
88+ }
89+
90+ // if both versions are equal, return 0
5391 return 0 ;
5492 }
5593
@@ -58,22 +96,22 @@ public boolean equals(Object that) {
5896 if (this == that ) {
5997 return true ;
6098 }
61- if (that == null ) {
62- return false ;
63- }
64- if (this .getClass () != that .getClass ()) {
99+ if (that == null || this .getClass () != that .getClass ()) {
65100 return false ;
66101 }
67102 return this .compareTo ((Version ) that ) == 0 ;
68103 }
69104
70105 @ Override
71106 public int hashCode () {
72- return Objects .hashCode (semver );
107+ return Objects .hash (semver , preReleaseTag , isPreRelease );
73108 }
74109
75110 @ Override
76111 public String toString () {
77- return this .semver ;
112+ if (isPreRelease && preReleaseTag != null ) {
113+ return "prerelease-" + semver + "-" + preReleaseTag ;
114+ }
115+ return semver ;
78116 }
79117}
0 commit comments