mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-10-18 09:23:26 -05:00
fix: report an archive another profile masks
This commit is contained in:
1 parent
39237004db
commit
bfa6c51ff5
3 files changed
+86
-6
No files matched your search
@@ -1444,11 +1444,6 @@ def generate_emulator_pack(
|
||||
archive_name, archive_prefix, pack_structure, standalone
|
||||
)
|
||||
|
||||
if archive_dest.lower() in seen_lower:
|
||||
continue
|
||||
if _has_path_conflict(archive_dest, seen_destinations, seen_parents):
|
||||
continue
|
||||
|
||||
own_entry = archive_entry(archive_name, files)
|
||||
if required_only and _archive_is_optional(own_entry, archive_name, files):
|
||||
continue
|
||||
@@ -1460,6 +1455,18 @@ def generate_emulator_pack(
|
||||
data_dir_registry=data_registry,
|
||||
offline=offline,
|
||||
)
|
||||
taken = archive_dest.lower() in seen_lower
|
||||
if taken or _has_path_conflict(archive_dest, seen_destinations, seen_parents):
|
||||
# Another profile's file holds this path. The same archive
|
||||
# asked for twice is served; anything else leaves this
|
||||
# profile without its archive, which used to pass in
|
||||
# silence: a neocdz.zip lacking 000-lo.lo shipped as the
|
||||
# one the second core needs.
|
||||
if not (taken and local_path and _same_bytes(
|
||||
local_path, packed_at.get(archive_dest.lower())
|
||||
)):
|
||||
report_missing(archive_name, archive_dest)
|
||||
continue
|
||||
if local_path and status not in ("not_found",):
|
||||
if local_path.endswith(".zip"):
|
||||
_add_zip_to_pack(local_path, archive_dest, zf, own_entry)
|
||||
|
||||
+14
-1
@@ -1688,7 +1688,20 @@ def verify_emulator(
|
||||
archive, profile.get("archive_prefix", ""),
|
||||
profile.get("pack_structure"), standalone,
|
||||
)
|
||||
if local_path:
|
||||
block = placement_block(
|
||||
dest, placed_files, set(placed), placed_parents, True
|
||||
)
|
||||
if block and local_path and result["status"] != Status.MISSING:
|
||||
other_path, owner, other_dest = placed.get(dest.lower(), (None, "", ""))
|
||||
if block == "path_conflict" or content_id(local_path) != content_id(other_path):
|
||||
# The pack serves the other profile's file here: this
|
||||
# archive is not in it, whatever this profile resolves.
|
||||
result["status"] = Status.MISSING
|
||||
result["reason"] = (
|
||||
"a packed file occupies its directory" if block == "path_conflict"
|
||||
else f"the pack holds {owner}'s {other_dest} at this path"
|
||||
)
|
||||
elif local_path:
|
||||
occupy(dest, local_path, emu_name)
|
||||
dest_to_name[dest] = archive
|
||||
cur = result["status"]
|
||||
|
||||
@@ -278,5 +278,65 @@ class AlternativesAgreeWithThePack(unittest.TestCase):
|
||||
self.assertEqual(result["status_counts"].get(Status.UNTESTED), 1)
|
||||
|
||||
|
||||
|
||||
class AMaskedArchiveIsMissing(unittest.TestCase):
|
||||
"""Profile a ships a loose pack.zip; profile b needs pack.zip as an
|
||||
archive holding a member a's copy lacks. The pack skipped b's archive
|
||||
in silence and verify counted it OK on b's own copy."""
|
||||
|
||||
def setUp(self):
|
||||
import zipfile
|
||||
|
||||
self._tmp = tempfile.TemporaryDirectory(dir=REPO_ROOT / "tmp")
|
||||
self.root = Path(self._tmp.name)
|
||||
self.emulators = self.root / "emulators"
|
||||
files = {}
|
||||
for folder, members in (("A", {"x.bin": b"x"}), ("B", {"x.bin": b"x", "y.bin": b"y"})):
|
||||
target = self.root / "bios" / folder / "pack.zip"
|
||||
target.parent.mkdir(parents=True)
|
||||
with zipfile.ZipFile(target, "w") as archive:
|
||||
for name, data in members.items():
|
||||
archive.writestr(name, data)
|
||||
payload = target.read_bytes()
|
||||
sha1 = hashlib.sha1(payload).hexdigest()
|
||||
files[sha1] = {"path": str(target), "name": "pack.zip", "size": len(payload),
|
||||
"sha1": sha1, "md5": hashlib.md5(payload).hexdigest(),
|
||||
"sha256": hashlib.sha256(payload).hexdigest(), "crc32": "0"}
|
||||
self.sha1_b = sha1
|
||||
self.db = {"files": files, "indexes": generate_db.build_indexes(files, {})}
|
||||
self.emulators.mkdir()
|
||||
a_sha1 = next(k for k in files if k != sha1)
|
||||
(self.emulators / "a.yml").write_text(yaml.dump({
|
||||
"emulator": "A", "type": "libretro", "cores": ["a"], "systems": ["x"],
|
||||
"files": [{"name": "pack.zip", "required": True, "sha1": a_sha1}],
|
||||
}))
|
||||
(self.emulators / "b.yml").write_text(yaml.dump({
|
||||
"emulator": "B", "type": "libretro", "cores": ["b"], "systems": ["x"],
|
||||
"files": [{"name": "y.bin", "archive": "pack.zip", "required": True,
|
||||
"crc32": f"{__import__('zlib').crc32(b'y'):08x}"}],
|
||||
}))
|
||||
common._emulator_profiles_cache.clear()
|
||||
|
||||
def tearDown(self):
|
||||
common._emulator_profiles_cache.clear()
|
||||
self._tmp.cleanup()
|
||||
|
||||
def test_both_report_the_archive_missing(self):
|
||||
from verify import Status, verify_emulator
|
||||
|
||||
out = self.root / "dist"
|
||||
out.mkdir()
|
||||
report = io.StringIO()
|
||||
with contextlib.redirect_stdout(report):
|
||||
builder.generate_emulator_pack(
|
||||
["a", "b"], str(self.emulators), self.db, str(self.root / "bios"),
|
||||
str(out), offline=True,
|
||||
)
|
||||
self.assertIn("pack.zip", report.getvalue().split("MISSING", 1)[-1])
|
||||
result = verify_emulator(["a", "b"], str(self.emulators), self.db)
|
||||
statuses = [d["status"] for d in result["details"] if d["name"] == "pack.zip"]
|
||||
self.assertIn(Status.MISSING, statuses)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in new issue
Block a user