#!/usr/bin/env python3 """Create a deterministic manifest of Web source/generated/runtime assets.""" from __future__ import annotations import hashlib import json from pathlib import Path ROOT = Path(__file__).resolve().parents[1] WEB = ROOT / "web" paths: list[Path] = [] for pattern in ("*.html", "src/*.ts", "src/*.tsx", "public/api/*.json", "public/module-preload.js", "public/modules/*.json"): paths.extend(WEB.glob(pattern)) entries = [] for path in sorted(set(paths)): data = path.read_bytes() entries.append({"path": str(path.relative_to(ROOT)), "bytes": len(data), "sha256": hashlib.sha256(data).hexdigest()}) manifest = { "schema": "freecad-web-release-manifest/v1", "generatedAt": "2026-08-29", "entries": entries, "counts": {"html": sum(entry["path"].endswith(".html") for entry in entries), "source": sum("/src/" in entry["path"] for entry in entries), "apiIndex": sum("/public/api/" in entry["path"] for entry in entries), "moduleArtifacts": sum("/public/modules/" in entry["path"] or entry["path"].endswith("public/module-preload.js") for entry in entries)}, } out = ROOT / "docs/p6/web-release-manifest.json" out.parent.mkdir(parents=True, exist_ok=True) out.write_text(json.dumps(manifest, ensure_ascii=False, indent=2) + "\n", encoding="utf-8") print(json.dumps({"output": str(out.relative_to(ROOT)), "entries": len(entries), "sha256": hashlib.sha256(out.read_bytes()).hexdigest()}, ensure_ascii=False))