Files
codex/codex-webui/scripts/sync-rust-assets.mjs
2026-05-02 17:16:20 -03:00

86 lines
2.3 KiB
JavaScript

#!/usr/bin/env node
import { createHash } from "node:crypto";
import {
cpSync,
existsSync,
mkdirSync,
readdirSync,
readFileSync,
rmSync,
} from "node:fs";
import { dirname, join, relative, resolve } from "node:path";
import { fileURLToPath } from "node:url";
const __filename = fileURLToPath(import.meta.url);
const packageRoot = resolve(dirname(__filename), "..");
const repoRoot = resolve(packageRoot, "..");
const distRoot = join(packageRoot, "dist");
const rustAssetsRoot = join(repoRoot, "codex-rs", "web-server", "assets");
const check = process.argv.includes("--check");
if (!existsSync(join(distRoot, "index.html"))) {
throw new Error("Missing dist/index.html. Run the codex-webui build first.");
}
if (check) {
const diff = diffTrees(distRoot, rustAssetsRoot);
if (diff.length > 0) {
throw new Error(
`codex web assets are out of date:\n${diff.map((item) => ` ${item}`).join("\n")}`,
);
}
console.log("codex web Rust assets are up to date.");
} else {
rmSync(rustAssetsRoot, { force: true, recursive: true });
mkdirSync(rustAssetsRoot, { recursive: true });
cpSync(distRoot, rustAssetsRoot, { recursive: true });
console.log(
`Synced ${relative(repoRoot, distRoot)} to ${relative(repoRoot, rustAssetsRoot)}.`,
);
}
function diffTrees(leftRoot, rightRoot) {
const leftFiles = listFiles(leftRoot);
const rightFiles = listFiles(rightRoot);
const allFiles = new Set([...leftFiles.keys(), ...rightFiles.keys()]);
const diff = [];
for (const file of [...allFiles].sort()) {
const left = leftFiles.get(file);
const right = rightFiles.get(file);
if (!left) {
diff.push(`unexpected ${file}`);
} else if (!right) {
diff.push(`missing ${file}`);
} else if (left !== right) {
diff.push(`changed ${file}`);
}
}
return diff;
}
function listFiles(root) {
const files = new Map();
if (!existsSync(root)) {
return files;
}
walk(root, root, files);
return files;
}
function walk(root, dir, files) {
for (const entry of readdirSync(dir, { withFileTypes: true })) {
const path = join(dir, entry.name);
if (entry.isDirectory()) {
walk(root, path, files);
} else if (entry.isFile()) {
files.set(relative(root, path), sha256(path));
}
}
}
function sha256(path) {
return createHash("sha256").update(readFileSync(path)).digest("hex");
}