#!/usr/bin/env node import { createHash } from "node:crypto"; import { readFileSync, writeFileSync } from "node:fs"; import { resolve } from "node:path"; import { fileURLToPath } from "node:url"; const root = resolve(fileURLToPath(import.meta.url), "../../.."); const mode = process.argv.includes("--write") ? "write" : "check"; const artifactPaths = [ "wasm-port/build/wasm/sim-configs-inventory/boundary-summary.tsv", "wasm-port/build/wasm/sim-configs-inventory/ini-boundary-summary.tsv", ]; const targetFiles = [ "wasm-port/runtime/sdk/src/linuxcnc-hal.js", "wasm-port/runtime/sdk/src/project-release-readiness.js", ]; function escapeRegExp(text) { return String(text).replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } function sha256(path) { return createHash("sha256") .update(readFileSync(resolve(root, path))) .digest("hex"); } const hashes = Object.fromEntries(artifactPaths.map((path) => [path, sha256(path)])); function replaceHashBlock(text) { let nextText = text; for (const [artifactPath, hash] of Object.entries(hashes)) { const pattern = new RegExp(`("${escapeRegExp(artifactPath)}":\\s*\\n\\s*")[a-f0-9]{64}(")`, "g"); nextText = nextText.replace(pattern, `$1${hash}$2`); } return nextText; } const staleFiles = []; for (const targetFile of targetFiles) { const absolutePath = resolve(root, targetFile); const text = readFileSync(absolutePath, "utf8"); const nextText = replaceHashBlock(text); if (nextText !== text) { staleFiles.push(targetFile); if (mode === "write") { writeFileSync(absolutePath, nextText); } } } if (staleFiles.length > 0 && mode === "check") { console.error(`sim_config_boundary_hashes=stale files=${staleFiles.join(",")}`); console.error("run: wasm-port/tools/update_sim_config_boundary_hashes.sh --write"); process.exit(1); } for (const [artifactPath, hash] of Object.entries(hashes)) { console.log(`${artifactPath} ${hash}`); } console.log(`sim_config_boundary_hashes=${staleFiles.length === 0 ? "ok" : "updated"}`);