mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-10-18 01:13:30 -05:00
fix: accept every version a profile lists by name
A profile lists each version its code takes under one name. The core extra carries the first; a held copy matching another entry of the same profile is no longer reported as a hash discrepancy.
This commit is contained in:
1 parent
490fefac97
commit
2e52f06896
2 files changed
+75
-1
No files matched your search
@@ -538,6 +538,33 @@ def _platform_pack_name(
|
||||
return f"{stem}{tags}_BIOS_Pack{_system_tag(system_filter)}.zip"
|
||||
|
||||
|
||||
def _matches_an_alternative(fe: dict, local_path: str, profiles: dict) -> bool:
|
||||
"""Whether the copy is another version the same profile accepts there.
|
||||
|
||||
A profile lists every version its code takes under one name (each GRP
|
||||
of Raze's table, eduke32's demo and retail NWINTER.GRP); the extra
|
||||
carries the first, and the held copy matching a sibling is no mismatch.
|
||||
"""
|
||||
profile = profiles.get(fe.get("source_profile") or "", {})
|
||||
name = fe.get("source_name") or fe.get("name")
|
||||
path = fe.get("source_path") or name
|
||||
siblings = [
|
||||
entry for entry in profile.get("files") or []
|
||||
if isinstance(entry, dict) and entry.get("name") == name
|
||||
and (entry.get("path") or name) == path
|
||||
]
|
||||
if len(siblings) < 2:
|
||||
return False
|
||||
actual = compute_hashes(local_path, frozenset({"sha1", "md5", "crc32"}))
|
||||
for entry in siblings:
|
||||
for algorithm in ("sha1", "md5", "crc32"):
|
||||
declared = entry.get(algorithm)
|
||||
values = declared if isinstance(declared, list) else [declared]
|
||||
if any(v and str(v).lower() == actual.get(algorithm, "") for v in values):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def generate_pack(
|
||||
platform_name: str,
|
||||
platforms_dir: str,
|
||||
@@ -996,7 +1023,9 @@ def generate_pack(
|
||||
)
|
||||
if disagreement:
|
||||
core_discrepancies.append(f"{full_dest} -{disagreement}")
|
||||
if status == "hash_mismatch":
|
||||
if status == "hash_mismatch" and not _matches_an_alternative(
|
||||
fe, local_path, emu_profiles or {}
|
||||
):
|
||||
# The core's declared hash comes from its source, the local dump
|
||||
# is what the collection holds. Shipping it keeps the emulator
|
||||
# working when the code never reads the hash; the divergence is
|
||||
|
||||
@@ -15,6 +15,7 @@ import sys
|
||||
import tempfile
|
||||
import unittest
|
||||
import zipfile
|
||||
import zlib
|
||||
from pathlib import Path
|
||||
from unittest import mock
|
||||
|
||||
@@ -2861,3 +2862,47 @@ class ADuplicateYamlKeyIsRefused(unittest.TestCase):
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
|
||||
class AnAcceptedVersionIsNoCoreDiscrepancy(unittest.TestCase):
|
||||
"""eduke32 lists the retail and demo NWINTER.GRP under one name: the extra
|
||||
carries the first, and a held demo copy is a version the code takes."""
|
||||
|
||||
PROFILE = {"files": [
|
||||
{"name": "NWINTER.GRP", "size": 9, "crc32": "00000000",
|
||||
"validation": ["size", "crc32"]},
|
||||
{"name": "NWINTER.GRP", "size": 4, "crc32": "",
|
||||
"validation": ["size", "crc32"]},
|
||||
]}
|
||||
|
||||
def _extra(self) -> dict:
|
||||
# The shape find_undeclared_files gives a core extra: source_path
|
||||
# defaults to the name when the profile declares no path.
|
||||
return {"name": "NWINTER.GRP", "source_name": "NWINTER.GRP",
|
||||
"source_path": "NWINTER.GRP", "source_profile": "eduke32"}
|
||||
|
||||
def test_a_sibling_version_matches(self):
|
||||
from scripts.generate_pack import _matches_an_alternative
|
||||
|
||||
with tempfile.TemporaryDirectory(dir=TMP_ROOT) as tmp:
|
||||
held = Path(tmp) / "NWINTER.GRP"
|
||||
held.write_bytes(b"demo")
|
||||
profile = json.loads(json.dumps(self.PROFILE))
|
||||
profile["files"][1]["crc32"] = f"{zlib.crc32(b'demo'):08x}"
|
||||
self.assertTrue(_matches_an_alternative(
|
||||
self._extra(), str(held), {"eduke32": profile}))
|
||||
|
||||
def test_a_copy_no_entry_declares_still_disagrees(self):
|
||||
from scripts.generate_pack import _matches_an_alternative
|
||||
|
||||
with tempfile.TemporaryDirectory(dir=TMP_ROOT) as tmp:
|
||||
held = Path(tmp) / "NWINTER.GRP"
|
||||
held.write_bytes(b"other")
|
||||
profile = json.loads(json.dumps(self.PROFILE))
|
||||
profile["files"][1]["crc32"] = f"{zlib.crc32(b'demo'):08x}"
|
||||
self.assertFalse(_matches_an_alternative(
|
||||
self._extra(), str(held), {"eduke32": profile}))
|
||||
|
||||
def test_the_pack_consults_the_alternatives(self):
|
||||
source = (ROOT / "scripts" / "generate_pack.py").read_text()
|
||||
self.assertRegex(source, r'status == "hash_mismatch" and not _matches_an_alternative\(')
|
||||
Reference in new issue
Block a user