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

125 lines
5.5 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 docsRoot = path.join(root, "docs");
const sourceRevision = execFileSync("git", ["-C", sourceRoot, "rev-parse", "HEAD"], { encoding: "utf8" }).trim();
const files = [
"src/Mod/Cloud/CMakeLists.txt",
"src/Mod/Cloud/App/CMakeLists.txt",
"src/Mod/Cloud/App/AppCloud.cpp",
"src/Mod/Cloud/App/AppCloud.h",
"src/Mod/Cloud/Init.py",
"src/Mod/Cloud/InitGui.py",
"src/Mod/Cloud/Gui/CMakeLists.txt",
"src/Mod/Cloud/Gui/AppCloudGui.cpp",
"src/Mod/Cloud/Gui/Command.cpp",
];
const text = (file) => fs.readFileSync(path.join(sourceRoot, file), "utf8");
const lineOf = (file, pattern) => {
const lines = text(file).split(/\r?\n/);
const index = lines.findIndex((line) => line.includes(pattern));
if (index < 0) throw new Error(`pattern not found: ${file}:${pattern}`);
return index + 1;
};
const sourceRef = (file, pattern) => ({ file, line: lineOf(file, pattern) });
const inputs = Object.fromEntries(files.map((file) => [
file,
crypto.createHash("sha256").update(text(file)).digest("hex"),
]));
const report = {
schema: "freecad-web-p6-cloud-source-boundary/v1",
task_id: "FW-P6-CLD-A",
module: "Cloud",
result: "pass_probe_only",
sourceRevision,
cmake: {
target: "Cloud",
kind: "shared_library",
appTarget: "Cloud",
scriptsTarget: "CloudScripts",
buildCondition: "Cloud App is always added; Gui, InitGui.py and CloudGui are gated by BUILD_GUI",
entries: [
sourceRef("src/Mod/Cloud/CMakeLists.txt", "add_subdirectory(App)"),
sourceRef("src/Mod/Cloud/CMakeLists.txt", "if(BUILD_GUI)"),
sourceRef("src/Mod/Cloud/App/CMakeLists.txt", "add_library(Cloud SHARED"),
sourceRef("src/Mod/Cloud/Gui/CMakeLists.txt", "add_library(CloudGui SHARED"),
],
},
dependencies: {
required: ["FreeCADApp", "OpenSSL", "CURL", "XercesC", "Boost", "ZLIB"],
cmake: [
sourceRef("src/Mod/Cloud/CMakeLists.txt", "find_package(OpenSSL REQUIRED)"),
sourceRef("src/Mod/Cloud/CMakeLists.txt", "find_package(CURL REQUIRED)"),
sourceRef("src/Mod/Cloud/App/CMakeLists.txt", "FreeCADApp"),
sourceRef("src/Mod/Cloud/App/CMakeLists.txt", "${XercesC_LIBRARIES}"),
],
network: ["libcurl", "OpenSSL"],
},
registration: {
pythonModule: "Cloud",
entry: sourceRef("src/Mod/Cloud/App/AppCloud.cpp", "PyMOD_INIT_FUNC(Cloud)"),
moduleClass: sourceRef("src/Mod/Cloud/App/AppCloud.h", "class Module: public Py::ExtensionModule<Module>"),
guiModule: sourceRef("src/Mod/Cloud/Gui/AppCloudGui.cpp", "PyMOD_INIT_FUNC(CloudGui)"),
},
actions: {
"create/recompute": {
applicable: false,
reason: "Cloud exposes service configuration and document transfer; no Cloud-specific parametric object is registered.",
entries: [
sourceRef("src/Mod/Cloud/App/AppCloud.h", "class Module: public Py::ExtensionModule<Module>"),
sourceRef("src/Mod/Cloud/App/AppCloud.cpp", "Py::Object Cloud::Module::sCloudURL"),
],
},
"inspect/source-inventory": {
entry: sourceRef("src/Mod/Cloud/Init.py", "FreeCAD init script of the Cloud module"),
registration: sourceRef("src/Mod/Cloud/App/AppCloud.cpp", "PyMOD_INIT_FUNC(Cloud)"),
readOnly: true,
},
"python-api": {
entry: sourceRef("src/Mod/Cloud/App/AppCloud.h", "\"URL\""),
methods: ["URL", "TokenAuth", "TokenSecret", "TCPPort", "Save", "Restore", "ProtocolVersion", "Region"],
implementation: sourceRef("src/Mod/Cloud/App/AppCloud.cpp", "Py::Object Cloud::Module::sCloudSave"),
},
"save/reopen": {
applicable: false,
reason: "Cloud persistence is remote S3-style transfer through Cloud Save/Restore, not a local FCStd save/reopen action.",
save: sourceRef("src/Mod/Cloud/App/AppCloud.cpp", "bool Cloud::Module::cloudSave"),
restore: sourceRef("src/Mod/Cloud/App/AppCloud.cpp", "bool Cloud::Module::cloudRestore"),
persistence: sourceRef("src/Mod/Cloud/App/AppCloud.cpp", "void Cloud::CloudWriter::writeFiles"),
},
},
gui: {
condition: "BUILD_GUI",
workbench: sourceRef("src/Mod/Cloud/InitGui.py", "class CloudWorkbench"),
extension: sourceRef("src/Mod/Cloud/Gui/AppCloudGui.cpp", "PyMOD_INIT_FUNC(CloudGui)"),
command: sourceRef("src/Mod/Cloud/Gui/Command.cpp", "DEF_STD_CMD(CmdCloudTest)"),
excludedFromHeadless: ["FreeCADGui", "PySide", "CloudGui"],
},
boundaries: [
"This is a source probe only; no Cloud runtime, network, browser, or persistence claim is made.",
"Cloud Save/Restore requires configured remote service credentials and is outside the headless source probe.",
"No Cloud-specific parametric object type was found in the inspected module sources.",
],
inputs,
};
fs.mkdirSync(path.join(docsRoot, "p6"), { recursive: true });
fs.writeFileSync(path.join(docsRoot, "p6/cloud-source-boundary.json"), `${JSON.stringify(report, null, 2)}\n`);
fs.writeFileSync(path.join(docsRoot, "freecad-p6-cloud-a-rg.log"), [
`result=${report.result}`,
`sourceRevision=${sourceRevision}`,
`files=${files.length}`,
`target=${report.cmake.target}`,
`guiCondition=${report.cmake.buildCondition}`,
`dependencies=${report.dependencies.required.join(",")}`,
].join("\n") + "\n");
console.log(JSON.stringify({ result: report.result, module: report.module, files: files.length, target: report.cmake.target }));