#!/usr/bin/env node
// checks an incremental render against a fresh one of the same generation: every page both
// kept reads the same once shared names are masked, and every shared file a page names is
// in its repo's store
// node verify.mjs <incremental out> <fresh out>
import { existsSync, readdirSync, readFileSync, realpathSync } from "node:fs";
import path from "node:path";
import { gunzipSync } from "node:zlib";
import { fileOf, readJson } from "./common.mjs";
import { latestPath, maskShared, SHARED_DIR, sharedNamed } from "./shared.mjs";
const [incremental, fresh] = process.argv.slice(2);
const html = (out, state, route) => {
const dir = realpathSync(path.join(out, "site", state.did));
return maskShared(gunzipSync(readFileSync(path.join(dir, fileOf(state.prefix, route) + ".gz"))).toString());
};
const result = { compared: 0, differ: [], only_incremental: 0, only_fresh: 0, missing_shared: [], latest_differ: [] };
for (const name of readdirSync(path.join(incremental, "state"))) {
const a = readJson(path.join(incremental, "state", name));
const b = readJson(path.join(fresh, "state", name));
if (!a?.pages || !b?.pages) continue;
const dir = realpathSync(path.join(incremental, "site", a.did));
for (const hash of sharedNamed(a.pages, a.latest)) {
if (!existsSync(path.join(dir, SHARED_DIR, hash + ".json.gz"))) result.missing_shared.push(`${a.prefix} ${hash}`);
}
for (const name of Object.keys(a.latest ?? {})) {
if (!existsSync(path.join(dir, latestPath(name) + ".gz"))) result.missing_shared.push(`${a.prefix} ${name}`);
// a name the fresh render points elsewhere is the newest copy going stale, not a broken page
if (b.latest?.[name] !== a.latest[name]) result.latest_differ.push(`${a.prefix} ${name}`);
}
for (const route of Object.keys(a.pages)) {
if (!(route in b.pages)) {
result.only_incremental++;
continue;
}
result.compared++;
if (html(incremental, a, route) !== html(fresh, b, route)) result.differ.push(route);
}
result.only_fresh += Object.keys(b.pages).filter((route) => !(route in a.pages)).length;
}
console.log(JSON.stringify(result));
process.exitCode = result.differ.length > 0 || result.missing_shared.length > 0 ? 1 : 0;