mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-10-10 21:43:23 -05:00
fix: settle a core file only by its size or slot
This commit is contained in:
1 parent
be45eda62d
commit
f6da2cff3a
10 files changed
+321
-135
No files matched your search
@@ -89,14 +89,14 @@ Full list with per-file details: **[https://abdess.github.io/retrobios/](https:/
|
||||
| Batocera | 353/353 | 12,287/12,718 | MD5 hash |
|
||||
| BizHawk | 118/118 | 800/801 | SHA1 hash |
|
||||
| EmuDeck | 168/168 | 430/432 | MD5 hash |
|
||||
| Lakka | 526/526 | 5,256/5,286 | file presence |
|
||||
| Lakka | 526/526 | 5,258/5,288 | file presence |
|
||||
| MiSTer FPGA | 81/81 | - | MD5 hash |
|
||||
| ROCKNIX | 38/38 | 5,695/5,725 | MD5 hash |
|
||||
| Recalbox | 351/351 | 2,721/2,729 | MD5 hash |
|
||||
| RetroArch | 526/526 | 5,256/5,286 | file presence |
|
||||
| RetroBat | 348/348 | 11,875/12,305 | MD5 hash |
|
||||
| Recalbox | 351/351 | 2,726/2,734 | MD5 hash |
|
||||
| RetroArch | 526/526 | 5,258/5,288 | file presence |
|
||||
| RetroBat | 348/348 | 11,876/12,306 | MD5 hash |
|
||||
| RetroDECK | 2,008/2,008 | 5,387/5,437 | MD5 hash |
|
||||
| RetroPie * | 526/526 | 9,171/9,313 | file presence |
|
||||
| RetroPie * | 526/526 | 9,175/9,317 | file presence |
|
||||
| RomM | 381/381 | 746/752 | MD5 hash |
|
||||
|
||||
Each fraction is what the pack has over what is needed, counting required and optional files alike since both ship. The first column is the BIOS list the platform publishes. The second counts files its emulators load that this list never mentions, found by reading their source code, and it is routinely several times larger. A short fraction means files are still missing, and they are named in the [gap analysis](https://abdess.github.io/retrobios/gaps/).
|
||||
@@ -180,4 +180,4 @@ The scripts and tooling are released under the [MIT License](LICENSE).
|
||||
The BIOS and firmware files are not covered by that license: they are third-party system software, preserved and provided for personal backup, archival, and interoperability with emulation software. [NOTICE](NOTICE) sets out their status and how to ask for a file to be removed.
|
||||
The reasoning, and where it is weakest, is in the [FAQ](https://abdess.github.io/retrobios/wiki/faq/#is-this-legal).
|
||||
|
||||
*Auto-generated on 2026-10-10T05:32:25Z*
|
||||
*Auto-generated on 2026-10-10T07:00:25Z*
|
||||
+26
-26
@@ -7860,6 +7860,32 @@
|
||||
"nintendo-gamecube"
|
||||
]
|
||||
},
|
||||
{
|
||||
"dest": "SC-55/ROM1.BIN",
|
||||
"sha1": "b91bb1d9dccffe831b7cfde7800a3fe32b2fbda6",
|
||||
"sha256": "8a1eb33c7599b746c0c50283e4349a1bb1773b5c0ec0e9661219bf6c067d2042",
|
||||
"size": 32768,
|
||||
"repo_path": "bios/Roland/soundcanvas-roms/SC-55mk2-v1.01/rom1.bin",
|
||||
"cores": [
|
||||
"dosbox"
|
||||
],
|
||||
"systems": [
|
||||
"dos"
|
||||
]
|
||||
},
|
||||
{
|
||||
"dest": "SC-55/ROM2.BIN",
|
||||
"sha1": "078cb5feea05e80bb9a1bb857a2163ee434fd053",
|
||||
"sha256": "a4c9fd821059054c7e7681d61f49ce6f42ed2fe407a7ec1ba0dfdc9722582ce0",
|
||||
"size": 524288,
|
||||
"repo_path": "bios/Roland/sounddata/Nuked-SC55-Resources/ROMs/SC-55mk2-v1.01/rom2.bin",
|
||||
"cores": [
|
||||
"dosbox"
|
||||
],
|
||||
"systems": [
|
||||
"dos"
|
||||
]
|
||||
},
|
||||
{
|
||||
"dest": "SC-55/ROM_SM.BIN",
|
||||
"sha1": "4d48578d811a762a8e7bfaf18989bcac70ae1ba4",
|
||||
@@ -61556,32 +61582,6 @@
|
||||
"nintendo-gamecube"
|
||||
]
|
||||
},
|
||||
{
|
||||
"dest": "SC-55/ROM1.BIN",
|
||||
"sha1": "b91bb1d9dccffe831b7cfde7800a3fe32b2fbda6",
|
||||
"sha256": "8a1eb33c7599b746c0c50283e4349a1bb1773b5c0ec0e9661219bf6c067d2042",
|
||||
"size": 32768,
|
||||
"repo_path": "bios/Roland/soundcanvas-roms/SC-55mk2-v1.01/rom1.bin",
|
||||
"cores": [
|
||||
"dosbox"
|
||||
],
|
||||
"systems": [
|
||||
"dos"
|
||||
]
|
||||
},
|
||||
{
|
||||
"dest": "SC-55/ROM2.BIN",
|
||||
"sha1": "078cb5feea05e80bb9a1bb857a2163ee434fd053",
|
||||
"sha256": "a4c9fd821059054c7e7681d61f49ce6f42ed2fe407a7ec1ba0dfdc9722582ce0",
|
||||
"size": 524288,
|
||||
"repo_path": "bios/Roland/sounddata/Nuked-SC55-Resources/ROMs/SC-55mk2-v1.01/rom2.bin",
|
||||
"cores": [
|
||||
"dosbox"
|
||||
],
|
||||
"systems": [
|
||||
"dos"
|
||||
]
|
||||
},
|
||||
{
|
||||
"dest": "fbalpha2012/hiscore.dat",
|
||||
"sha1": "7381472bf046126257e51a0124e4553282f020e5",
|
||||
|
||||
+60
-4
@@ -237,10 +237,10 @@
|
||||
}
|
||||
}
|
||||
],
|
||||
"total_files": 3220,
|
||||
"total_size": 4192446979,
|
||||
"pack_files": 3222,
|
||||
"pack_size": 4192446979,
|
||||
"total_files": 3225,
|
||||
"total_size": 4193257987,
|
||||
"pack_files": 3227,
|
||||
"pack_size": 4193257987,
|
||||
"total_omitted": 1,
|
||||
"omitted_files": [
|
||||
{
|
||||
@@ -5338,6 +5338,16 @@
|
||||
"sega-saturn"
|
||||
]
|
||||
},
|
||||
{
|
||||
"dest": "bk/BASIC10.ROM",
|
||||
"sha1": "af7eae90c398ec12942a408fa5ac2722e331738c",
|
||||
"sha256": "24be347356715352fcab480ed1559302d47d598255980a32150eba1431b462b8",
|
||||
"size": 24576,
|
||||
"repo_path": "bios/Elektronika/BK/BASIC10.ROM",
|
||||
"cores": [
|
||||
"bk"
|
||||
]
|
||||
},
|
||||
{
|
||||
"dest": "bk/TERAK.ROM",
|
||||
"sha1": "273a9933b68a290c5aedcd6d69faa7b1d22c0344",
|
||||
@@ -24115,6 +24125,32 @@
|
||||
"gearcoleco"
|
||||
]
|
||||
},
|
||||
{
|
||||
"dest": "syscard2.pce",
|
||||
"sha1": "88da02e2503f7c32810f5d93a34849d470742b6d",
|
||||
"sha256": "0deb13845c7e44ea78a25bbbe324afd60a0ec29ea5a4cf5780349f1598d24cd3",
|
||||
"size": 262144,
|
||||
"repo_path": "bios/NEC/PC Engine/syscard2.pce",
|
||||
"cores": [
|
||||
"geargrafx"
|
||||
],
|
||||
"systems": [
|
||||
"nec-pc-engine"
|
||||
]
|
||||
},
|
||||
{
|
||||
"dest": "syscard1.pce",
|
||||
"sha1": "a39a66da7de6ba94ab84d04eef7afeec7d4ee66a",
|
||||
"sha256": "afe9f27f91ac918348555b86298b4f984643eafa2773196f2c5441ea84f0c3bb",
|
||||
"size": 262144,
|
||||
"repo_path": "bios/NEC/PC Engine/syscard1.pce",
|
||||
"cores": [
|
||||
"geargrafx"
|
||||
],
|
||||
"systems": [
|
||||
"nec-pc-engine"
|
||||
]
|
||||
},
|
||||
{
|
||||
"dest": "pac-n1.bin",
|
||||
"sha1": "6973e2593e66fd21627fedccec98d4a364afaaff",
|
||||
@@ -32985,6 +33021,26 @@
|
||||
"virtualjaguar"
|
||||
]
|
||||
},
|
||||
{
|
||||
"dest": "jagboot.rom",
|
||||
"sha1": "af643900fea84234e08b616a6d27f03f0a61db96",
|
||||
"sha256": "f0bd29599b3dfca7f5620c011256c1dc45c9d82c428a318f965c2ba3ded2e9f9",
|
||||
"size": 131072,
|
||||
"repo_path": "bios/Atari/Jaguar/boot.rom",
|
||||
"cores": [
|
||||
"virtualjaguar"
|
||||
]
|
||||
},
|
||||
{
|
||||
"dest": "jagboot_m.rom",
|
||||
"sha1": "af643900fea84234e08b616a6d27f03f0a61db96",
|
||||
"sha256": "f0bd29599b3dfca7f5620c011256c1dc45c9d82c428a318f965c2ba3ded2e9f9",
|
||||
"size": 131072,
|
||||
"repo_path": "bios/Atari/Jaguar/boot.rom",
|
||||
"cores": [
|
||||
"virtualjaguar"
|
||||
]
|
||||
},
|
||||
{
|
||||
"dest": "pinmame/roms/gts1.zip",
|
||||
"sha1": "d4b0c8277c187a92279e2d2b71fc91b72d581257",
|
||||
|
||||
+26
-26
@@ -8099,6 +8099,32 @@
|
||||
"nintendo-gamecube"
|
||||
]
|
||||
},
|
||||
{
|
||||
"dest": "SC-55/ROM1.BIN",
|
||||
"sha1": "b91bb1d9dccffe831b7cfde7800a3fe32b2fbda6",
|
||||
"sha256": "8a1eb33c7599b746c0c50283e4349a1bb1773b5c0ec0e9661219bf6c067d2042",
|
||||
"size": 32768,
|
||||
"repo_path": "bios/Roland/soundcanvas-roms/SC-55mk2-v1.01/rom1.bin",
|
||||
"cores": [
|
||||
"dosbox"
|
||||
],
|
||||
"systems": [
|
||||
"dos"
|
||||
]
|
||||
},
|
||||
{
|
||||
"dest": "SC-55/ROM2.BIN",
|
||||
"sha1": "078cb5feea05e80bb9a1bb857a2163ee434fd053",
|
||||
"sha256": "a4c9fd821059054c7e7681d61f49ce6f42ed2fe407a7ec1ba0dfdc9722582ce0",
|
||||
"size": 524288,
|
||||
"repo_path": "bios/Roland/sounddata/Nuked-SC55-Resources/ROMs/SC-55mk2-v1.01/rom2.bin",
|
||||
"cores": [
|
||||
"dosbox"
|
||||
],
|
||||
"systems": [
|
||||
"dos"
|
||||
]
|
||||
},
|
||||
{
|
||||
"dest": "SC-55/ROM_SM.BIN",
|
||||
"sha1": "4d48578d811a762a8e7bfaf18989bcac70ae1ba4",
|
||||
@@ -61795,32 +61821,6 @@
|
||||
"nintendo-gamecube"
|
||||
]
|
||||
},
|
||||
{
|
||||
"dest": "SC-55/ROM1.BIN",
|
||||
"sha1": "b91bb1d9dccffe831b7cfde7800a3fe32b2fbda6",
|
||||
"sha256": "8a1eb33c7599b746c0c50283e4349a1bb1773b5c0ec0e9661219bf6c067d2042",
|
||||
"size": 32768,
|
||||
"repo_path": "bios/Roland/soundcanvas-roms/SC-55mk2-v1.01/rom1.bin",
|
||||
"cores": [
|
||||
"dosbox"
|
||||
],
|
||||
"systems": [
|
||||
"dos"
|
||||
]
|
||||
},
|
||||
{
|
||||
"dest": "SC-55/ROM2.BIN",
|
||||
"sha1": "078cb5feea05e80bb9a1bb857a2163ee434fd053",
|
||||
"sha256": "a4c9fd821059054c7e7681d61f49ce6f42ed2fe407a7ec1ba0dfdc9722582ce0",
|
||||
"size": 524288,
|
||||
"repo_path": "bios/Roland/sounddata/Nuked-SC55-Resources/ROMs/SC-55mk2-v1.01/rom2.bin",
|
||||
"cores": [
|
||||
"dosbox"
|
||||
],
|
||||
"systems": [
|
||||
"dos"
|
||||
]
|
||||
},
|
||||
{
|
||||
"dest": "fbalpha2012/hiscore.dat",
|
||||
"sha1": "7381472bf046126257e51a0124e4553282f020e5",
|
||||
|
||||
+14
-4
@@ -241,10 +241,10 @@
|
||||
}
|
||||
}
|
||||
],
|
||||
"total_files": 12397,
|
||||
"total_size": 8504485005,
|
||||
"pack_files": 12399,
|
||||
"pack_size": 8504485005,
|
||||
"total_files": 12398,
|
||||
"total_size": 8504485261,
|
||||
"pack_files": 12400,
|
||||
"pack_size": 8504485261,
|
||||
"total_omitted": 30,
|
||||
"omitted_files": [
|
||||
{
|
||||
@@ -61418,6 +61418,16 @@
|
||||
"genesis_plus_gx"
|
||||
]
|
||||
},
|
||||
{
|
||||
"dest": "c600.rom",
|
||||
"sha1": "d4181c9f046aafc3fb326b381baac809d9e38d16",
|
||||
"sha256": "de1e3e035878bab43d0af8fe38f5839c527e9548647036598ee6fe7ec74d2a7d",
|
||||
"size": 256,
|
||||
"repo_path": "bios/Apple/Apple II/AppleIIe_DiskII.rom",
|
||||
"cores": [
|
||||
"gsplus"
|
||||
]
|
||||
},
|
||||
{
|
||||
"dest": "gzdoom.pk3",
|
||||
"sha1": "810ed9968c5b3bdc2c348c9bc76e9f80fbe31308",
|
||||
|
||||
+56
-30
@@ -15,10 +15,10 @@
|
||||
}
|
||||
],
|
||||
"standalone_copies": [],
|
||||
"total_files": 9890,
|
||||
"total_size": 8731814780,
|
||||
"pack_files": 12533,
|
||||
"pack_size": 8772347307,
|
||||
"total_files": 9892,
|
||||
"total_size": 8731913084,
|
||||
"pack_files": 12535,
|
||||
"pack_size": 8772445611,
|
||||
"total_omitted": 8,
|
||||
"omitted_files": [
|
||||
{
|
||||
@@ -43373,6 +43373,32 @@
|
||||
"nintendo-gamecube"
|
||||
]
|
||||
},
|
||||
{
|
||||
"dest": "SC-55/ROM1.BIN",
|
||||
"sha1": "b91bb1d9dccffe831b7cfde7800a3fe32b2fbda6",
|
||||
"sha256": "8a1eb33c7599b746c0c50283e4349a1bb1773b5c0ec0e9661219bf6c067d2042",
|
||||
"size": 32768,
|
||||
"repo_path": "bios/Roland/soundcanvas-roms/SC-55mk2-v1.01/rom1.bin",
|
||||
"cores": [
|
||||
"dosbox"
|
||||
],
|
||||
"systems": [
|
||||
"dos"
|
||||
]
|
||||
},
|
||||
{
|
||||
"dest": "SC-55/ROM2.BIN",
|
||||
"sha1": "078cb5feea05e80bb9a1bb857a2163ee434fd053",
|
||||
"sha256": "a4c9fd821059054c7e7681d61f49ce6f42ed2fe407a7ec1ba0dfdc9722582ce0",
|
||||
"size": 524288,
|
||||
"repo_path": "bios/Roland/sounddata/Nuked-SC55-Resources/ROMs/SC-55mk2-v1.01/rom2.bin",
|
||||
"cores": [
|
||||
"dosbox"
|
||||
],
|
||||
"systems": [
|
||||
"dos"
|
||||
]
|
||||
},
|
||||
{
|
||||
"dest": "SC-55/ROM_SM.BIN",
|
||||
"sha1": "4d48578d811a762a8e7bfaf18989bcac70ae1ba4",
|
||||
@@ -99938,6 +99964,32 @@
|
||||
"zesarux"
|
||||
]
|
||||
},
|
||||
{
|
||||
"dest": "cpc664.rom",
|
||||
"sha1": "4a38f7f5bf7fd0a95cf882433c69e67251a46868",
|
||||
"sha256": "347c9458851329512e90bfd6524f758ed6ac4bdcdeb58546db2f35338b5e8f12",
|
||||
"size": 49152,
|
||||
"repo_path": "bios/Other/zesarux/cpc664.rom",
|
||||
"cores": [
|
||||
"zesarux"
|
||||
],
|
||||
"systems": [
|
||||
"amstrad-cpc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"dest": "cpc6128.rom",
|
||||
"sha1": "29dd0487dc5a96cd00966d074de8700ddd4ee18b",
|
||||
"sha256": "1923b3779ea73519ff3c931c29917f72322b66bcfe37eba7ceeb9e49d095c8ea",
|
||||
"size": 49152,
|
||||
"repo_path": "bios/Other/zesarux/cpc6128.rom",
|
||||
"cores": [
|
||||
"zesarux"
|
||||
],
|
||||
"systems": [
|
||||
"amstrad-cpc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"dest": "pcw_boot.rom",
|
||||
"sha1": "245a173cfc7976a4cae8d255f3d1422aeaf5f09a",
|
||||
@@ -101233,32 +101285,6 @@
|
||||
"nintendo-gamecube"
|
||||
]
|
||||
},
|
||||
{
|
||||
"dest": "SC-55/ROM1.BIN",
|
||||
"sha1": "b91bb1d9dccffe831b7cfde7800a3fe32b2fbda6",
|
||||
"sha256": "8a1eb33c7599b746c0c50283e4349a1bb1773b5c0ec0e9661219bf6c067d2042",
|
||||
"size": 32768,
|
||||
"repo_path": "bios/Roland/soundcanvas-roms/SC-55mk2-v1.01/rom1.bin",
|
||||
"cores": [
|
||||
"dosbox"
|
||||
],
|
||||
"systems": [
|
||||
"dos"
|
||||
]
|
||||
},
|
||||
{
|
||||
"dest": "SC-55/ROM2.BIN",
|
||||
"sha1": "078cb5feea05e80bb9a1bb857a2163ee434fd053",
|
||||
"sha256": "a4c9fd821059054c7e7681d61f49ce6f42ed2fe407a7ec1ba0dfdc9722582ce0",
|
||||
"size": 524288,
|
||||
"repo_path": "bios/Roland/sounddata/Nuked-SC55-Resources/ROMs/SC-55mk2-v1.01/rom2.bin",
|
||||
"cores": [
|
||||
"dosbox"
|
||||
],
|
||||
"systems": [
|
||||
"dos"
|
||||
]
|
||||
},
|
||||
{
|
||||
"dest": "fbalpha2012/hiscore.dat",
|
||||
"sha1": "7381472bf046126257e51a0124e4553282f020e5",
|
||||
|
||||
+41
-22
@@ -1670,40 +1670,59 @@ def filter_systems_by_target(
|
||||
return filtered
|
||||
|
||||
|
||||
def expand_platform_declared_names(config: dict, db: dict) -> set[str]:
|
||||
"""Build set of file names declared by a platform config.
|
||||
def platform_declarations(
|
||||
config: dict, db: dict, *, enrich: bool = True
|
||||
) -> dict[str, list[tuple[int | None, str]]]:
|
||||
"""Every file name a platform declares, with each declaration's size and destination.
|
||||
|
||||
Enriches the set with canonical names and aliases from the database
|
||||
by resolving each platform file's MD5 through by_md5. This handles
|
||||
cases where a platform declares a file under a different name than
|
||||
the emulator profile (e.g. Batocera ROM1 vs gsplus ROM).
|
||||
A name alone does not say which file a declaration is: RetroArch declares
|
||||
galaksija/ROM1.BIN, a 4 KiB ROM, and DOSBox reads a 32 KiB SC-55 ROM1.BIN.
|
||||
The size, from the platform entry or else from the file its hash names,
|
||||
tells a declaration of the same file from a same-named one; None stands
|
||||
for a size nobody knows. The destination, sanitized and case-folded, is
|
||||
the slot the declaration fills.
|
||||
|
||||
With ``enrich``, a declaration also answers for the canonical name and
|
||||
the aliases the database knows its MD5 under. This handles a platform
|
||||
declaring a file under a different name than the emulator profile
|
||||
(e.g. Batocera ROM1 vs gsplus ROM).
|
||||
"""
|
||||
declared: set[str] = set()
|
||||
declared: dict[str, list[tuple[int | None, str]]] = {}
|
||||
by_md5 = db.get("indexes", {}).get("by_md5", {})
|
||||
files_db = db.get("files", {})
|
||||
for system in config.get("systems", {}).values():
|
||||
for fe in system.get("files", []):
|
||||
name = fe.get("name", "")
|
||||
dest = sanitize_pack_path(fe.get("destination") or name).lower()
|
||||
# A zipped_file entry pins a member of the archive it names: its
|
||||
# md5 and its size, when stated, are not the archive's.
|
||||
by_hash: dict = {}
|
||||
size = None
|
||||
if not fe.get("zipped_file"):
|
||||
md5 = (fe.get("md5") or "").lower()
|
||||
if md5 and "," not in md5:
|
||||
by_hash = files_db.get(by_md5.get(md5, ""), {})
|
||||
size = fe.get("size")
|
||||
if size is None:
|
||||
size = files_db.get(
|
||||
(fe.get("sha1") or "").lower(), by_hash
|
||||
).get("size")
|
||||
if name:
|
||||
declared.add(name)
|
||||
md5 = fe.get("md5", "")
|
||||
if not md5:
|
||||
declared.setdefault(name, []).append((size, dest))
|
||||
if not enrich:
|
||||
continue
|
||||
# Skip multi-hash and zipped_file entries (inner ROM MD5, not file MD5)
|
||||
if "," in md5 or fe.get("zipped_file"):
|
||||
continue
|
||||
sha1 = by_md5.get(md5.lower())
|
||||
if not sha1:
|
||||
continue
|
||||
entry = files_db.get(sha1, {})
|
||||
db_name = entry.get("name", "")
|
||||
if db_name:
|
||||
declared.add(db_name)
|
||||
for alias in entry.get("aliases", []):
|
||||
declared.add(alias)
|
||||
known = by_hash
|
||||
for other in (known.get("name", ""), *known.get("aliases", [])):
|
||||
if other:
|
||||
declared.setdefault(other, []).append((known.get("size"), dest))
|
||||
return declared
|
||||
|
||||
|
||||
def expand_platform_declared_names(config: dict, db: dict) -> set[str]:
|
||||
"""The names a platform declares, enriched as `platform_declarations`."""
|
||||
return set(platform_declarations(config, db))
|
||||
|
||||
|
||||
import re
|
||||
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ this module builds so the report and the pack withdraw the same files."""
|
||||
from __future__ import annotations
|
||||
|
||||
from common import PROFILE_IDENTITY_FIELDS
|
||||
from common import expand_platform_declared_names
|
||||
from common import expand_platform_declared_names, platform_declarations
|
||||
from common import load_emulator_profiles
|
||||
from common import resolution_is_hash_exact
|
||||
from common import resolve_local_file
|
||||
@@ -494,12 +494,7 @@ def _collect_emulator_extras(
|
||||
|
||||
# Use strict YAML names (no DB alias enrichment) so that files known
|
||||
# under an alias still get packed at the emulator's expected path.
|
||||
yaml_names: set[str] = set()
|
||||
for system in config.get("systems", {}).values():
|
||||
for fe in system.get("files", []):
|
||||
name = fe.get("name", "")
|
||||
if name:
|
||||
yaml_names.add(name)
|
||||
yaml_names = platform_declarations(config, db, enrich=False)
|
||||
|
||||
undeclared = find_undeclared_files(
|
||||
config, emulators_dir, db, emu_profiles, target_cores=target_cores,
|
||||
|
||||
+31
-10
@@ -29,6 +29,7 @@ import json
|
||||
import os
|
||||
import sys
|
||||
import zipfile
|
||||
from collections.abc import Mapping
|
||||
|
||||
import slots
|
||||
|
||||
@@ -43,7 +44,8 @@ from common import (
|
||||
check_inside_zip,
|
||||
compute_hashes,
|
||||
expand_directory_entries,
|
||||
expand_platform_declared_names,
|
||||
name_match_size_ok,
|
||||
platform_declarations,
|
||||
filter_systems_by_target,
|
||||
group_identical_platforms,
|
||||
list_emulator_profiles,
|
||||
@@ -396,7 +398,8 @@ def _candidate_verdict(
|
||||
fname: str,
|
||||
is_standalone: bool,
|
||||
include_all: bool,
|
||||
declared_names: set,
|
||||
declared_names: Mapping[str, list[tuple[int | None, str]]] | set[str],
|
||||
dest: str = "",
|
||||
) -> str:
|
||||
"""Whether a profile entry can be a gap, and whether it is settled.
|
||||
|
||||
@@ -415,9 +418,27 @@ def _candidate_verdict(
|
||||
# A platform declaring any name the core answers to has met the
|
||||
# requirement: quasi88 reads n88sub.rom or disk.rom, and System.dat
|
||||
# names disk.rom. Without the aliases the pack carried the ROM twice.
|
||||
answers = {fname, file_entry.get("archive") or "", *file_entry.get("aliases", [])}
|
||||
if answers & declared_names:
|
||||
# The archive answers by its name. A loose file answers where the
|
||||
# declaration fills the entry's own slot, whose content the slot
|
||||
# arbitration decides, or elsewhere at a size the core accepts:
|
||||
# Galaksija's 4 KiB ROM1.BIN does not stand for DOSBox's 32 KiB
|
||||
# SC-55 one.
|
||||
if file_entry.get("archive") in declared_names:
|
||||
return "settled"
|
||||
slot = sanitize_pack_path(dest).lower()
|
||||
for name in (fname, *file_entry.get("aliases", [])):
|
||||
if name not in declared_names:
|
||||
continue
|
||||
declarations = (
|
||||
declared_names[name]
|
||||
if isinstance(declared_names, Mapping)
|
||||
else [(None, "")]
|
||||
)
|
||||
if any(
|
||||
(slot and where == slot) or name_match_size_ok(file_entry, size)
|
||||
for size, where in declarations
|
||||
):
|
||||
return "settled"
|
||||
return "keep"
|
||||
|
||||
|
||||
@@ -438,16 +459,16 @@ def find_undeclared_files(
|
||||
target_cores: set[str] | None = None,
|
||||
data_names: set[str] | None = None,
|
||||
include_all: bool = False,
|
||||
declared_names: set[str] | None = None,
|
||||
declared_names: Mapping[str, list[tuple[int | None, str]]] | None = None,
|
||||
) -> list[dict]:
|
||||
"""Find files needed by cores but not declared in platform config.
|
||||
|
||||
declared_names overrides the default enriched set from
|
||||
expand_platform_declared_names. Pass a strict set (YAML names only)
|
||||
when building packs so alias-only names still get packed.
|
||||
declared_names overrides the default enriched declarations from
|
||||
platform_declarations. Pass the strict ones (YAML names only) when
|
||||
building packs so alias-only names still get packed.
|
||||
"""
|
||||
if declared_names is None:
|
||||
declared_names = expand_platform_declared_names(config, db)
|
||||
declared_names = platform_declarations(config, db)
|
||||
|
||||
# Whether the builder drops a file whose local copy contradicts its
|
||||
# declared hash, which decides if such a copy counts as held here.
|
||||
@@ -523,7 +544,7 @@ def find_undeclared_files(
|
||||
if not fname or seen_key in seen_files:
|
||||
continue
|
||||
verdict = _candidate_verdict(
|
||||
f, fname, is_standalone, include_all, declared_names
|
||||
f, fname, is_standalone, include_all, declared_names, dest
|
||||
)
|
||||
if verdict == "settled":
|
||||
seen_files.add(seen_key)
|
||||
|
||||
@@ -92,5 +92,64 @@ class ADeclaredAliasSettlesTheRequirement(unittest.TestCase):
|
||||
self.assertEqual([u["name"] for u in undeclared], [])
|
||||
|
||||
|
||||
class ASameNamedFileOfAnotherSizeSettlesNothing(unittest.TestCase):
|
||||
"""RetroArch declares Galaksija's ROM1.BIN, a 4 KiB ROM; DOSBox reads a
|
||||
32 KiB SC-55 ROM1.BIN and checks its size. The gap pass settled DOSBox's
|
||||
entry on the name alone: the report never listed SC-55/ROM1.BIN, and a
|
||||
missing dump would have shown no gap."""
|
||||
|
||||
PROFILE = (
|
||||
"emulator: DOSBox\ntype: libretro\nsystems: [dos]\ncores: [dosbox]\n"
|
||||
"files:\n - name: ROM1.BIN\n path: SC-55/ROM1.BIN\n"
|
||||
" size: 32768\n validation: [size]\n"
|
||||
)
|
||||
|
||||
def undeclared(self, declared_size, destination="galaksija/ROM1.BIN", md5=None, db_size=None):
|
||||
import os # noqa: PLC0415
|
||||
import tempfile # noqa: PLC0415
|
||||
|
||||
from common import _emulator_profiles_cache # noqa: PLC0415
|
||||
from verify import find_undeclared_files # noqa: PLC0415
|
||||
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
Path(tmp, "emulators").mkdir()
|
||||
Path(tmp, "emulators", "dosbox.yml").write_text(self.PROFILE)
|
||||
_emulator_profiles_cache.clear()
|
||||
self.addCleanup(_emulator_profiles_cache.clear)
|
||||
config = {"platform": "P", "verification_mode": "existence", "cores": "all_libretro",
|
||||
"systems": {"galaksija": {"files": [
|
||||
{"name": "ROM1.BIN", "destination": destination,
|
||||
"size": declared_size, "md5": md5}]}}}
|
||||
db = {"files": {}, "indexes": {"by_name": {}, "by_md5": {}, "by_crc32": {}, "by_path_suffix": {}}}
|
||||
if md5:
|
||||
db["files"]["a" * 40] = {"name": "ROM1.BIN", "size": db_size}
|
||||
db["indexes"]["by_md5"][md5] = "a" * 40
|
||||
previous = os.getcwd()
|
||||
os.chdir(tmp)
|
||||
self.addCleanup(os.chdir, previous)
|
||||
return [u["path"] for u in find_undeclared_files(config, "emulators", db, data_names=set())]
|
||||
|
||||
def test_a_declaration_at_a_size_the_core_rejects_leaves_the_gap_open(self):
|
||||
self.assertEqual(self.undeclared(4096), ["SC-55/ROM1.BIN"])
|
||||
|
||||
def test_a_declaration_at_an_accepted_size_settles_it(self):
|
||||
self.assertEqual(self.undeclared(32768), [])
|
||||
|
||||
def test_a_declaration_without_a_size_still_settles_it(self):
|
||||
self.assertEqual(self.undeclared(None), [])
|
||||
|
||||
def test_the_size_of_the_file_its_hash_names_stands_in(self):
|
||||
"""Batocera writes no size: its md5 names the file, and the file's size
|
||||
decides. MT32_CONTROL.ROM at 64 KiB covered DOSBox's 128 KiB entries."""
|
||||
self.assertEqual(
|
||||
self.undeclared(None, md5="b" * 32, db_size=4096), ["SC-55/ROM1.BIN"]
|
||||
)
|
||||
|
||||
def test_a_declaration_filling_the_entry_slot_settles_it(self):
|
||||
"""Same destination, other size: which bytes fill the slot is the slot
|
||||
arbitration's call, and the builder leaves a taken slot alone."""
|
||||
self.assertEqual(self.undeclared(4096, destination="SC-55/ROM1.BIN"), [])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in new issue
Block a user