mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-10-20 18:59:07 -05:00
fix: verify applies storage tiers like the pack
The builder never looks up a user_provided entry (it writes instructions in its place) nor an external one (fetched from its URL at build time). verify resolved both by name, so a same-named file in bios/ made it credit a file the pack does not carry.
This commit is contained in:
1 parent
1ea6b9d070
commit
2bd9f8a264
2 files changed
+66
-2
No files matched your search
+34
-2
@@ -782,6 +782,31 @@ def _mark_unplaced(config: dict, undeclared: list[dict], profiles: dict) -> None
|
||||
u["omitted"] = _UNPLACED_REASONS[reason]
|
||||
|
||||
|
||||
def _storage_verdict(file_entry: dict, emulator_pack: bool) -> dict | None:
|
||||
"""The result a storage tier fixes before any lookup, as the builder sees it.
|
||||
|
||||
A user_provided entry is never taken from the collection: a platform pack
|
||||
writes its instructions in the slot and counts it filled, an emulator pack
|
||||
lists it to provide. An external one is fetched from its URL when the pack
|
||||
is built, never read from bios/. Resolving either by name credited a
|
||||
same-named file the pack does not carry.
|
||||
"""
|
||||
storage = file_entry.get("storage", "embedded")
|
||||
base = {"name": file_entry.get("name", ""), "required": file_entry.get("required", True)}
|
||||
if storage == "user_provided":
|
||||
if emulator_pack:
|
||||
stated = file_entry.get("unsourceable")
|
||||
why = (
|
||||
stated if isinstance(stated, str) and stated
|
||||
else file_entry.get("instructions") or "the user provides it"
|
||||
)
|
||||
return {**base, "status": Status.MISSING, "unsourceable": why}
|
||||
return {**base, "status": Status.OK, "user_provided": True}
|
||||
if storage == "external":
|
||||
return {**base, "status": Status.MISSING, "reason": "fetched from its URL when the pack is built"}
|
||||
return None
|
||||
|
||||
|
||||
_HIDDEN_REASONS = {
|
||||
"case_twin": "a packed file of the same name in another case takes its place",
|
||||
"path_conflict": "a packed file occupies its directory",
|
||||
@@ -1064,7 +1089,11 @@ def verify_platform(
|
||||
destination = sanitize_pack_path(
|
||||
file_entry.get("destination", file_entry.get("name", ""))
|
||||
)
|
||||
if not reads_file_contents(mode):
|
||||
stored = _storage_verdict(file_entry, emulator_pack=False)
|
||||
if stored is not None:
|
||||
result = stored
|
||||
local_path = None
|
||||
elif not reads_file_contents(mode):
|
||||
result = verify_entry_existence(
|
||||
file_entry,
|
||||
local_path,
|
||||
@@ -1795,7 +1824,10 @@ def verify_emulator(
|
||||
required = file_entry.get("required", True)
|
||||
hle = file_entry.get("hle_fallback", False)
|
||||
|
||||
if not local_path:
|
||||
stored = _storage_verdict(file_entry, emulator_pack=True)
|
||||
if stored is not None:
|
||||
result = stored
|
||||
elif not local_path:
|
||||
result = {"name": name, "status": Status.MISSING, "required": required}
|
||||
# An entry the profile documents as unsourceable is absent by
|
||||
# design: a per-user key, a slot the user fills, a dump nobody
|
||||
|
||||
@@ -242,5 +242,37 @@ class FlatFirmwareFolder(unittest.TestCase):
|
||||
self.assertEqual([f["dest"] for f in files if f["dest"].count("/") > 1], [])
|
||||
|
||||
|
||||
class UserProvidedIsNeverTakenFromTheCollection(unittest.TestCase):
|
||||
"""The builder writes instructions for a user_provided entry and never
|
||||
looks it up. verify resolved it by name, so a same-named file in bios/
|
||||
made it report 1/1 OK for a pack that holds no such file."""
|
||||
|
||||
def test_verify_matches_the_builder(self):
|
||||
from verify import Status, verify_emulator
|
||||
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
previous = os.getcwd()
|
||||
os.chdir(tmp)
|
||||
self.addCleanup(os.chdir, previous)
|
||||
for d in ("emulators", "bios/Sony"):
|
||||
Path(d).mkdir(parents=True)
|
||||
Path("bios/Sony/scph5501.bin").write_bytes(b"psx")
|
||||
sha1 = hashlib.sha1(b"psx").hexdigest()
|
||||
files = {sha1: {"path": "bios/Sony/scph5501.bin", "name": "scph5501.bin",
|
||||
"size": 3, "sha1": sha1, "md5": hashlib.md5(b"psx").hexdigest(),
|
||||
"sha256": hashlib.sha256(b"psx").hexdigest(), "crc32": "00000001"}}
|
||||
db = {"files": files, "indexes": generate_db.build_indexes(files, {})}
|
||||
Path("emulators/fake.yml").write_text(
|
||||
"emulator: Fake\ntype: libretro\nsystems: [psx]\ncores: [fake]\n"
|
||||
"files:\n - name: scph5501.bin\n storage: user_provided\n"
|
||||
)
|
||||
common._emulator_profiles_cache.clear()
|
||||
self.addCleanup(common._emulator_profiles_cache.clear)
|
||||
result = verify_emulator(["fake"], "emulators", db)
|
||||
statuses = [d["status"] for d in result["details"] if d["name"] == "scph5501.bin"]
|
||||
self.assertEqual(statuses, [Status.MISSING])
|
||||
self.assertNotIn(Status.OK, result["status_counts"])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in new issue
Block a user