Accumulated uncommitted work: GHOST Web backend, WebGL/GPU web layer, web workflow engine and protocol, tooling, docs and task records. Large generated evidence, user-testing archives, build snapshots and imported test assets remain untracked. Co-Authored-By: Claude Code <noreply@anthropic.com>
25 lines
2.8 KiB
Python
25 lines
2.8 KiB
Python
"""Read back the actual GUI-produced quit.blend using original native recovery."""
|
|
import argparse, hashlib, json, pathlib, sys
|
|
import bpy
|
|
assert bpy.app.version == (5, 2, 0) and sys.platform != "emscripten"
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument("--work-dir", required=True)
|
|
args = parser.parse_args(sys.argv[sys.argv.index("--") + 1:])
|
|
work = pathlib.Path(args.work_dir).resolve(); expected_path = work / "native-last-session-expected.json"; expected = json.loads(expected_path.read_text())
|
|
assert bpy.app.background, "Readback must not generate another GUI-exit quit file"
|
|
assert expected["schemaVersion"] == 1 and expected["kind"] == "source-derived-original-native-exit" and expected["phase"] == "EXPECTED_STATE_WRITTEN_QUIT_PENDING"
|
|
producer = pathlib.Path(__file__).with_name("native-last-session-prepare.py")
|
|
assert expected["producerSha256"] == hashlib.sha256(producer.read_bytes()).hexdigest()
|
|
quit_file = pathlib.Path(expected["quitFile"]).resolve(); assert quit_file == work / "native-temp" / "quit.blend"
|
|
quit_bytes = quit_file.read_bytes(); assert quit_bytes; quit_sha256 = hashlib.sha256(quit_bytes).hexdigest()
|
|
assert expected["expectedMain"]["filepath"] == str(work / "source-session.blend")
|
|
bpy.context.preferences.filepaths.temporary_directory = str(quit_file.parent)
|
|
assert pathlib.Path(bpy.app.tempdir).parent == quit_file.parent
|
|
assert bpy.ops.wm.recover_last_session("EXEC_DEFAULT", use_scripts=False) == {"FINISHED"}
|
|
actual = {"filepath": bpy.data.filepath, "scene": bpy.context.scene.name, "marker": bpy.context.scene.get("wbv2_last_session_unsaved"), "objects": sorted(obj.name for obj in bpy.data.objects), "images": {image.name: {"pixels": list(image.pixels[:4]), "size": list(image.size), "packed": bool(image.packed_file)} for image in bpy.data.images if image.source == "FILE"}}
|
|
assert actual == expected["expectedMain"], "Actual native quit recovery differs from the producer Main"
|
|
assert hashlib.sha256(quit_file.read_bytes()).hexdigest() == quit_sha256, "Readback changed the original quit artifact"
|
|
receipt = {"schemaVersion": 1, "kind": "desktop-native-quit-readback", "phase": "NATIVE_QUIT_READBACK_CAPTURED", "acceptance": "NOT_CLAIMED", "inputSha256": expected["inputSha256"], "producerSha256": expected["producerSha256"], "readerSha256": hashlib.sha256(pathlib.Path(__file__).read_bytes()).hexdigest(), "expectedReceiptSha256": hashlib.sha256(expected_path.read_bytes()).hexdigest(), "quitFile": {"path": str(quit_file), "bytes": len(quit_bytes), "sha256": quit_sha256}, "actualMain": actual, "version": list(bpy.app.version), "platform": sys.platform, "nativeBinary": str(pathlib.Path(bpy.app.binary_path).resolve())}
|
|
with (work / "native-last-session-readback.json").open("x") as stream: json.dump(receipt, stream, indent=2)
|
|
print("WBV2_NATIVE_QUIT_READBACK", str(work / "native-last-session-readback.json"), flush=True)
|