Skip to content

Commit 4b3e0e2

Browse files
Merge pull request #22 from LostLuma/feature/loom-ploceus-version-lookup
Fetch latest Loom and Ploceus versions for the develop page
2 parents 542aa46 + 6565bd1 commit 4b3e0e2

2 files changed

Lines changed: 102 additions & 24 deletions

File tree

public/develop.js

Lines changed: 63 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import {
66
getLatestRavenBuilds,
77
getLatestSparrowBuilds,
88
getLatestNestsBuilds,
9+
getLoomVersions,
10+
getPloceusVersions,
911
getVersionDetails,
1012
isSharedVersioning
1113
} from "./meta_maven_utils.js";
@@ -15,7 +17,6 @@ import { normalizeMinecraftVersion } from "./minecraft_semver.js";
1517
(async () => {
1618
const FABRIC_LOOM = "net.fabricmc.fabric-loom-remap"
1719
const QUILT_LOOM = "org.quiltmc.loom.remap"
18-
const LOOM_VERSION = "1.15-SNAPSHOT"
1920
const PLOCEUS = "ploceus"
2021

2122
const FABRIC_LOADER = "net.fabricmc:fabric-loader"
@@ -57,22 +58,60 @@ import { normalizeMinecraftVersion } from "./minecraft_semver.js";
5758
return Object.entries(dependencyManagementSelectorRadios).find(([_, button]) => button.checked)[0];
5859
}
5960

61+
function isStable(version) {
62+
return !version.includes("-");
63+
}
64+
65+
function significantPrefix(version) {
66+
return version.split(".").splice(0, 2).join(".");
67+
}
68+
69+
function highestCompatibleVersions(loomVersions, ploceusVersions) {
70+
// Map of major.minor -> latest patch of the same major.minor
71+
const ploceusLookup = new Map(ploceusVersions.reverse().filter(isStable).map(version => {
72+
return [significantPrefix(version), version];
73+
}));
74+
75+
for (const loomVersion of loomVersions) {
76+
if (!isStable(loomVersion)) {
77+
continue;
78+
}
79+
80+
const prefix = significantPrefix(loomVersion);
81+
const ploceusVersion = ploceusLookup.get(prefix);
82+
83+
if (ploceusVersion) {
84+
return [loomVersion, ploceusVersion];
85+
}
86+
}
87+
88+
throw new Error("Unable to compute recommended Loom and Ploceus versions");
89+
}
90+
6091
async function updateDisplayedElements() {
6192
const minecraftVersion = selectedMinecraftVersion();
6293
const intermediaryGen = selectedCalamusGeneration();
6394
const modLoader = selectedModLoader();
6495
const dependencyManagement = selectedDependencyManagement();
65-
96+
6697
if (minecraftVersions.includes(minecraftVersion)) {
6798
const versionDetails = await getVersionDetails(intermediaryGen, minecraftVersion);
68-
const loaderVersion = await getLatestLoaderVersion(modLoader);
69-
const featherBuilds = await getLatestFeatherBuilds(intermediaryGen, versionDetails);
70-
const ravenBuilds = await getLatestRavenBuilds(versionDetails);
71-
const sparrowBuilds = await getLatestSparrowBuilds(versionDetails);
72-
const nestsBuilds = await getLatestNestsBuilds(versionDetails);
73-
const oslVersion = await getLatestOslVersion(intermediaryGen);
99+
100+
const [loaderVersion, loomVersions, ploceusVersions, featherBuilds, ravenBuilds, sparrowBuilds, nestsBuilds, oslVersion] = await Promise.all(
101+
[
102+
getLatestLoaderVersion(modLoader),
103+
getLoomVersions(modLoader),
104+
getPloceusVersions(),
105+
getLatestFeatherBuilds(intermediaryGen, versionDetails),
106+
getLatestRavenBuilds(versionDetails),
107+
getLatestSparrowBuilds(versionDetails),
108+
getLatestNestsBuilds(versionDetails),
109+
getLatestOslVersion(intermediaryGen),
110+
]
111+
);
74112

75113
const sharedVersioning = isSharedVersioning(versionDetails);
114+
const [loomVersion, ploceusVersion] = highestCompatibleVersions(loomVersions, ploceusVersions);
76115

77116
// wait for requests to finish to avoid flicker
78117
hideElements();
@@ -86,7 +125,7 @@ import { normalizeMinecraftVersion } from "./minecraft_semver.js";
86125
break;
87126
case "versionCatalog":
88127
showElement("version-catalog");
89-
await displayVersionCatalog(versionDetails, intermediaryGen, modLoader, loaderVersion, featherBuilds, ravenBuilds, sparrowBuilds, nestsBuilds, oslVersion);
128+
await displayVersionCatalog(versionDetails, intermediaryGen, modLoader, loaderVersion, loomVersion, ploceusVersion, featherBuilds, ravenBuilds, sparrowBuilds, nestsBuilds, oslVersion);
90129
break;
91130
default:
92131
throw new Error(`Unknown dependency management type ${dependencyManagement}`);
@@ -95,13 +134,13 @@ import { normalizeMinecraftVersion } from "./minecraft_semver.js";
95134
const singleProject = (intermediaryGen != "gen1" || !sharedVersioning || versionDetails.sharedMappings || !versionDetails.client || !versionDetails.server);
96135

97136
if (singleProject) {
98-
await displayBuildScript(versionDetails, intermediaryGen, modLoader, loaderVersion, featherBuilds, ravenBuilds, sparrowBuilds, nestsBuilds, oslVersion, dependencyManagement);
137+
await displayBuildScript(versionDetails, intermediaryGen, modLoader, loaderVersion, loomVersion, ploceusVersion, featherBuilds, ravenBuilds, sparrowBuilds, nestsBuilds, oslVersion, dependencyManagement);
99138

100139
if (dependencyManagement === "propertiesFile") {
101140
await displayProjectProperties(versionDetails, intermediaryGen, modLoader, loaderVersion, featherBuilds, ravenBuilds, sparrowBuilds, nestsBuilds, oslVersion);
102141
}
103142
} else {
104-
await displayBuildScriptForGen1Split("root", versionDetails, intermediaryGen, modLoader, loaderVersion, featherBuilds, ravenBuilds, sparrowBuilds, nestsBuilds, oslVersion, dependencyManagement);
143+
await displayBuildScriptForGen1Split("root", versionDetails, intermediaryGen, modLoader, loaderVersion, loomVersion, ploceusVersion, featherBuilds, ravenBuilds, sparrowBuilds, nestsBuilds, oslVersion, dependencyManagement);
105144

106145
if (dependencyManagement === "propertiesFile") {
107146
await displayProjectPropertiesForGen1Split("root", versionDetails, intermediaryGen, modLoader, loaderVersion, featherBuilds, ravenBuilds, sparrowBuilds, nestsBuilds, oslVersion, dependencyManagement);
@@ -111,14 +150,14 @@ import { normalizeMinecraftVersion } from "./minecraft_semver.js";
111150
showElement("client.build.gradle");
112151
showElement("client.gradle.properties");
113152

114-
await displayBuildScriptForGen1Split("client", versionDetails, intermediaryGen, modLoader, loaderVersion, featherBuilds, ravenBuilds, sparrowBuilds, nestsBuilds, oslVersion, dependencyManagement);
153+
await displayBuildScriptForGen1Split("client", versionDetails, intermediaryGen, modLoader, loaderVersion, loomVersion, ploceusVersion, featherBuilds, ravenBuilds, sparrowBuilds, nestsBuilds, oslVersion, dependencyManagement);
115154
await displayProjectPropertiesForGen1Split("client", versionDetails, intermediaryGen, modLoader, loaderVersion, featherBuilds, ravenBuilds, sparrowBuilds, nestsBuilds, oslVersion, dependencyManagement);
116155
}
117156
if (versionDetails.server) {
118157
showElement("server.build.gradle");
119158
showElement("server.gradle.properties");
120159

121-
await displayBuildScriptForGen1Split("server", versionDetails, intermediaryGen, modLoader, loaderVersion, featherBuilds, ravenBuilds, sparrowBuilds, nestsBuilds, oslVersion, dependencyManagement);
160+
await displayBuildScriptForGen1Split("server", versionDetails, intermediaryGen, modLoader, loaderVersion, loomVersion, ploceusVersion, featherBuilds, ravenBuilds, sparrowBuilds, nestsBuilds, oslVersion, dependencyManagement);
122161
await displayProjectPropertiesForGen1Split("server", versionDetails, intermediaryGen, modLoader, loaderVersion, featherBuilds, ravenBuilds, sparrowBuilds, nestsBuilds, oslVersion, dependencyManagement);
123162
}
124163
}
@@ -187,7 +226,7 @@ import { normalizeMinecraftVersion } from "./minecraft_semver.js";
187226
}
188227
}
189228

190-
async function displayBuildScript(minecraftVersion, intermediaryGen, modLoader, loaderVersion, featherBuilds, ravenBuilds, sparrowBuilds, nestsBuilds, oslVersion, dependencyManagement) {
229+
async function displayBuildScript(minecraftVersion, intermediaryGen, modLoader, loaderVersion, loomVersion, ploceusVersion, featherBuilds, ravenBuilds, sparrowBuilds, nestsBuilds, oslVersion, dependencyManagement) {
191230
const sharedVersioning = isSharedVersioning(minecraftVersion);
192231
const elementId = "build.gradle.content";
193232

@@ -197,16 +236,16 @@ import { normalizeMinecraftVersion } from "./minecraft_semver.js";
197236

198237
switch (modLoader) {
199238
case "fabric":
200-
plugins.push(`\t${generatePluginDefinition(FABRIC_LOOM, "loom", LOOM_VERSION, dependencyManagement)}`);
239+
plugins.push(`\t${generatePluginDefinition(FABRIC_LOOM, "loom", loomVersion, dependencyManagement)}`);
201240
break;
202241
case "quilt":
203-
plugins.push(`\t${generatePluginDefinition(QUILT_LOOM, "loom", LOOM_VERSION, dependencyManagement)}`);
242+
plugins.push(`\t${generatePluginDefinition(QUILT_LOOM, "loom", loomVersion, dependencyManagement)}`);
204243
break;
205244
default:
206245
throw new Error("unknown mod loader " + modLoader);
207246
}
208247

209-
plugins.push(`\t${generatePluginDefinition(PLOCEUS, "ploceus", LOOM_VERSION, dependencyManagement)}`);
248+
plugins.push(`\t${generatePluginDefinition(PLOCEUS, "ploceus", ploceusVersion, dependencyManagement)}`);
210249

211250
if (plugins) {
212251
plugins.unshift("plugins {");
@@ -327,7 +366,7 @@ import { normalizeMinecraftVersion } from "./minecraft_semver.js";
327366
}
328367
}
329368

330-
async function displayBuildScriptForGen1Split(project, minecraftVersion, intermediaryGen, modLoader, loaderVersion, featherBuilds, ravenBuilds, sparrowBuilds, nestsBuilds, oslVersion, dependencyManagement) {
369+
async function displayBuildScriptForGen1Split(project, minecraftVersion, intermediaryGen, modLoader, loaderVersion, loomVersion, ploceusVersion, featherBuilds, ravenBuilds, sparrowBuilds, nestsBuilds, oslVersion, dependencyManagement) {
331370
if (project == "root") {
332371
const elementId = "build.gradle.content";
333372

@@ -337,16 +376,16 @@ import { normalizeMinecraftVersion } from "./minecraft_semver.js";
337376

338377
switch (modLoader) {
339378
case "fabric":
340-
plugins.push(`\t${generatePluginDefinition(FABRIC_LOOM, "loom", LOOM_VERSION, dependencyManagement, false)}`);
379+
plugins.push(`\t${generatePluginDefinition(FABRIC_LOOM, "loom", loomVersion, dependencyManagement, false)}`);
341380
break;
342381
case "quilt":
343-
plugins.push(`\t${generatePluginDefinition(QUILT_LOOM, "loom", LOOM_VERSION, dependencyManagement, false)}`);
382+
plugins.push(`\t${generatePluginDefinition(QUILT_LOOM, "loom", loomVersion, dependencyManagement, false)}`);
344383
break;
345384
default:
346385
throw new Error("unknown mod loader " + modLoader);
347386
}
348387

349-
plugins.push(`\t${generatePluginDefinition(PLOCEUS, "ploceus", LOOM_VERSION, dependencyManagement, false)}`);
388+
plugins.push(`\t${generatePluginDefinition(PLOCEUS, "ploceus", ploceusVersion, dependencyManagement, false)}`);
350389

351390
if (plugins) {
352391
plugins.unshift("plugins {");
@@ -563,7 +602,7 @@ import { normalizeMinecraftVersion } from "./minecraft_semver.js";
563602
}
564603
}
565604

566-
async function displayVersionCatalog(minecraftVersion, intermediaryGen, modLoader, loaderVersion, featherBuilds, ravenBuilds, sparrowBuilds, nestsBuilds, oslVersion) {
605+
async function displayVersionCatalog(minecraftVersion, intermediaryGen, modLoader, loaderVersion, loomVersion, ploceusVersion, featherBuilds, ravenBuilds, sparrowBuilds, nestsBuilds, oslVersion) {
567606
const elementId = "version-catalog.content";
568607
const lines = [];
569608

@@ -616,8 +655,8 @@ import { normalizeMinecraftVersion } from "./minecraft_semver.js";
616655
}
617656

618657
lines.push(``);
619-
lines.push(`loom = "${LOOM_VERSION}"`);
620-
lines.push(`ploceus = "${LOOM_VERSION}"`);
658+
lines.push(`loom = "${loomVersion}"`);
659+
lines.push(`ploceus = "${ploceusVersion}"`);
621660

622661
lines.push(``);
623662
lines.push(`[libraries]`);

public/meta_maven_utils.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,3 +212,42 @@ export function isSharedVersioning(minecraftVersion) {
212212
const fc = minecraftVersion.id.charAt(0);
213213
return !(fc == 'r' || fc == 'p' || fc == 'c' || fc == 'i' || fc == 'a' || fc == 's');
214214
}
215+
216+
async function getVersionsFromMavenMetadata(url) {
217+
const response = await fetch(url);
218+
const data = await response.text();
219+
220+
const parser = new DOMParser();
221+
const document = parser.parseFromString(data, "text/xml");
222+
const versions = document.getElementsByTagName("version");
223+
224+
const results = [];
225+
226+
for (const version of versions) {
227+
results.push(version.textContent);
228+
}
229+
230+
return results.sort((left, right) => compareVersion(left, right));
231+
}
232+
233+
export async function getLoomVersions(modLoader) {
234+
let base;
235+
236+
switch (modLoader) {
237+
case "fabric":
238+
base = "https://maven.fabricmc.net/net/fabricmc/fabric-loom-remap/net.fabricmc.fabric-loom-remap.gradle.plugin";
239+
break;
240+
case "quilt":
241+
base = "https://maven.quiltmc.org/repository/release/org/quiltmc/loom/remap/org.quiltmc.loom.remap.gradle.plugin";
242+
break;
243+
default:
244+
throw new Error("unknown mod loader " + modLoader);
245+
}
246+
247+
return await getVersionsFromMavenMetadata(`${base}/maven-metadata.xml`);
248+
}
249+
250+
export async function getPloceusVersions() {
251+
const url = `https://${MAVEN}/releases/net/ornithemc/ploceus/maven-metadata.xml`;
252+
return await getVersionsFromMavenMetadata(url);
253+
}

0 commit comments

Comments
 (0)