fix: refuse a target --verify-packs cannot honour

An unknown target, or one the platform does not publish, was dropped and
the full pack verified under it with rc 0 (finding 34).
This commit is contained in:
Abdessamad Derraz committed 2026-11-05 11:43:53 +01:00
1 parent 609710e2d7
commit 8ef4eb47fc
3 files changed
+41 -11

No files matched your search

+17 -9
View File
@@ -2652,6 +2652,19 @@ def _run_verify_packs(args: argparse.Namespace) -> None:
else: else:
raise ValueError("--verify-packs requires --platform or --all") raise ValueError("--verify-packs requires --platform or --all")
# The target is checked as the build checks it: a mistyped one, or one
# the platform does not publish, was dropped and the full pack verified
# under it, `all OK` for a pack no build had made.
target_cores_cache: dict[str, set[str] | None] = {}
if args.target:
try:
target_cores_cache, platforms = build_target_cores_cache(
platforms, args.target, args.platforms_dir, is_all=args.all
)
except (FileNotFoundError, ValueError) as e:
print(f"ERROR: {e}", file=sys.stderr)
sys.exit(1)
all_ok = True all_ok = True
verify_regions = getattr(args, "regions", None) verify_regions = getattr(args, "regions", None)
verify_profiles = load_emulator_profiles(args.emulators_dir) verify_profiles = load_emulator_profiles(args.emulators_dir)
@@ -2689,7 +2702,7 @@ def _run_verify_packs(args: argparse.Namespace) -> None:
else: else:
print(f" {platform_name}: SKIP (no pack in {args.output_dir})") print(f" {platform_name}: SKIP (no pack in {args.output_dir})")
continue continue
tc = _target_cores_for(platform_name, args.target, args.platforms_dir) tc = target_cores_cache.get(platform_name)
# A group pack and a pack built for the platform alone can both be # A group pack and a pack built for the platform alone can both be
# present, and each one is a pack of this platform. # present, and each one is a pack of this platform.
for pack_name in found: for pack_name in found:
@@ -4877,17 +4890,12 @@ def _target_cores_for(
) -> set[str] | None: ) -> set[str] | None:
"""Cores a target leaves available, or None when no target was asked for. """Cores a target leaves available, or None when no target was asked for.
None means no narrowing, which is what an unfiltered pack expects. Read Called on a platform the build already packed under the target, so the
the way --all builds: a platform without a target file was packed target is known to it: a platform without one is left out of the run.
unnarrowed under the target's name, and checking that pack must not
raise where building it did not.
""" """
if not target_name: if not target_name:
return None return None
try: return load_target_config(platform_name, target_name, platforms_dir)
return load_target_config(platform_name, target_name, platforms_dir)
except (FileNotFoundError, ValueError):
return None
def _expected_pack_names( def _expected_pack_names(
+6 -2
View File
@@ -4,7 +4,8 @@
under the target's name (Recalbox, Lakka, BizHawk, MiSTer, ROCKNIX). The under the target's name (Recalbox, Lakka, BizHawk, MiSTer, ROCKNIX). The
conformance check read the same target without the --all tolerance, raised conformance check read the same target without the --all tolerance, raised
FileNotFoundError on the first of those packs and stopped the run in a FileNotFoundError on the first of those packs and stopped the run in a
traceback after every pack had been written. traceback after every pack had been written. Such a platform is now left
out of a targeted --all run, and the check refuses it as the build does.
""" """
from __future__ import annotations from __future__ import annotations
@@ -31,7 +32,10 @@ class CheckReadsTheTargetLikeTheBuild(unittest.TestCase):
contextlib.redirect_stdout(io.StringIO()): contextlib.redirect_stdout(io.StringIO()):
with self.assertRaises(ValueError): with self.assertRaises(ValueError):
build_target_cores_cache(["recalbox"], "x86_64", platforms, is_all=True) build_target_cores_cache(["recalbox"], "x86_64", platforms, is_all=True)
self.assertIsNone(_target_cores_for("recalbox", "x86_64", platforms)) # The build never packs such a platform under the target, so the
# check refuses it too instead of reading the full pack.
with self.assertRaises(FileNotFoundError):
_target_cores_for("recalbox", "x86_64", platforms)
def test_a_platform_with_a_target_file_is_narrowed(self): def test_a_platform_with_a_target_file_is_narrowed(self):
cores = _target_cores_for("retroarch", "switch", str(REPO_ROOT / "platforms")) cores = _target_cores_for("retroarch", "switch", str(REPO_ROOT / "platforms"))
+18
View File
@@ -116,6 +116,24 @@ class VerifyPackChoice(unittest.TestCase):
dict(zip((name for _p, name in checked), self.variants)), names dict(zip((name for _p, name in checked), self.variants)), names
) )
def test_a_target_the_platform_lacks_is_refused(self):
"""`--platform bizhawk --target rpi4typo --verify-packs` verified the
full pack and said `all OK`, where the build refused the target."""
import contextlib
import io
bizhawk = self.gp._platform_pack_stem(["bizhawk"], "bizhawk", "platforms")
self._touch(f"{bizhawk}_BIOS_Pack.zip")
self._touch(f"{self.stem}_BIOS_Pack.zip")
for platform, target in (("bizhawk", "rpi4typo"), ("retroarch", "swich")):
with self.subTest(platform=platform), \
contextlib.redirect_stdout(io.StringIO()), \
contextlib.redirect_stderr(io.StringIO()), \
self.assertRaises(SystemExit) as ctx:
self._run(self._args(platform=platform, target=target))
self.assertEqual(ctx.exception.code, 1)
self.assertEqual(self.variants, [])
def test_the_run_ends_on_a_summary(self): def test_the_run_ends_on_a_summary(self):
"""A failing pack was named only above its own error lines, and the """A failing pack was named only above its own error lines, and the
log ended on the last platform's OK line.""" log ended on the last platform's OK line."""