feat: mark files a core finds by content

DuckStation identifies its BIOS by MD5 in a folder it scans
(bios.cpp:208), so its entries' names are labels. The export wrote them
into Batocera's and ROCKNIX's lists as files to hold: a user with only
scph5501.bin read 104 missing BIOS where DuckStation boots. Labels also
lent their md5 to a name another core opens, and paired by name they
replaced System.dat's scph5000.bin hashes.

found_by: name | content, on a profile or a file and keyed by build like
load_from. The truth records which cores open each name (_named_by). A
label pairs with a platform entry by hash only, is never added, merges
with an opened name only on a shared hash, and is counted in the export
report rather than listed as missing.
This commit is contained in:
Abdessamad Derraz committed 2026-10-20 16:32:22 +02:00
1 parent eaf6d1859d
commit e5174a07bf
8 files changed
+182 -6

No files matched your search

+45
View File
@@ -294,5 +294,50 @@ class ASizeOutsideARangeIsAnotherFile(unittest.TestCase):
self.assertEqual(len(system["files"]), 2)
class TruthRecordsWhoOpensByName(unittest.TestCase):
"""DuckStation finds its BIOS by MD5 in a folder it scans (bios.cpp:208,
397-427): its names are labels. The export wrote them into Batocera's
list as files to hold, and a user with only scph5501.bin read 104
missing BIOS where DuckStation boots."""
DUCK = {"type": "libretro", "systems": ["sony-playstation"], "found_by": "content",
"files": [{"name": "scph1001_v20.bin", "md5": "a" * 32},
{"name": "scph1001.bin", "md5": "b" * 32}]}
PCSX = {"type": "libretro", "systems": ["sony-playstation"],
"files": [{"name": "scph1001.bin", "size": 524288}]}
def truth(self, profiles: dict) -> dict:
config = {"cores": list(profiles), "systems": {"sony-playstation": {"files": []}}}
return generate_platform_truth("p", config, {}, profiles)
def entries(self, truth: dict) -> list[dict]:
return truth["systems"]["sony-playstation"]["files"]
def test_a_content_scanning_core_names_nothing(self):
truth = self.truth({"duckstation": self.DUCK})
self.assertEqual({f["name"]: f["_named_by"] for f in self.entries(truth)},
{"scph1001_v20.bin": [], "scph1001.bin": []})
def test_a_label_lends_no_hash_to_a_name_another_core_opens(self):
"""pcsx_rearmed opens scph1001.bin by name, with no hash: it took the
md5 of DuckStation's label of that name."""
truth = self.truth({"duckstation": self.DUCK, "pcsx": self.PCSX})
named = [f for f in self.entries(truth) if f["_named_by"] == ["pcsx"]]
self.assertEqual(len(named), 1)
self.assertNotIn("md5", named[0])
def test_the_build_decides(self):
ymir = {"type": "standalone + libretro", "systems": ["sega-saturn"],
"found_by": {"standalone": "content"},
"files": [{"name": "sega_101.bin", "md5": "c" * 32}]}
config = {"cores": ["ymir"], "standalone_cores": [],
"systems": {"sega-saturn": {"files": []}}}
libretro = generate_platform_truth("p", config, {}, {"ymir": ymir})
self.assertEqual(libretro["systems"]["sega-saturn"]["files"][0]["_named_by"], ["ymir"])
config["standalone_cores"] = ["ymir"]
standalone = generate_platform_truth("p", config, {}, {"ymir": ymir})
self.assertEqual(standalone["systems"]["sega-saturn"]["files"][0]["_named_by"], [])
if __name__ == "__main__":
unittest.main()