From 1c7b2e85a4145202e4bbb0e6410717fb7a71fdbc Mon Sep 17 00:00:00 2001 From: Abdessamad Derraz <3028866+Abdess@users.noreply.github.com> Date: Sun, 18 Oct 2026 18:18:19 +0200 Subject: [PATCH] fix: resolve nameless md5 entries as verify does --- scripts/generate_pack.py | 18 +++++++--- tests/test_core_file_fills_declaration.py | 43 +++++++++++++++++++++++ 2 files changed, 57 insertions(+), 4 deletions(-) diff --git a/scripts/generate_pack.py b/scripts/generate_pack.py index d90177a5..bf6920a1 100644 --- a/scripts/generate_pack.py +++ b/scripts/generate_pack.py @@ -778,12 +778,22 @@ def generate_pack( continue if not dest: # EmuDeck-style entries (system:md5 whitelist, no filename). + # Judged as verify judges it: resolved on disk, the md5 + # list parsed once (case, comma lists). fkey = f"{sys_id}/{file_entry.get('name', '')}" - md5 = file_entry.get("md5", "") - if md5 and md5 in db.get("indexes", {}).get("by_md5", {}): - file_status.setdefault(fkey, "ok") - else: + held, held_status = resolve_file( + file_entry, db, bios_dir, zip_contents, + data_dir_registry=data_registry, offline=offline, + ) + if held_status == "not_found" or not held: file_status[fkey] = "missing" + elif baseline_verdict( + file_entry, held, held_status, verification_mode, + config.get("hash_rule", ""), + )[1]: + file_status[fkey] = "excluded" + else: + file_status.setdefault(fkey, "ok") continue if base_dest: full_dest = f"{base_dest}/{dest}" diff --git a/tests/test_core_file_fills_declaration.py b/tests/test_core_file_fills_declaration.py index 1e80a830..afe8bb1d 100644 --- a/tests/test_core_file_fills_declaration.py +++ b/tests/test_core_file_fills_declaration.py @@ -310,5 +310,48 @@ class TwoDeclarationsOfOnePath(unittest.TestCase): self.assertIn("1/1 files OK", printed) +class ANamelessWhitelistEntry(unittest.TestCase): + """EmuDeck lists md5 values with no file name. The builder looked the + raw string up in by_md5: an uppercase value or a comma list was + missing in the pack and met in verify.""" + + def test_the_pack_counts_what_verify_counts(self): + _emulator_profiles_cache.clear() + root = Path(tempfile.mkdtemp(dir=REPO_ROOT / "tmp")) + self.addCleanup(shutil.rmtree, root, True) + bios = root / "bios" / "Sony" / "PlayStation" + bios.mkdir(parents=True) + data = b"PSX BIOS BYTES" + (bios / "scph.bin").write_bytes(data) + sha1, md5 = hashlib.sha1(data).hexdigest(), hashlib.md5(data).hexdigest() + db = { + "files": {sha1: {"path": str(bios / "scph.bin"), "name": "scph.bin", + "md5": md5, "crc32": "", "size": len(data)}}, + "indexes": {"by_md5": {md5: sha1}, "by_name": {"scph.bin": [sha1]}, + "by_crc32": {}, "by_path_suffix": {}}, + } + for folder in ("platforms", "emulators"): + (root / folder).mkdir() + values = [md5.upper(), f"{'0' * 32},{md5}", "f" * 32] + (root / "platforms" / "fakeplat.yml").write_text(yaml.safe_dump({ + "platform": "FakePlat", "verification_mode": "md5", + "base_destination": "bios", "cores": [], + "systems": {"sony-playstation": {"files": [ + {"name": f"sony-playstation:{v}", "destination": "", "md5": v} + for v in values + ]}}, + })) + config = load_platform_config("fakeplat", str(root / "platforms")) + result = verify_platform(config, db, str(root / "emulators")) + out = io.StringIO() + with redirect_stdout(out): + generate_pack( + "fakeplat", str(root / "platforms"), db, str(root / "bios"), + str(root / "out"), emulators_dir=str(root / "emulators"), offline=True, + ) + self.assertEqual(result["status_counts"], {"ok": 2, "missing": 1}) + self.assertIn("2/3 files OK", out.getvalue()) + + if __name__ == "__main__": unittest.main()