Skip to content

Commit b9c6cda

Browse files
committed
better versioning
1 parent 4d00101 commit b9c6cda

File tree

6 files changed

+185
-23
lines changed

6 files changed

+185
-23
lines changed

.github/workflows/build-and-test.yml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,8 @@ name: Build and test
66
on:
77
pull_request:
88
branches: [ master, main ]
9-
paths-ignore:
10-
- '**.md'
119
push:
1210
branches: [ master, main ]
13-
paths-ignore:
14-
- '**.md'
1511

1612
jobs:
1713
build-and-test:

src/main/java/com/falsepattern/lib/FalsePatternLib.java

Lines changed: 45 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
package com.falsepattern.lib;
22

3+
import com.falsepattern.lib.api.Version;
34
import com.google.common.eventbus.EventBus;
45
import com.google.common.eventbus.Subscribe;
56
import cpw.mods.fml.common.DummyModContainer;
67
import cpw.mods.fml.common.FMLCommonHandler;
78
import cpw.mods.fml.common.LoadController;
89
import cpw.mods.fml.common.ModMetadata;
910
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
11+
import lombok.NonNull;
1012
import lombok.val;
1113
import lombok.var;
1214
import net.minecraft.launchwrapper.Launch;
@@ -27,11 +29,13 @@ public class FalsePatternLib extends DummyModContainer {
2729
public static Logger libLog = LogManager.getLogger(ModInfo.MODNAME);
2830
public static final boolean developerEnvironment = (boolean) Launch.blackboard.get("fml.deobfuscatedEnvironment");
2931

30-
private static Map<String, String> loadedLibraries = new HashMap<>();
31-
private static Set<String> mavenRepositories = new HashSet<>();
32+
private static final Map<String, Version> loadedLibraries = new HashMap<>();
33+
private static final Map<String, String> loadedLibraryMods = new HashMap<>();
34+
private static final Set<String> mavenRepositories = new HashSet<>();
3235

3336
private static boolean modWasDownloaded = false;
3437

38+
@SuppressWarnings("unchecked")
3539
public FalsePatternLib() {
3640
super(new ModMetadata());
3741
libLog.info("FalsePatternLib has been awakened!");
@@ -68,18 +72,39 @@ public static void addMavenRepo(String url) {
6872
mavenRepositories.add(url);
6973
}
7074

71-
public static void loadLibrary(String groupId, String artifactId, String version, String devSuffix, boolean isMod) {
72-
libLog.info("Adding library {}:{}:{}", groupId, artifactId, version);
75+
@SuppressWarnings("ResultOfMethodCallIgnored")
76+
public static void loadLibrary(String loadingModId, String groupId, String artifactId, @NonNull Version minVersion, Version maxVersion, @NonNull Version preferredVersion, String devSuffix, boolean isMod) {
77+
libLog.info("Adding library {}:{}:{}, requested by mod {}", groupId, artifactId, preferredVersion, loadingModId);
7378
var artifact = groupId + ":" + artifactId;
7479
if (loadedLibraries.containsKey(artifact)) {
7580
val currentVer = loadedLibraries.get(artifact);
76-
if (!version.equals(currentVer)) {
77-
libLog.warn("Tried to load library {}:{}:{}, but version {} was already loaded!", groupId, artifactId, version, currentVer);
78-
return;
81+
if (currentVer.equals(preferredVersion)) return;
82+
val rangeString = "(minimum: " + minVersion + (maxVersion == null ? "" : ", maximum: " + maxVersion) + ")";
83+
if (minVersion.compareTo(currentVer) > 0 || (maxVersion != null && maxVersion.compareTo(currentVer) < 0)) {
84+
for (int i = 0; i < 16; i++) {
85+
libLog.fatal("ALERT VVVVVVVVVVVV ALERT");
86+
}
87+
libLog.fatal("Library {}:{} already loaded with version {}, " +
88+
"but a version in the range {} was requested! Thing may go horribly wrong! " +
89+
"Requested by mod: {}, previously loaded by mod: {}",
90+
groupId, artifactId, currentVer,
91+
rangeString,
92+
loadingModId, loadedLibraryMods.get(artifact));
93+
for (int i = 0; i < 16; i++) {
94+
libLog.fatal("ALERT ^^^^^^^^^^^^ ALERT");
95+
}
96+
} else {
97+
libLog.info("Attempted loading of library {}:{} with preferred version {}, " +
98+
"but version {} was already loaded, which matched the range {}. This is not an error. " +
99+
"Requested by mod: {}, previously loaded by mod: {}",
100+
groupId, artifactId, preferredVersion,
101+
currentVer, rangeString,
102+
loadingModId, loadedLibraryMods.get(artifact));
79103
}
104+
return;
80105
}
81106
val modsDir = new File(CoreLoadingPlugin.mcDir, "mods");
82-
val jarName = String.format("%s-%s%s.jar", artifactId, version, (developerEnvironment && devSuffix != null) ? ("-" + devSuffix) : "");
107+
val jarName = String.format("%s%s-%s%s.jar", isMod ? "" : (groupId + "-"), artifactId, preferredVersion, (developerEnvironment && devSuffix != null) ? ("-" + devSuffix) : "");
83108
File file;
84109
if (isMod) {
85110
file = new File(modsDir, jarName);
@@ -95,32 +120,33 @@ public static void loadLibrary(String groupId, String artifactId, String version
95120
if (!isMod) {
96121
addToClasspath(file);
97122
}
98-
loadedLibraries.put(artifact, version);
99-
libLog.info("Library {}:{}:{} successfully loaded from disk!", groupId, artifactId, version);
123+
loadedLibraries.put(artifact, preferredVersion);
124+
libLog.info("Library {}:{}:{} successfully loaded from disk!", groupId, artifactId, preferredVersion);
100125
return;
101126
} catch (RuntimeException e) {
102-
libLog.warn("Failed to load library {}:{}:{} from file! Redownloading...", groupId, artifactId, version);
127+
libLog.warn("Failed to load library {}:{}:{} from file! Redownloading...", groupId, artifactId, preferredVersion);
103128
file.delete();
104129
}
105130
}
106131
for (var repo: mavenRepositories) {
107132
try {
108133
if (!repo.endsWith("/")) repo = repo + "/";
109-
val url = new URL(String.format("%s%s/%s/%s/%s", repo, groupId.replace('.', '/'), artifactId, version, jarName));
134+
val url = new URL(String.format("%s%s/%s/%s/%s", repo, groupId.replace('.', '/'), artifactId, preferredVersion, jarName));
110135

111136
val connection = (HttpsURLConnection) url.openConnection();
112137
connection.setConnectTimeout(1500);
113138
connection.setReadTimeout(1500);
114139
connection.setRequestProperty("User-Agent", "FalsePatternLib Downloader");
115140
if (connection.getResponseCode() != 200) {
116-
libLog.info("Artifact {}:{}:{} was not found on repo {}", groupId, artifactId, version, repo);
141+
libLog.info("Artifact {}:{}:{} was not found on repo {}", groupId, artifactId, preferredVersion, repo);
117142
connection.disconnect();
118143
continue;
119144
}
120-
libLog.info("Downloading {}:{}:{} from {}", groupId, artifactId, version, repo);
145+
libLog.info("Downloading {}:{}:{} from {}", groupId, artifactId, preferredVersion, repo);
121146
download(connection.getInputStream(), file);
122-
libLog.info("Downloaded {}:{}:{}", groupId, artifactId, version);
123-
loadedLibraries.put(artifact, version);
147+
libLog.info("Downloaded {}:{}:{}", groupId, artifactId, preferredVersion);
148+
loadedLibraries.put(artifact, preferredVersion);
149+
loadedLibraryMods.put(artifact, loadingModId);
124150
if (isMod) {
125151
if (!modWasDownloaded) {
126152
modWasDownloaded = true;
@@ -132,7 +158,9 @@ public static void loadLibrary(String groupId, String artifactId, String version
132158
return;
133159
} catch (IOException ignored) {}
134160
}
135-
throw new IllegalStateException("Failed to download library " + groupId + ":" + artifactId + ":" + version + " from any repository!");
161+
val errorMessage = "Failed to download library " + groupId + ":" + artifactId + ":" + preferredVersion + " from any repository! Requested by mod: " + loadingModId;
162+
libLog.fatal(errorMessage);
163+
throw new IllegalStateException(errorMessage);
136164
}
137165

138166
private static void addToClasspath(File file) {
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package com.falsepattern.lib.api;
2+
3+
import lombok.NonNull;
4+
import lombok.val;
5+
6+
import java.util.Arrays;
7+
import java.util.stream.Collectors;
8+
9+
public class ComplexVersion extends Version {
10+
final Version[] versions;
11+
public ComplexVersion(@NonNull Version mainVersion, Version... subVersions) {
12+
this.versions = new Version[subVersions.length + 1];
13+
this.versions[0] = mainVersion;
14+
System.arraycopy(subVersions, 0, this.versions, 1, subVersions.length);
15+
}
16+
17+
@Override
18+
public int compareTo(@NonNull Version o) {
19+
if (o instanceof ComplexVersion) {
20+
val other = (ComplexVersion) o;
21+
int count = Math.min(versions.length, other.versions.length);
22+
for (int i = 0; i < count; i++) {
23+
val result = versions[i].compareTo(other.versions[i]);
24+
if (result != 0) return result;
25+
}
26+
if (versions.length != other.versions.length) {
27+
return versions.length - other.versions.length;
28+
} else {
29+
return 0;
30+
}
31+
} else if (o instanceof SemanticVersion) {
32+
val other = (SemanticVersion) o;
33+
val result = other.compareTo(versions[0]);
34+
if (result != 0) {
35+
return result;
36+
}
37+
if (versions.length > 1) {
38+
return -1;
39+
}
40+
return 0;
41+
} else {
42+
throw new IllegalArgumentException("Could not compare version with class " + o.getClass().getName());
43+
}
44+
}
45+
46+
@Override
47+
public String toString() {
48+
return Arrays.stream(versions).map(Version::toString).collect(Collectors.joining("-"));
49+
}
50+
}

src/main/java/com/falsepattern/lib/api/DependencyLoader.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
package com.falsepattern.lib.api;
22

33
import com.falsepattern.lib.FalsePatternLib;
4+
import lombok.Builder;
5+
import lombok.NonNull;
46

57
public class DependencyLoader {
6-
public static void loadLibrary(String groupId, String artifactId, String version, String devSuffix, boolean isMod) {
7-
FalsePatternLib.loadLibrary(groupId, artifactId, version, devSuffix, isMod);
8+
@Builder
9+
public static void loadLibrary(String loadingModId, String groupId, String artifactId, @NonNull Version minVersion, Version maxVersion, @NonNull Version preferredVersion, String devSuffix, boolean isMod) {
10+
FalsePatternLib.loadLibrary(loadingModId, groupId, artifactId, minVersion, maxVersion, preferredVersion, devSuffix, isMod);
811
}
912

1013
public static void addMavenRepo(String url) {
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package com.falsepattern.lib.api;
2+
3+
import lombok.Builder;
4+
import lombok.Getter;
5+
import lombok.NonNull;
6+
import lombok.val;
7+
8+
import java.util.Objects;
9+
10+
public class SemanticVersion extends Version {
11+
@Getter
12+
private final int majorVersion;
13+
@Getter
14+
private final int minorVersion;
15+
@Getter
16+
private final int patchVersion;
17+
@Getter
18+
private final String preRelease;
19+
@Getter
20+
private final String build;
21+
22+
@Builder
23+
public SemanticVersion(int majorVersion, int minorVersion, int patchVersion, String preRelease, String build) {
24+
this.majorVersion = majorVersion;
25+
this.minorVersion = minorVersion;
26+
this.patchVersion = patchVersion;
27+
preRelease = preRelease.trim();
28+
build = build.trim();
29+
this.preRelease = "".equals(preRelease) ? null : preRelease;
30+
this.build = "".equals(build) ? null : build;
31+
}
32+
33+
@Override
34+
public int compareTo(@NonNull Version o) {
35+
if (o instanceof ComplexVersion) {
36+
val result = this.compareTo(((ComplexVersion)o).versions[0]);
37+
if (result != 0) {
38+
return result;
39+
} else if (((ComplexVersion) o).versions.length > 1) {
40+
return 1;
41+
} else {
42+
return 0;
43+
}
44+
} else if (o instanceof SemanticVersion) {
45+
val other = (SemanticVersion)o;
46+
if (majorVersion != other.majorVersion) {
47+
return majorVersion - other.majorVersion;
48+
} else if (minorVersion != other.minorVersion) {
49+
return minorVersion - other.minorVersion;
50+
} else if (patchVersion != other.patchVersion) {
51+
return patchVersion - other.patchVersion;
52+
} else if (!Objects.equals(preRelease, other.preRelease)) {
53+
if (preRelease == null) {
54+
return 1;
55+
} else if (other.preRelease == null) {
56+
return -1;
57+
}
58+
return preRelease.compareTo(other.preRelease);
59+
} else {
60+
return 0;
61+
}
62+
}
63+
return 0;
64+
}
65+
66+
@Override
67+
public String toString() {
68+
return majorVersion + "." + minorVersion + "." + patchVersion + (preRelease == null ? "" : "-" + preRelease) + (build == null ? "" : "+" + build);
69+
}
70+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package com.falsepattern.lib.api;
2+
3+
public abstract class Version implements Comparable<Version> {
4+
Version(){}
5+
6+
public boolean equals(Version other) {
7+
return compareTo(other) == 0;
8+
}
9+
10+
@Override
11+
public boolean equals(Object obj) {
12+
if (!(obj instanceof Version)) return false;
13+
return equals((Version) obj);
14+
}
15+
}

0 commit comments

Comments
 (0)