From 5945bb0b61f656c764c21af28040225e678e5297 Mon Sep 17 00:00:00 2001 From: Codex Date: Mon, 19 Oct 2026 19:55:02 +0200 Subject: [PATCH] Fail closed when Rayforge runtime is missing --- scripts/check_rayforge_windows_gui.py | 34 +++++++++++--------- tests/test_rayforge_windows_gui_preflight.py | 9 ++++++ 2 files changed, 28 insertions(+), 15 deletions(-) diff --git a/scripts/check_rayforge_windows_gui.py b/scripts/check_rayforge_windows_gui.py index c76cacc..281c193 100644 --- a/scripts/check_rayforge_windows_gui.py +++ b/scripts/check_rayforge_windows_gui.py @@ -11,21 +11,25 @@ from pathlib import Path def inspect(rayforge: Path, python_env: Path) -> dict[str, object]: msys2_shell = Path("C:/msys64/msys2_shell.cmd") msys2_env = rayforge / ".msys2_env" - gi_probe = subprocess.run( - [str(python_env), "-c", "import gi"], - capture_output=True, - text=True, - check=False, - ) - gi_available = gi_probe.returncode == 0 - gi_error = next( - ( - line.strip() - for line in reversed(gi_probe.stderr.splitlines()) - if line.strip() - ), - "unable to import gi", - ) + if python_env.is_file(): + gi_probe = subprocess.run( + [str(python_env), "-c", "import gi"], + capture_output=True, + text=True, + check=False, + ) + gi_available = gi_probe.returncode == 0 + gi_error = next( + ( + line.strip() + for line in reversed(gi_probe.stderr.splitlines()) + if line.strip() + ), + "unable to import gi", + ) + else: + gi_available = False + gi_error = "python runtime not found" app_entry = rayforge / "rayforge" / "__main__.py" addon_manifest = ( Path(__file__).parents[1] diff --git a/tests/test_rayforge_windows_gui_preflight.py b/tests/test_rayforge_windows_gui_preflight.py index fe9f2ef..271f1d0 100644 --- a/tests/test_rayforge_windows_gui_preflight.py +++ b/tests/test_rayforge_windows_gui_preflight.py @@ -1,6 +1,9 @@ import json import unittest from pathlib import Path +import tempfile + +from scripts.check_rayforge_windows_gui import inspect ROOT = Path(__file__).parents[1] @@ -30,6 +33,12 @@ class RayforgeWindowsGuiPreflightTests(unittest.TestCase): def test_result_records_the_requested_runtime_probe(self): self.assertIn("No module named 'gi'", self.result["observed_launch_error"]) + def test_missing_runtime_path_fails_closed(self): + with tempfile.TemporaryDirectory() as temporary: + result = inspect(Path(temporary), Path(temporary) / "missing-python.exe") + self.assertFalse(result["ready_for_manual_gui_test"]) + self.assertEqual("python runtime not found", result["observed_launch_error"]) + if __name__ == "__main__": unittest.main()