From 195fb920368ae585c1b03cd430de872d97e83ee3 Mon Sep 17 00:00:00 2001 From: Abdessamad Derraz <3028866+Abdess@users.noreply.github.com> Date: Sun, 18 Oct 2026 07:14:38 +0200 Subject: [PATCH] fix: name the platform a typo meant in every CLI slots ended a mistyped --platform on a traceback; generate_truth, refresh_data_dirs and auto_fetch exited 0 having done nothing for it. All six now stop on require_platform before any work. --- scripts/auto_fetch.py | 2 ++ scripts/diff_truth.py | 2 ++ scripts/export_native.py | 9 ++++++++- scripts/generate_truth.py | 2 ++ scripts/refresh_data_dirs.py | 5 ++++- scripts/slots.py | 3 +++ tests/test_system_selection.py | 29 +++++++++++++++++++++++++++-- 7 files changed, 48 insertions(+), 4 deletions(-) diff --git a/scripts/auto_fetch.py b/scripts/auto_fetch.py index 092cff4f..61d258a7 100644 --- a/scripts/auto_fetch.py +++ b/scripts/auto_fetch.py @@ -32,6 +32,7 @@ from common import ( list_registered_platforms, load_database, load_platform_config, + require_platform, require_yaml, ) @@ -441,6 +442,7 @@ def main() -> None: include_archived=True, ) elif args.platform: + require_platform(args.platform, args.platforms_dir) platforms = [args.platform] else: parser.error("Specify --platform or --all") diff --git a/scripts/diff_truth.py b/scripts/diff_truth.py index 27138681..b4a1ab2b 100644 --- a/scripts/diff_truth.py +++ b/scripts/diff_truth.py @@ -20,6 +20,7 @@ from common import ( list_registered_platforms, load_platform_config, native_layer, + require_platform, require_yaml, truth_target_dir, yaml_load, @@ -187,6 +188,7 @@ def main() -> None: args.platforms_dir, include_archived=True ) else: + require_platform(args.platform, args.platforms_dir) platforms = [args.platform] reports: list[dict] = [] diff --git a/scripts/export_native.py b/scripts/export_native.py index aba4155b..96200beb 100644 --- a/scripts/export_native.py +++ b/scripts/export_native.py @@ -28,7 +28,13 @@ from pathlib import Path sys.path.insert(0, str(Path(__file__).resolve().parent)) from artifacts import file_lock, write_bytes_atomic, write_text_atomic -from common import list_registered_platforms, load_platform_config, native_layer, yaml_load +from common import ( + list_registered_platforms, + load_platform_config, + native_layer, + require_platform, + yaml_load, +) from exporter import discover_exporters from exporter.baseline import HASH_FIELDS, _hash_values, _single_size, build_native_model @@ -535,6 +541,7 @@ def main() -> None: include_archived=True, ) else: + require_platform(args.platform, args.platforms_dir) platforms = [args.platform] sys.exit( diff --git a/scripts/generate_truth.py b/scripts/generate_truth.py index 259812c4..d4ad251a 100644 --- a/scripts/generate_truth.py +++ b/scripts/generate_truth.py @@ -19,6 +19,7 @@ from common import ( load_emulator_profiles, load_platform_config, load_target_config, + require_platform, require_yaml, truth_target_dir, write_text_atomic, @@ -88,6 +89,7 @@ def main(argv: list[str] | None = None) -> None: include_archived=True, ) else: + require_platform(args.platform, args.platforms_dir) platforms = [args.platform] # A target-narrowed model is a different artifact: written under the diff --git a/scripts/refresh_data_dirs.py b/scripts/refresh_data_dirs.py index dbbbb370..e36f865e 100644 --- a/scripts/refresh_data_dirs.py +++ b/scripts/refresh_data_dirs.py @@ -25,7 +25,7 @@ import urllib.request import zipfile from pathlib import Path from artifacts import file_lock as _file_lock -from common import yaml_load +from common import require_platform, yaml_load try: import yaml @@ -539,6 +539,9 @@ def main() -> None: format="%(message)s", ) + if args.platform: + # The registry sits in the platforms directory it serves. + require_platform(args.platform, os.path.dirname(args.registry) or ".") registry = load_registry(args.registry) if args.key: diff --git a/scripts/slots.py b/scripts/slots.py index a9097135..c40cbe68 100644 --- a/scripts/slots.py +++ b/scripts/slots.py @@ -809,6 +809,7 @@ def main() -> int: list_registered_platforms, load_emulator_profiles, load_platform_config, + require_platform, ) parser = argparse.ArgumentParser( @@ -832,6 +833,8 @@ def main() -> int: with open(args.db, encoding="utf-8") as handle: db = json.load(handle) profiles = load_emulator_profiles(args.emulators_dir) + if args.platform: + require_platform(args.platform, args.platforms_dir) names = ( [args.platform] if args.platform diff --git a/tests/test_system_selection.py b/tests/test_system_selection.py index 654b72ae..3652576b 100644 --- a/tests/test_system_selection.py +++ b/tests/test_system_selection.py @@ -11,6 +11,7 @@ libretro pack. from __future__ import annotations import os +import re import subprocess import sys import tempfile @@ -94,12 +95,28 @@ class AMistypedPlatformIsNamed(unittest.TestCase): """verify and cross_reference ended a typo on a traceback; generate_pack ran its whole build first and then said "no pack for batocra".""" + # Every script taking --platform: slots ended on a traceback, and + # generate_truth, refresh_data_dirs and auto_fetch exited 0 having done + # nothing (or, for refresh_data_dirs, refreshed every unscoped entry). + CLIS = { + "verify.py": [], + "cross_reference.py": [], + "slots.py": [], + "diff_truth.py": [], + "auto_fetch.py": ["--dry-run"], + "refresh_data_dirs.py": ["--dry-run"], + } + def test_every_cli_names_the_platform_it_meant(self): scratch = tempfile.TemporaryDirectory(dir=REPO_ROOT / "tmp") self.addCleanup(scratch.cleanup) out = Path(scratch.name) / "packs" - for script, extra in (("verify.py", []), ("cross_reference.py", []), - ("generate_pack.py", ["--offline", "--output-dir", str(out)])): + writers = { + "generate_pack.py": ["--offline", "--output-dir", str(out)], + "generate_truth.py": ["--output-dir", str(out)], + "export_native.py": ["--output-dir", str(out)], + } + for script, extra in {**self.CLIS, **writers}.items(): with self.subTest(script=script): proc = subprocess.run( [sys.executable, f"scripts/{script}", "--platform", "batocra", *extra], @@ -111,6 +128,14 @@ class AMistypedPlatformIsNamed(unittest.TestCase): self.assertIn("Did you mean 'batocera'?", proc.stderr) self.assertFalse(out.exists()) + def test_the_list_holds_every_script_taking_a_platform(self): + taking = { + path.name for path in (REPO_ROOT / "scripts").glob("*.py") + if re.search(r'add_argument\(\s*"--platform"', path.read_text(encoding="utf-8")) + } + listed = set(self.CLIS) | {"generate_pack.py", "generate_truth.py", "export_native.py"} + self.assertEqual(taking - listed, set()) + class StrictVerifyFailsOnACriticalMiss(unittest.TestCase): """verify exited 0 with a required file missing on an md5 platform, so