diff --git a/scripts/generate_pack.py b/scripts/generate_pack.py index 78579542..665034e7 100644 --- a/scripts/generate_pack.py +++ b/scripts/generate_pack.py @@ -474,7 +474,9 @@ def _select_variants( required_only=required_only, ) if regions: - region_index = region_mod.build_region_index(emu_profiles or {}) + region_index = region_mod.platform_region_index( + config, emu_profiles or {}, target_cores + ) region_drops = region_mod.resolve_region_drops( region_groups, region_index, regions ) @@ -3366,7 +3368,9 @@ def _manifest_selection( required_only=required_only, extras_out=extras, ) - region_index = region_mod.build_region_index(emu_profiles) + region_index = region_mod.platform_region_index( + config, emu_profiles, target_cores + ) drops = ( region_mod.resolve_region_drops(region_groups, region_index, regions) if regions diff --git a/scripts/packverify.py b/scripts/packverify.py index c4eecdb0..087357f7 100644 --- a/scripts/packverify.py +++ b/scripts/packverify.py @@ -572,7 +572,9 @@ def verify_pack_against_platform( region_drops: set[str] = set() if regions: - region_index = region_mod.build_region_index(emu_profiles) + region_index = region_mod.platform_region_index( + config, emu_profiles, target_cores + ) region_groups, _extra_dests = platform_region_groups( config, expected_systems, diff --git a/scripts/region.py b/scripts/region.py index d6336caa..9ae04912 100644 --- a/scripts/region.py +++ b/scripts/region.py @@ -125,6 +125,22 @@ def region_tag(requested: list[str]) -> str: ) +def platform_region_index( + config: dict, profiles: dict, target_cores: set[str] | None = None +) -> dict[str, dict]: + """The region index of the emulators a platform runs, nothing else. + + Built over every profile, an emulator foreign to the platform voided the + filter: Pizza Boy SC, an Android app, declares bios_CD_E.bin without a + region, so the Genesis Plus GX and PicoDrive tags never counted and + `--region us` kept both CD BIOSes in the RetroArch pack. + """ + from common import resolve_platform_cores + + cores = resolve_platform_cores(config, profiles, target_cores=target_cores) + return build_region_index({n: profiles[n] for n in cores if n in profiles}) + + def build_region_index(profiles: dict) -> dict[str, dict]: """Build a region lookup from emulator profiles. diff --git a/scripts/verify.py b/scripts/verify.py index 1b46639e..40343b85 100644 --- a/scripts/verify.py +++ b/scripts/verify.py @@ -973,7 +973,9 @@ def verify_platform( target_cores=target_cores, ) region_drops = region_mod.resolve_region_drops( - region_groups, region_mod.build_region_index(profiles), regions + region_groups, + region_mod.platform_region_index(config, profiles, target_cores), + regions, ) # A destination two systems declare with two hashes ships one file, the diff --git a/tests/test_region_platform_index.py b/tests/test_region_platform_index.py new file mode 100644 index 00000000..a91bf96f --- /dev/null +++ b/tests/test_region_platform_index.py @@ -0,0 +1,44 @@ +"""A platform's region filter listens to the emulators it runs only. + +The index was built over every profile: Pizza Boy SC, an Android app no +frontend here runs as a core, declares bios_CD_E.bin without a region, which +voided the [europe] tag Genesis Plus GX and PicoDrive give it, and +`--region us` kept both foreign Mega-CD BIOSes in the RetroArch pack. +""" + +from __future__ import annotations + +import sys +import unittest +from pathlib import Path + +REPO_ROOT = Path(__file__).resolve().parents[1] +sys.path.insert(0, str(REPO_ROOT / "scripts")) + +import region as region_mod # noqa: E402 + +PROFILES = { + "gpgx": {"emulator": "GPGX", "type": "libretro", "systems": ["sega-mega-cd"], + "files": [{"name": "bios_CD_E.bin", "region": ["europe"]}]}, + "pizza": {"emulator": "Pizza", "type": "standalone", "systems": ["sega-mega-cd"], + "files": [{"name": "bios_CD_E.bin"}]}, +} + + +class OnlyThePlatformsCores(unittest.TestCase): + def test_a_foreign_untagged_entry_does_not_void_the_tag(self): + config = {"cores": ["gpgx"], "systems": {"sega-mega-cd": {"files": []}}} + index = region_mod.platform_region_index(config, PROFILES) + self.assertFalse(index["bios_CD_E.bin"]["has_untagged"]) + self.assertTrue(region_mod.build_region_index(PROFILES)["bios_CD_E.bin"]["has_untagged"]) + + def test_every_platform_site_reads_it(self): + for module in ("verify.py", "generate_pack.py", "packverify.py"): + source = (REPO_ROOT / "scripts" / module).read_text(encoding="utf-8") + self.assertNotIn("build_region_index(emu_profiles", source, module) + self.assertNotIn("build_region_index(profiles)", source, module) + self.assertIn("platform_region_index(", source, module) + + +if __name__ == "__main__": + unittest.main()