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

73 lines
5.2 KiB
JavaScript

#!/usr/bin/env node
import crypto from "node:crypto";
import fs from "node:fs";
import path from "node:path";
import { execFileSync } from "node:child_process";
const root = path.resolve(path.dirname(new URL(import.meta.url).pathname), "..");
const sourceRoot = path.join(root, "freecad-source");
const docs = path.join(root, "docs/p6");
const runRg = (pattern, files) => execFileSync("rg", ["-n", pattern, ...files], { cwd: sourceRoot, encoding: "utf8" }).trim().split("\n").filter(Boolean);
const fileHash = (relative) => crypto.createHash("sha256").update(fs.readFileSync(path.join(sourceRoot, relative))).digest("hex");
const sourceFiles = [
"src/Mod/Material/CMakeLists.txt",
"src/Mod/Material/App/CMakeLists.txt",
"src/Mod/Material/Gui/CMakeLists.txt",
"src/Mod/Material/App/AppMaterial.cpp",
"src/Mod/Material/Gui/AppMatGui.cpp",
];
const report = {
schema: "freecad-web-p6-material-source-boundary/v1",
taskId: "FW-P6-MAT-A",
module: "Material",
result: "pass_boundary",
sourceRevision: execFileSync("git", ["rev-parse", "HEAD"], { cwd: sourceRoot, encoding: "utf8" }).trim(),
commands: ["rg -n \"BUILD_|Init|addObject|registerType|PyInit\" src/Mod/Material"],
cmake: {
module: { file: "src/Mod/Material/CMakeLists.txt", appLine: 3, guiGuardLines: [5, 7], scriptsLines: [9, 17] },
app: { file: "src/Mod/Material/App/CMakeLists.txt", target: "Materials", targetLine: 138, webDefinitionLines: [140, 142], externalGuardLines: [11, 13, 127, 136], dependencies: ["FreeCADApp", "QtConcurrent", "yaml-cpp"], linkLine: 173 },
gui: { file: "src/Mod/Material/Gui/CMakeLists.txt", target: "MatGui", targetLine: 159, externalGuardLines: [9, 11, 52, 57, 129, 138], dependencies: ["Materials", "FreeCADGui", "QtConcurrent"], linkLine: 198 },
},
appBoundary: {
moduleEntry: { file: "src/Mod/Material/App/AppMaterial.cpp", line: 76, symbol: "PyMOD_INIT_FUNC(Materials)" },
pythonTypes: { file: "src/Mod/Material/App/AppMaterial.cpp", lines: [88, 99], names: ["Array2D", "Array3D", "MaterialFilter", "MaterialFilterOptions", "MaterialLibrary", "MaterialManager", "MaterialProperty", "Material", "ModelManager", "ModelProperty", "Model", "UUIDs"] },
nativeTypes: { file: "src/Mod/Material/App/AppMaterial.cpp", lines: [105, 131], count: 27, externalConditional: [112, 115] },
pythonSources: { file: "src/Mod/Material/App/CMakeLists.txt", lines: [56, 82], generatedBindings: 12 },
},
guiBoundary: {
moduleEntry: { file: "src/Mod/Material/Gui/AppMatGui.cpp", line: 77, symbol: "PyMOD_INIT_FUNC(MatGui)" },
guiDependencyGuard: { file: "src/Mod/Material/Gui/AppMatGui.cpp", lines: [79, 82], condition: "Gui::Application::Instance" },
materialModuleImport: { file: "src/Mod/Material/Gui/AppMatGui.cpp", lines: [84, 91], import: "Materials" },
registration: { file: "src/Mod/Material/Gui/AppMatGui.cpp", lines: [97, 128], symbols: ["MatGui::Workbench", "MatGui::MaterialTreeWidget"] },
},
actionEntrypoints: [
{ file: "src/Mod/Material/Init.py", kind: "module-script" },
{ file: "src/Mod/Material/InitGui.py", kind: "gui-script" },
{ file: "src/Mod/Material/importFCMat.py", kind: "import-script" },
{ file: "src/Mod/Material/MaterialEditor.py", kind: "material-editor" },
{ file: "src/Mod/Material/App/MaterialManager.cpp", kind: "native-material-manager" },
{ file: "src/Mod/Material/App/PropertyMaterial.cpp", kind: "document-property" },
],
conditions: {
gui: "BUILD_GUI controls the MatGui subdirectory",
external: "BUILD_MATERIAL_EXTERNAL adds external manager sources and GUI migration/settings sources",
runtime: "This card records source boundaries only; no WASM runtime or browser capability is claimed.",
},
matches: {
module: runRg("add_subdirectory|BUILD_GUI", ["src/Mod/Material/CMakeLists.txt"]),
app: runRg("BUILD_MATERIAL_EXTERNAL|generate_from_py|add_library\\(Materials|FREECAD_WEB|target_link_libraries", ["src/Mod/Material/App/CMakeLists.txt"]),
gui: runRg("BUILD_MATERIAL_EXTERNAL|add_library\\(MatGui|target_link_libraries", ["src/Mod/Material/Gui/CMakeLists.txt"]),
appEntry: runRg("PyMOD_INIT_FUNC|addType|::init\\(\\)", ["src/Mod/Material/App/AppMaterial.cpp"]),
guiEntry: runRg("PyMOD_INIT_FUNC|Gui::Application|import Materials|::init\\(\\)", ["src/Mod/Material/Gui/AppMatGui.cpp"]),
},
sourceSha256: Object.fromEntries(sourceFiles.map((file) => [file, fileHash(file)])),
boundaries: [
"App and Gui are separate targets; BUILD_GUI gates only Gui while Materials remains the native App target.",
"BUILD_MATERIAL_EXTERNAL is conditional and is not counted as available in the Web boundary without an explicit dependency closure.",
"No runtime probe, API parity, persistence, or Chrome result is inferred from this source inventory.",
],
};
fs.writeFileSync(path.join(docs, "material-source-boundary.json"), `${JSON.stringify(report, null, 2)}\n`);
fs.writeFileSync(path.join(root, "docs/freecad-p6-material-a-boundary.log"), `${JSON.stringify({ result: report.result, sourceRevision: report.sourceRevision, appTarget: report.cmake.app.target, guiTarget: report.cmake.gui.target, externalConditional: true })}\n`);
console.log(JSON.stringify({ result: report.result, appTarget: report.cmake.app.target, guiTarget: report.cmake.gui.target, sourceFiles: sourceFiles.length }));