From 9ba63e6a540c3b98b7c856e5250649d4bdb595ba Mon Sep 17 00:00:00 2001 From: Abdessamad Derraz <3028866+Abdess@users.noreply.github.com> Date: Sun, 18 Oct 2026 02:50:58 +0200 Subject: [PATCH] fix: refuse a platform list where one is taken generate_pack split --platform on commas to validate it, then used the whole string as one platform and crashed. Every script takes a single platform; a list is refused with a message pointing at --all. --- scripts/common.py | 7 +++++++ scripts/generate_pack.py | 3 +-- tests/test_audit_regressions.py | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/scripts/common.py b/scripts/common.py index ca90a94e..a9a2484e 100644 --- a/scripts/common.py +++ b/scripts/common.py @@ -424,6 +424,13 @@ def require_platform(name: str, platforms_dir: str = "platforms") -> None: A typo used to end in a traceback (verify, cross_reference) or in "no pack for batocra" after the whole build ran (generate_pack). """ + if "," in name: + # generate_pack split the list to validate it, then used the whole + # string as one name and ended in a traceback. + raise SystemExit( + f"ERROR: --platform takes one platform, not '{name}'. " + "Run once per platform, or use --all." + ) if os.path.exists(os.path.join(platforms_dir, f"{name}.yml")): return import difflib # noqa: PLC0415 diff --git a/scripts/generate_pack.py b/scripts/generate_pack.py index b3d14433..bf64cbcd 100644 --- a/scripts/generate_pack.py +++ b/scripts/generate_pack.py @@ -2917,8 +2917,7 @@ def _main(held: contextlib.ExitStack) -> None: args = parser.parse_args() packresolve.set_offline(bool(args.offline)) if args.platform: - for name in args.platform.split(","): - require_platform(name.strip(), args.platforms_dir) + require_platform(args.platform, args.platforms_dir) _refuse_unapplied_flags(args, parser) if args.target: diff --git a/tests/test_audit_regressions.py b/tests/test_audit_regressions.py index 94798a0b..cf8b9647 100644 --- a/tests/test_audit_regressions.py +++ b/tests/test_audit_regressions.py @@ -375,6 +375,38 @@ class VerboseAppliesToJson(unittest.TestCase): self.assertNotIn('if d["status"] != Status.OK\n ]', source) +class OnePlatformPerFlag(unittest.TestCase): + """generate_pack validated --platform as a comma list, then used the whole + string as one name: `--platform bizhawk,misterfpga` passed and ended in a + FileNotFoundError traceback. Every script now says it takes one name.""" + + def test_a_list_is_refused_with_a_message(self): + import subprocess + + runs = { + "generate_pack.py": ["--list-systems"], + "verify.py": [], + "cross_reference.py": [], + } + for script, extra in runs.items(): + with self.subTest(script=script): + completed = subprocess.run( + [sys.executable, f"scripts/{script}", "--platform", + "bizhawk,misterfpga", *extra], + capture_output=True, text=True, cwd=ROOT, timeout=600, check=False, + ) + self.assertNotEqual(completed.returncode, 0) + self.assertIn("takes one platform", completed.stderr) + self.assertNotIn("Traceback", completed.stderr) + + def test_unknown_names_still_get_a_suggestion(self): + from common import require_platform + + with self.assertRaises(SystemExit) as caught: + require_platform("batocra", str(ROOT / "platforms")) + self.assertIn("batocera", str(caught.exception)) + + class FaqRegressions(unittest.TestCase): """The FAQ states facts the code owns; these tie it back to the source.