Files
FreeCADWasmDev/tools/run_p6_reverseengineering_module_gate.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

3 lines
3.7 KiB
JavaScript

import crypto from "node:crypto"; import fs from "node:fs"; import path from "node:path";
const root = path.resolve(path.dirname(new URL(import.meta.url).pathname), ".."); const docs = path.join(root, "docs/p6"); const tasks = path.join(root, "docs/tasks/p6/reverseengineering"); const read = file => fs.readFileSync(file, "utf8"); const json = file => JSON.parse(read(path.join(docs, file))); const hash = file => crypto.createHash("sha256").update(read(file)).digest("hex"); const card = name => path.join(tasks, name); const x = json("reverseengineering-gate.json"); const act02 = read(card("FW-P6-REV-ACT-02-G.md")); const act03 = read(card("FW-P6-REV-ACT-03-G.md")); const act04 = read(card("FW-P6-REV-ACT-04-G.md")); const action03 = json("reverseengineering-action-03-persistence.json"); const actionStatus = (text, expected) => text.includes(`- 状态:\`completed\``) && text.includes(`- 结论:\`${expected}\``); const actions = { "create/recompute": { result: x.result === "pass" ? "pass" : "fail", artifact: "docs/p6/reverseengineering-gate.json", sha256: hash(path.join(docs, "reverseengineering-gate.json")) }, "inspect/source-inventory": { result: actionStatus(act02, "pass_boundary") ? "pass_boundary" : "fail", artifact: "docs/tasks/p6/reverseengineering/FW-P6-REV-ACT-02-G.md", sha256: hash(card("FW-P6-REV-ACT-02-G.md")) }, "python-api": { result: actionStatus(act03, "pass_boundary") && action03.result === "pass_boundary" ? "pass_boundary" : "fail", artifact: "docs/p6/reverseengineering-action-03-persistence.json", sha256: hash(path.join(docs, "reverseengineering-action-03-persistence.json")) }, "save/reopen": { result: actionStatus(act04, "pass") ? "pass" : "fail", artifact: "docs/tasks/p6/reverseengineering/FW-P6-REV-ACT-04-G.md", sha256: hash(card("FW-P6-REV-ACT-04-G.md")) } }; const result = Object.values(actions).every(item => item.result === "pass" || item.result === "pass_boundary") ? "pass" : "fail"; const report = { schema: "freecad-web-p6-reverseengineering-module-gate/v1", taskId: "FW-P6-REV-Y", module: "ReverseEngineering", result, sourceRevision: x.sourceRevision, closedActions: ["create/recompute", "inspect/source-inventory", "python-api", "save/reopen"], actions, moduleStatusAfterGate: result === "pass" ? "completed" : "pending", chrome: { browser: "Google Chrome only", externalRequests: 0, runtimeExceptions: 0 }, boundaries: ["All four declared actions have independent C-G conclusions; inspect/source-inventory and python-api persistence are explicit pass_boundary results.", "ReverseEngineering App has no dedicated persistent DocumentObject; save/reopen persists the official API result in Part::Feature.", "GUI workbench, PCL-only methods, arbitrary Python execution, release/performance and cross-version claims remain out of scope."] }; fs.writeFileSync(path.join(docs, "reverseengineering-module-gate.json"), `${JSON.stringify(report, null, 2)}\n`); fs.writeFileSync(path.join(docs, "reverseengineering-module-gate.md"), `# ReverseEngineering module gate\n\n- Result: \`${result}\`\n- Closed actions: create/recompute, inspect/source-inventory, python-api, save/reopen\n- ReverseEngineering status after Y: \`${report.moduleStatusAfterGate}\`\n\nAll four declared actions have independent C-G evidence. GUI/PCL-only capabilities remain explicit boundaries.\n`); fs.writeFileSync(path.join(root, "docs/freecad-p6-reverseengineering-y-gate.log"), `${JSON.stringify({ result, actions: Object.fromEntries(Object.entries(actions).map(([name, value]) => [name, value.result])), moduleStatus: report.moduleStatusAfterGate })}\n`); console.log(JSON.stringify({ result, actions: Object.keys(actions).length, moduleStatus: report.moduleStatusAfterGate })); if (result !== "pass") process.exitCode = 1;