From 46a4a26a546259c07c69532458f83ac711a5ddfc Mon Sep 17 00:00:00 2001 From: Abdessamad Derraz <3028866+Abdess@users.noreply.github.com> Date: Fri, 6 Nov 2026 08:50:29 +0100 Subject: [PATCH] fix: keep bundled game data out of missing verify counted game data installed with its emulator as missing, which cross_reference files as bundled: 24 of Batocera's 427. Bundled firmware already left the lists, and the line naming it never printed. Every bundled entry is now counted on that line, required firmware named and the rest under --verbose. --- scripts/verify.py | 26 ++++++++++++++++++-------- tests/test_verify_listing.py | 27 +++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 8 deletions(-) diff --git a/scripts/verify.py b/scripts/verify.py index f47c7f011..b12991d90 100644 --- a/scripts/verify.py +++ b/scripts/verify.py @@ -1845,6 +1845,13 @@ def _print_undeclared_section(result: dict, verbose: bool) -> None: game_data, bios_files, unplaced = _split_undeclared(undeclared) + # A file installed with its emulator is never collected, firmware or + # game data, required or not: cross_reference counts it apart. The + # firmware already left the pack lists (_mark_unplaced), the game data + # did not, and Abuse's three bundled data files read as missing. + bundled = [u for u in undeclared if not u["in_repo"] and u.get("bundled")] + game_data = [u for u in game_data if u["in_repo"] or not u.get("bundled")] + req_not_in_repo = _core_required_missing(bios_files) req_hle_not_in_repo = [ u @@ -1854,12 +1861,6 @@ def _print_undeclared_section(result: dict, verbose: bool) -> None: req_in_repo = [u for u in bios_files if u["required"] and u["in_repo"]] opt_in_repo = [u for u in bios_files if not u["required"] and u["in_repo"]] opt_not_in_repo = [u for u in bios_files if not u["required"] and not u["in_repo"]] - - bundled = [ - u for u in bios_files - if u["required"] and not u["in_repo"] and u.get("bundled") - and not u.get("hle_fallback") - ] # The builder's count, one file per pack path, when the platform pass # replayed it. Counting entries said 1130 for RetroArch, 48 more than the # pack holds: rom.key alone was claimed by three Amiga cores. @@ -1886,8 +1887,17 @@ def _print_undeclared_section(result: dict, verbose: bool) -> None: for u in opt_not_in_repo: _print_undeclared_entry(u, "MISSING (optional)", verbose, repeated) if bundled: - names = ", ".join(sorted({u["name"] for u in bundled})) - print(f" Bundled with their emulator, not collected: {names}") + # The required firmware is named, as a missing one would be; the + # rest (shaders, runtime libraries, engine data) on request. + shown = bundled if verbose else [ + u for u in bundled + if u["required"] and u.get("category", "bios") != "game_data" + ] + names = ", ".join(sorted({u["name"] for u in shown})) + print( + f" Bundled with their emulator, not collected: {len(bundled)}" + + (f" ({names})" if names else "") + ) if unplaced: print(f" Core files held but not packed: {len(unplaced)} " f"({_omission_reasons(unplaced)})") diff --git a/tests/test_verify_listing.py b/tests/test_verify_listing.py index c825b52a5..209a8dae1 100644 --- a/tests/test_verify_listing.py +++ b/tests/test_verify_listing.py @@ -200,6 +200,33 @@ class EveryGapCountedIsNamed(unittest.TestCase): self.assertIn("MISSING (game data): engine needs level.dat", verbose.getvalue()) +class BundledGameDataIsNotMissing(unittest.TestCase): + """cross_reference put Abuse's abuse.lsp, defaults.prp and english.lsp + under bundled while verify called them missing game data: 24 of the 427 + Batocera counted.""" + + def test_bundled_game_data_is_counted_apart(self): + import contextlib + import io + + sys.path.insert(0, str(REPO_ROOT / "scripts")) + import verify # noqa: PLC0415 + + result = {"undeclared_files": [ + {"name": "abuse.lsp", "emulator": "Abuse", "required": True, + "in_repo": False, "category": "game_data", "bundled": True, + "in_pack": False}, + {"name": "level.dat", "emulator": "engine", "required": True, + "in_repo": False, "category": "game_data"}, + ]} + with contextlib.redirect_stdout(io.StringIO()) as out: + verify._print_undeclared_section(result, verbose=True) + self.assertIn("Game data: 0 in pack, 1 missing", out.getvalue()) + self.assertNotIn("needs abuse.lsp", out.getvalue()) + self.assertIn("Bundled with their emulator, not collected: 1 (abuse.lsp)", + out.getvalue()) + + class CoreCopiesWithoutAGapEntryAreCounted(unittest.TestCase): """verify --platform recalbox --system nec-pc-engine printed no Core files line while the pack held six geargrafx syscard copies: the gap