Files
FreeCADWasmDev/tools/run_p6_reverseengineering_action02_kernel.mjs
wangdequan 9a7c4f0335 Save FreeCAD Web workspace sources and user validation evidence
IFC native binding remains incomplete; preserve accurate test results.
2026-09-15 22:01:58 +08:00

66 lines
4.5 KiB
JavaScript

import crypto from "node:crypto";
import fs from "node:fs";
import path from "node:path";
import { createRequire } from "node:module";
import { pathToFileURL } from "node:url";
const root = path.resolve(path.dirname(new URL(import.meta.url).pathname), "..");
const docs = path.join(root, "docs/p6");
const build = path.resolve(process.argv[2] ?? path.join(root, "freecad-source/build-web/configure/bin"));
globalThis.__dirname = `${build}${path.sep}`;
globalThis.require = createRequire(import.meta.url);
const loader = await import(pathToFileURL(path.join(build, "FreeCADWebReverseEngineeringRuntimeProbe.js")));
const kernel = await loader.default({ wasmBinary: fs.readFileSync(path.join(build, "FreeCADWebReverseEngineeringRuntimeProbe.wasm")), print: () => {}, printErr: () => {} });
const c = (name, type = "number", argTypes = [], args = []) => kernel.ccall(name, type, argTypes, args);
const entry = "src/Mod/ReverseEngineering/App/AppReverseEngineering.cpp";
const inspect = () => ({
returnCode: c("fc_web_reverseengineering_source_inventory_validate", "number", ["string"], [entry]),
sourceEntry: c("fc_web_reverseengineering_source_entry", "string"),
summary: c("fc_web_reverseengineering_source_summary", "string"),
registeredTypeCount: c("fc_web_reverseengineering_registered_type_count"),
pythonBindingCount: c("fc_web_reverseengineering_python_binding_count"),
pythonApiNames: c("fc_web_reverseengineering_api_names", "string"),
resourcesReleased: c("fc_web_reverseengineering_inventory_resources_released"),
error: c("fc_web_reverseengineering_error", "string")
});
const first = inspect();
const second = inspect();
const invalidEntry = "src/Mod/ReverseEngineering/App/Missing.cpp";
const rejected = {
returnCode: c("fc_web_reverseengineering_source_inventory_validate", "number", ["string"], [invalidEntry]),
error: c("fc_web_reverseengineering_error", "string")
};
const recovered = inspect();
const fixture = { module: "ReverseEngineering", action: "inspect/source-inventory", sourceEntry: entry, pythonBindingCount: 2 };
const hash = value => crypto.createHash("sha256").update(value).digest("hex");
const baselineHash = hash(JSON.stringify(first));
const recoveredHash = hash(JSON.stringify(recovered));
const result = {
first,
second,
rejected,
recovered,
deterministic: JSON.stringify(first) === JSON.stringify(second),
recoveryStable: baselineHash === recoveredHash,
pass: first.returnCode === 1 && second.returnCode === 1 && rejected.returnCode === 0 &&
rejected.error === "revision_mismatch" && recovered.returnCode === 1 &&
first.sourceEntry === entry && first.pythonBindingCount === 2 && first.resourcesReleased === 1
};
const wasmPath = path.join(build, "FreeCADWebReverseEngineeringRuntimeProbe.wasm");
const report = {
schema: "freecad-web-p6-reverseengineering-action-02-kernel/v1",
taskId: "FW-P6-REV-ACT-02-C",
module: "ReverseEngineering",
action: "inspect/source-inventory",
fixture: { ...fixture, inputSha256: hash(JSON.stringify(fixture)) },
result: result.pass && result.deterministic && result.recoveryStable ? "pass" : "fail",
replay: { ...result, baselineSha256: baselineHash, recoveredSha256: recoveredHash, resultSha256: hash(JSON.stringify(result)) },
commands: ["ninja -C freecad-source/build-web/configure FreeCADWebReverseEngineeringRuntimeProbe -j8", "node tools/run_p6_reverseengineering_action02_kernel.mjs freecad-source/build-web/configure/bin"],
artifacts: { wasm: { path: "freecad-source/build-web/configure/bin/FreeCADWebReverseEngineeringRuntimeProbe.wasm", sha256: hash(fs.readFileSync(wasmPath)) }, workerLog: "docs/freecad-p6-reverseengineering-action-02-c-kernel.log" },
boundaries: ["ReverseEngineering App has no persistent DocumentObject registrations in this GUI-free slice; the inventory reports zero native object types and two Python bindings.", "PCL-only APIs and ReverseEngineeringGui remain outside this action."]
};
fs.writeFileSync(path.join(docs, "reverseengineering-action-02-kernel.json"), `${JSON.stringify(report, null, 2)}\n`);
fs.writeFileSync(path.join(root, "docs/freecad-p6-reverseengineering-action-02-c-kernel.log"), `${JSON.stringify({ result: report.result, deterministic: result.deterministic, recoveryStable: result.recoveryStable, pythonBindingCount: first.pythonBindingCount })}\n`);
console.log(JSON.stringify({ result: report.result, deterministic: result.deterministic, recoveryStable: result.recoveryStable, pythonBindingCount: first.pythonBindingCount }));
if (report.result !== "pass") process.exitCode = 1;