Files
workinf_Blender_Wasm/tools/web/generate-blender-parity-map.mjs
mes123456 10640aeb3c
Some checks failed
M6 deployable RC / quick (push) Has been cancelled
M6 deployable RC / chromium (push) Has been cancelled
M6 deployable RC / release (push) Has been cancelled
Govern task context and advance execution pointer
2026-08-20 06:02:43 -04:00

70 lines
5.7 KiB
JavaScript

import crypto from "node:crypto";
import fs from "node:fs";
import path from "node:path";
import { fileURLToPath } from "node:url";
const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../..");
const output = path.resolve(process.argv[2] ?? path.join(root, "tests/golden/M15-02A/blender-parity-map.json"));
const sha256 = (bytes) => crypto.createHash("sha256").update(bytes).digest("hex");
const read = (relative) => { const file = path.join(root, relative); const bytes = fs.readFileSync(file); return { relative, bytes, value: JSON.parse(bytes) }; };
const sources = [
read("tests/golden/M15-01A/blender-rna-datablock-inventory.json"),
read("tests/golden/M15-01B/blender-operator-inventory.json"),
read("tests/golden/M15-01C/blender-family-inventory.json"),
read("tests/golden/M15-01D/blender-format-inventory.json"),
read("tests/golden/M15-01E/blender-editor-inventory.json"),
read("tests/golden/M15-01F/blender-core-inventory.json"),
];
const checkerByTask = {
"M15-01A": "tools/web/check-blender-rna-datablock-inventory.mjs",
"M15-01B": "tools/web/check-blender-operator-inventory.mjs",
"M15-01C": "tools/web/check-blender-family-inventory.mjs",
"M15-01D": "tools/web/check-blender-format-inventory.mjs",
"M15-01E": "tools/web/check-blender-editor-inventory.mjs",
"M15-01F": "tools/web/check-blender-core-inventory.mjs",
};
function item(id, task, ownerFamily, source, detail = {}) {
return { id, task, ownerFamily, implementationClass: "INVENTORY_BASELINE", coverage: "INVENTORIED_ONLY", tests: [checkerByTask[task]], evidence: [`tests/golden/${task}/manifest.json`], source, ...detail };
}
const entries = [];
for (const source of sources) {
const inv = source.value;
const task = inv.task;
if (task === "M15-01A") for (const value of inv.dataBlockTypes) entries.push(item(`datablock:${value.rnaIdentifier}`, task, "RNA_DATABLOCK", source.relative, { rnaIdentifier: value.rnaIdentifier }));
if (task === "M15-01B") for (const value of inv.operators) entries.push(item(`operator:${value.operator}`, task, "OPERATOR", source.relative, { operator: value.operator, poll: value.poll }));
if (task === "M15-01C") {
for (const value of inv.modifiers) entries.push(item(`modifier:${value.identifier}`, task, "MODIFIER", source.relative, { identifier: value.identifier }));
for (const value of inv.constraints) entries.push(item(`constraint:${value.identifier}`, task, "CONSTRAINT", source.relative, { identifier: value.identifier }));
for (const value of inv.nodes) entries.push(item(`node:${value.family}:${value.rnaIdentifier}`, task, `${value.family.toUpperCase()}_NODE`, source.relative, { identifier: value.rnaIdentifier }));
}
if (task === "M15-01D") {
for (const value of inv.stripTypes) entries.push(item(`strip:${value.identifier}`, task, "SEQUENCER", source.relative, { identifier: value.identifier }));
for (const value of inv.physicsTypes) entries.push(item(`physics:${value.rnaIdentifier}`, task, "PHYSICS", source.relative, { identifier: value.rnaIdentifier }));
for (const value of inv.ioOperators) entries.push(item(`io:${value.operator}`, task, "IMPORT_EXPORT", source.relative, { operator: value.operator }));
}
if (task === "M15-01E") {
for (const value of inv.areaTypes) entries.push(item(`area:${value.identifier}`, task, "EDITOR", source.relative, { identifier: value.identifier }));
for (const value of inv.regionTypes) entries.push(item(`region:${value.identifier}`, task, "REGION", source.relative, { identifier: value.identifier }));
for (const value of inv.spaceTypes) entries.push(item(`space:${value.identifier}`, task, "SPACE", source.relative, { identifier: value.identifier }));
for (const value of inv.spaceClasses) entries.push(item(`space-class:${value.rnaIdentifier}`, task, "SPACE", source.relative, { identifier: value.rnaIdentifier }));
for (const value of inv.workspaceModes) entries.push(item(`workspace:${value.identifier}`, task, "WORKSPACE", source.relative, { identifier: value.identifier }));
for (const value of inv.keymaps) {
const key = `${value.name}:${value.spaceType}:${value.regionType}`;
entries.push(item(`keymap:${key}`, task, "KEYMAP", source.relative, { name: value.name, spaceType: value.spaceType, regionType: value.regionType, itemCount: value.items.length }));
for (const [index, keymapItem] of value.items.entries()) entries.push(item(`keymap-item:${key}:${index}`, task, "KEYMAP", source.relative, { keymap: key, idname: keymapItem.idname, type: keymapItem.type, value: keymapItem.value }));
}
}
if (task === "M15-01F") for (const value of inv.classes) entries.push(item(`rna:${value.family}:${value.rnaIdentifier}`, task, value.family, source.relative, { identifier: value.rnaIdentifier }));
}
entries.sort((a, b) => a.id < b.id ? -1 : a.id > b.id ? 1 : 0);
const ids = entries.map((entry) => entry.id);
if (new Set(ids).size !== ids.length) throw new Error("duplicate parity map IDs");
const inventoryRefs = Object.fromEntries(sources.map((source) => [source.value.task, { path: source.relative, sha256: sha256(source.bytes) }]));
const map = { schemaVersion: 1, task: "M15-02A", operation: "BLENDER_PARITY_MAPPING", statusAxis: "INVENTORY_ONLY", implementationClasses: ["INVENTORY_BASELINE"], sourceInventories: inventoryRefs, summary: { mapped: entries.length, byTask: Object.fromEntries(sources.map((source) => [source.value.task, entries.filter((entry) => entry.task === source.value.task).length])), ownerFamilies: [...new Set(entries.map((entry) => entry.ownerFamily))].sort() }, entries, nextTask: "M15-02B" };
fs.mkdirSync(path.dirname(output), { recursive: true });
fs.writeFileSync(output, `${JSON.stringify(map, null, 2)}\n`);
process.stdout.write(`blender-parity-map-generated entries=${entries.length} output=${output} sha256=${sha256(fs.readFileSync(output))}\n`);