aboutsummaryrefslogtreecommitdiff
path: root/scripts/update_manifest.js
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/update_manifest.js')
-rwxr-xr-xscripts/update_manifest.js151
1 files changed, 151 insertions, 0 deletions
diff --git a/scripts/update_manifest.js b/scripts/update_manifest.js
new file mode 100755
index 00000000..1a06a2d7
--- /dev/null
+++ b/scripts/update_manifest.js
@@ -0,0 +1,151 @@
+#!/usr/bin/env node
+
+const fs = require("fs");
+const crypto = require("crypto");
+const path = require("path");
+const ArgumentParser = require("argparse").ArgumentParser;
+
+function isFile(file) {
+ if (!fs.existsSync(file)) {
+ console.error(`File '${file}' not found. Try again.`);
+ throw Error();
+ }
+ return file;
+}
+
+const argParser = new ArgumentParser({
+ addHelp: true,
+ description: "Adds a new latest version to the manifest file based on the " +
+ "provided zip file, including an incremental update."
+});
+argParser.addArgument("manifestFile", {
+ metavar: "<manifest file>", type: isFile
+});
+argParser.addArgument("version", {
+ metavar: "<version>"
+});
+argParser.addArgument([ "-f", "--full" ], {
+ metavar: "<full zip file>", type: isFile, nargs: 1,
+ dest: "fullZipFileArgs"
+});
+argParser.addArgument([ "-i", "--incremental" ], {
+ type: isFile, nargs: 2, dest: "incrementalArgs",
+ metavar: ["<incremental zip file>", "<file containing list of changed files>"]
+});
+argParser.addArgument([ "-e", "--executable" ], {
+ metavar: "[executable file]", nargs: 1,
+ dest: "executableArgs"
+});
+
+const {
+ manifestFile,
+ version,
+ fullZipFileArgs,
+ incrementalArgs,
+ executableArgs
+} = argParser.parseArgs();
+
+const [incrementalZipFile, changesFile] = incrementalArgs || [];
+const [fullZipFile] = fullZipFileArgs || [];
+const [executable] = executableArgs || [];
+
+// Do one final check
+if (!incrementalZipFile && !fullZipFile) {
+ console.error("No download archive specified! Abort.");
+ process.exit(1);
+}
+
+// Do a quick litmus test to prevent deleting everything incorrectly
+if (changesFile && !fs.existsSync("base")) {
+ console.error("The working directory must be set to an " +
+ "asset folder in order for deleted directories " +
+ "to be calculated correctly. Abort.");
+ process.exit(1);
+}
+
+const manifest = JSON.parse(fs.readFileSync(manifestFile));
+
+const dirsDeleted = new Set();
+const specialActions = changesFile ?
+ fs.readFileSync(changesFile)
+ .toString()
+ .trim()
+ .split("\n")
+ .map(line => line.split("\t"))
+ .map(([mode, target, source]) => {
+ switch (mode[0]) {
+ case "D": // Deleted
+ // Check if the folder exists relative to the working
+ // directory, and if not, add it to the dirsDeleted list.
+ // Keep going up the tree to see how many directories were
+ // deleted.
+ let dir = path.dirname(target);
+ while (!dirsDeleted.has(dir) && !fs.existsSync(dir)) {
+ dirsDeleted.add(dir);
+ dir = path.dirname(dir);
+ }
+
+ return { action: "delete", target };
+ case "R": // Renamed
+ // NOTE: Make sure that the launcher's implementation of
+ // the move action also creates directories when needed.
+ return { action: "move", source, target};
+ default:
+ return null;
+ }
+ })
+ // Remove ignored file mode changes
+ .filter(action => action !== null)
+ // Create actions based on directories to be deleted.
+ // Always have deeper directories first, to guarantee that deleting
+ // higher-level directories will succeed.
+ .concat(Array.from(dirsDeleted.values())
+ .sort((a, b) => b.split("/").length - a.split("/").length)
+ .map(dir => {
+ return { action: "deleteDir", target: dir };
+ }))
+ : [];
+
+const urlBase = "https://s3.wasabisys.com/ao-downloads/";
+
+const versionEntry = {
+ version,
+ executable,
+ prev: manifest.versions[0] ? manifest.versions[0].version : undefined,
+ full: fullZipFile ? [
+ {
+ action: "dl",
+ url: urlBase + encodeURIComponent(path.basename(fullZipFile)),
+ hash: crypto.createHash("sha1")
+ .update(fs.readFileSync(fullZipFile))
+ .digest("hex")
+ }
+ ] : undefined,
+ update: incrementalArgs ? [
+ ...specialActions,
+ {
+ action: "dl",
+ url: urlBase + encodeURIComponent(path.basename(incrementalZipFile)),
+ hash: crypto.createHash("sha1")
+ .update(fs.readFileSync(incrementalZipFile))
+ .digest("hex")
+ }
+ ] : undefined
+};
+
+console.log("Generated version entry:", versionEntry);
+
+const existingVersions = manifest.versions.filter(v => v.version == version);
+if (existingVersions.length > 0) {
+ console.warn(`Warning: version ${version} already exists. Adding new values.`);
+
+ // Don't overwrite prev - it will cause headaches
+ delete versionEntry.prev;
+
+ Object.assign(existingVersions[0], versionEntry);
+ console.log("Merged version entry:", existingVersions[0]);
+} else {
+ manifest.versions = [versionEntry, ...manifest.versions];
+}
+
+fs.writeFileSync(manifestFile, JSON.stringify(manifest, null, 4));