#!/usr/bin/env python3 import hashlib import json import pathlib import sys import tempfile import bpy OBJECT_NAME = "WebGapAssetMarkObject" def object_state(): obj = bpy.data.objects.get(OBJECT_NAME) if obj is None: raise RuntimeError("asset mark fixture object is missing") metadata = obj.asset_data return { "name": obj.name, "assetMarked": metadata is not None, "author": metadata.author if metadata is not None else "", "description": metadata.description if metadata is not None else "", "tags": sorted(tag.name for tag in metadata.tags) if metadata is not None else [], } def main(): arguments = sys.argv[sys.argv.index("--") + 1 :] if len(arguments) != 2: raise SystemExit( "usage: blender -b --factory-startup --python " "check-action-asset-mark-desktop.py -- FIXTURE REPORT" ) fixture, output = (pathlib.Path(value).resolve() for value in arguments) output.unlink(missing_ok=True) bpy.ops.wm.open_mainfile(filepath=str(fixture), load_ui=False) before = object_state() accepted_errors = ( "No data-block selected", "context is incorrect", "supports asset operations", ) try: poll = bool(bpy.ops.asset.mark.poll()) except RuntimeError as error: if not any(token in str(error) for token in accepted_errors): raise poll = False if poll: raise RuntimeError("asset.mark unexpectedly polled true without an editor ID context") try: bpy.ops.asset.mark() except RuntimeError as error: if not any(token in str(error) for token in accepted_errors): raise operator_status = "CANCELLED" else: raise RuntimeError("asset.mark unexpectedly finished without an editor ID context") after_cancel = object_state() if after_cancel != before: raise RuntimeError(f"asset.mark cancellation changed Main data: {before} != {after_cancel}") with tempfile.NamedTemporaryFile( prefix="m16-asset-mark-reopen-", suffix=".blend", dir=fixture.parent ) as temporary: bpy.ops.wm.save_as_mainfile(filepath=temporary.name, check_existing=False, compress=True) bpy.ops.wm.open_mainfile(filepath=temporary.name, load_ui=False) after = object_state() if after != before: raise RuntimeError(f"asset.mark save/reopen drift: {before} != {after}") report = { "schemaVersion": 1, "task": "M16-GAP-00279", "operation": "ASSET_MARK_DESKTOP", "fixture": str(fixture), "fixtureSha256": hashlib.sha256(fixture.read_bytes()).hexdigest(), "before": before, "after": after, "poll": poll, "operatorStatus": operator_status, "mainMutation": "NONE", "saveReopen": "EXACT", "blenderVersion": bpy.app.version_string, } output.parent.mkdir(parents=True, exist_ok=True) output.write_text(json.dumps(report, indent=2, sort_keys=True) + "\n", encoding="utf-8") print("asset-mark-desktop-ok poll=false status=CANCELLED mainMutation=none saveReopen=exact") if __name__ == "__main__": try: main() except Exception as error: print(f"asset-mark-desktop-failed: {error}") raise SystemExit(1)