Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feather diff viewer #5

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
132 changes: 12 additions & 120 deletions public/develop.js
Original file line number Diff line number Diff line change
@@ -1,123 +1,15 @@
(async () => {

const URL = "ornithemc.net";
const META = "meta." + URL;
const VERSION = "v3";


function makeMetaUrl(...pathComponents) {
let url = META + "/" + VERSION;
for (const pathComponent of pathComponents) {
url += "/";
url += pathComponent;
}
return "https://" + url;
}

async function getFromMeta(...pathComponents) {
const response = await fetch(makeMetaUrl(...pathComponents));
return response.json();
}

async function getMinecraftVersionsMeta() {
return await getFromMeta("versions", "game");
}

async function getFeatherVersionMeta(mcVersion) {
return await getFromMeta("versions", "feather", mcVersion);
}

async function getRavenVersionMeta(mcVersion) {
return await getFromMeta("versions", "raven", mcVersion);
}

async function getSparrowVersionMeta(mcVersion) {
return await getFromMeta("versions", "sparrow", mcVersion);
}

async function getNestsVersionMeta(mcVersion) {
return await getFromMeta("versions", "nests", mcVersion);
}

async function getLoaderVersionsMeta(loader) {
return await getFromMeta("versions", loader + "-loader");
}

async function getOslVersionsMeta() {
return await getFromMeta("versions", "osl");
}

function compareVersion(sv1, sv2) {
function rec(v1, v2) {
if (v1.length === 0 && v2.length === 0) return 0;
if (v1.length === 0) return 1;
if (v2.length === 0) return -1;
const [head1, ...tail1] = v1;
const [head2, ...tail2] = v2;
const ih1 = parseInt(head1);
const ih2 = parseInt(head2);
if (ih1 < ih2) return 1;
if (ih1 > ih2) return -1;
return rec(tail1, tail2);
}

return rec(sv1.split("."), sv2.split("."));
}

async function getMinecraftVersions() {
return await getMinecraftVersionsMeta()
.then(l => l.map(v => v.version));
}

async function getMinecraftStableVersions() {
return await getMinecraftVersionsMeta()
.then(l => l.filter(v => v.stable))
.then(l => l.map(v => v.version));
}

async function getLatestFeatherBuild(mcVersion) {
return await getFeatherVersionMeta(mcVersion)
.then(l => l.sort((e1, e2) => e2.build - e1.build))
.then(s => { console.log(s); return s; })
.then(([head, ..._]) => head)
.then(e => e !== undefined ? e.build : null);
}

async function getLatestRavenBuild(mcVersion) {
return await getRavenVersionMeta(mcVersion)
.then(l => l.sort((e1, e2) => e2.build - e1.build))
.then(([head, ..._]) => head)
.then(e => e !== undefined ? e.build : null);
}

async function getLatestSparrowBuild(mcVersion) {
return await getSparrowVersionMeta(mcVersion)
.then(l => l.sort((e1, e2) => e2.build - e1.build))
.then(([head, ..._]) => head)
.then(e => e !== undefined ? e.build : null);
}

async function getLatestNestsBuild(mcVersion) {
return await getNestsVersionMeta(mcVersion)
.then(l => l.sort((e1, e2) => e2.build - e1.build))
.then(([head, ..._]) => head)
.then(e => e !== undefined ? e.build : null);
}

async function getLatestLoader(loader) {
return await getLoaderVersionsMeta(loader)
.then(l => l.filter(e => e.stable))
.then(([head, ..._]) => head)
.then(e => e.version);
}

async function getLatestOsl() {
return await getOslVersionsMeta()
.then(l => l.sort((e1, e2) => compareVersion(e1.version, e2.version)))
.then(([head, ..._]) => head)
.then(e => e.version);
}
import {
getMinecraftStableVersions,
getMinecraftVersions,
getLatestLoader,
getLatestOsl,
getLatestFeatherBuild,
getLatestRavenBuild,
getLatestSparrowBuild,
getLatestNestsBuild
} from "./meta_maven_utils.js";

(async () => {
const minecraftStableVersions = await getMinecraftStableVersions();
const minecraftAllVersions = await getMinecraftVersions();

Expand Down Expand Up @@ -281,6 +173,6 @@

possibleVersions = minecraftStableVersions;
updateVersionList()
updateOrnitheDependencies()
await updateOrnitheDependencies()

})()
165 changes: 165 additions & 0 deletions public/feather_diff.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
// diffMappings, printDiff, diffMemberArray from https://github.com/modmuss50/YarnDiff/tree/master

import {
getFeatherBuildMaven,
getFeatherVersionMeta,
getMinecraftStableVersions,
getMinecraftVersions,
} from "./meta_maven_utils.js";

import { decompressSync } from "https://cdn.skypack.dev/fflate@0.8.2?min";
import * as tiny from "./tiny_mappings.js";

(async () => {
const minecraftStableVersions = await getMinecraftStableVersions();
const minecraftAllVersions = await getMinecraftVersions();

let possibleVersions;

const versionSelectorInput = document.getElementById("mc-version");
const versionListElement = document.getElementById("version-list");
const allowSnapshotsCheck = document.getElementById("allow-snapshots");

const buildSourceElement = document.getElementById("build-source");
const buildTargetElement = document.getElementById("build-target");
const diffViewerElement = document.getElementById("diff-viewer");

const hideClassPath = document.getElementById("hide-class-path");

async function updateFeatherBuilds() {
if (
possibleVersions.some((version) => versionSelectorInput.value === version)
) {
await getFeatherVersionMeta(versionSelectorInput.value).then(
(featherVersionMeta) => {
buildSourceElement.innerHTML = "";
buildTargetElement.innerHTML = "";
for (const featherVersion of featherVersionMeta) {
const featherVersionElement = document.createElement("option");
featherVersionElement.innerText = "Build " + featherVersion.build;
featherVersionElement.value = featherVersion.version;
buildSourceElement.appendChild(featherVersionElement);
buildTargetElement.appendChild(
featherVersionElement.cloneNode(true),
);
}
},
);

// Hide the diff viewer bc the source and target builds are the same
diffViewerElement.style.display = "none";
}
}

async function getTinyMappings(version) {
let arrayBuf = await getFeatherBuildMaven(version)
.then((response) => response.blob()) // Get response as a Blob
.then(async (blob) => {
const arrayBuffer = await blob.arrayBuffer(); // Convert Blob to ArrayBuffer
// Convert to Uint8Array
return new Uint8Array(arrayBuffer);
});
const decompressed = decompressSync(arrayBuf);
const decoder = new TextDecoder("utf-8");
const file = decoder.decode(decompressed);
return tiny.parseTiny(file);
}

async function updateFeatherDiff() {
const source = buildSourceElement.value;
const target = buildTargetElement.value;

if (source === target) {
console.log("Source and target builds are the same");
// Hide the diff viewer
diffViewerElement.style.display = "none";
return;
}
// Display the diff viewer
diffViewerElement.style.display = "inline";

const sourceMappings = await getTinyMappings(source);
const targetMappings = await getTinyMappings(target);

diffMappings(sourceMappings, targetMappings);
}

function diffMappings(source, target) {
printDiff(diffMemberArray(source.classes, target, hideClassPath.checked), "classes-diff")
printDiff(diffMemberArray(source.methods, target), "methods-diff")
printDiff(diffMemberArray(source.fields, target), "fields-diff")
}

function printDiff(diff, elementID) {
document.getElementById(elementID).innerText = diff.map(value => `${value.source} -> ${value.target}`).join("\n")
}

function diffMemberArray(source, targetMappings, stripPath = false) {
let diff = []

source.forEach(source => {
let target = targetMappings.find(source.calamus)

if (target !== undefined && source.feather !== target.feather) {
let sourceFeather = source.feather;
let targetFeather = target.feather;

if (stripPath) {
if (sourceFeather.substring(0, sourceFeather.lastIndexOf('/')) === targetFeather.substring(0, targetFeather.lastIndexOf('/'))) {
sourceFeather = sourceFeather.split('/').pop();
targetFeather = targetFeather.split('/').pop();
}
}

diff.push({
source: sourceFeather,
target: targetFeather
})
}
})
return diff
}

versionSelectorInput.addEventListener(
"input",
async (_) => await updateFeatherBuilds(),
);

allowSnapshotsCheck.addEventListener("change", (_) => {
if (allowSnapshotsCheck.checked) {
possibleVersions = minecraftAllVersions;
} else {
possibleVersions = minecraftStableVersions;
}
updateVersionList();
});

buildSourceElement.addEventListener(
"change",
async (_) => await updateFeatherDiff(),
);

buildTargetElement.addEventListener(
"change",
async (_) => await updateFeatherDiff(),
);

hideClassPath.addEventListener("change", async (_) => {
await updateFeatherDiff();
});

function updateVersionList() {
const list = possibleVersions;
while (versionListElement.firstChild)
versionListElement.removeChild(versionListElement.lastChild);
list.forEach((e) => {
const opt = new Option();
opt.value = e;
versionListElement.appendChild(opt);
});
}

possibleVersions = minecraftStableVersions;
updateVersionList();
await updateFeatherBuilds();
})();
Loading