mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-11-12 21:13:49 -06:00
fix: split parts hold what the full pack holds
Each part was built alone: the Other_Cores part never saw the platform's destinations and each part had its own case fold. RetroDECK's parts wrote bios/SGB1.sfc/ members beside the file bios/SGB1.sfc, RetroBat's wrote 21 openmsx/ twins of openMSX/ files, and a path two systems declare got each system's file. The full pack is now built in memory first and a part writes a declared file or core extra only where the full pack writes the same bytes.
This commit is contained in:
1 parent
895a520afd
commit
3e2a5279a1
2 files changed
+187
-33
No files matched your search
+126
-1
@@ -7,6 +7,7 @@ and in no part (4507 of RetroArch's 5430).
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import hashlib
|
||||
import sys
|
||||
import tempfile
|
||||
import unittest
|
||||
@@ -19,7 +20,7 @@ REPO_ROOT = Path(__file__).resolve().parent.parent
|
||||
sys.path.insert(0, str(REPO_ROOT / "scripts"))
|
||||
|
||||
from common import build_zip_contents_index, compute_hashes, load_emulator_profiles # noqa: E402
|
||||
from generate_pack import generate_split_packs # noqa: E402
|
||||
from generate_pack import PackRecord, generate_pack, generate_split_packs # noqa: E402
|
||||
|
||||
|
||||
class SplitPartsCoverTheExtras(unittest.TestCase):
|
||||
@@ -70,5 +71,129 @@ class SplitPartsCoverTheExtras(unittest.TestCase):
|
||||
self.assertIn("core_c.bin", members)
|
||||
|
||||
|
||||
class SplitPartsHoldWhatTheFullPackHolds(unittest.TestCase):
|
||||
"""A part sees neither the other systems' declarations nor their extras.
|
||||
|
||||
RetroDECK's Other_Cores part wrote bios/SGB1.sfc/program.rom beside the
|
||||
SNES part's file bios/SGB1.sfc, a file/directory clash the full pack
|
||||
refuses. RetroBat's ColecoVision part wrote openmsx/... beside the MSX
|
||||
part's openMSX/..., case twins the full pack folds. A path two systems
|
||||
declare got each system's file, one per part.
|
||||
"""
|
||||
|
||||
def _build(self, platform: dict, profiles: dict[str, dict], blobs: dict[str, bytes]):
|
||||
tmp = tempfile.TemporaryDirectory(dir=REPO_ROOT / "tmp")
|
||||
self.addCleanup(tmp.cleanup)
|
||||
root = Path(tmp.name)
|
||||
(root / "platforms").mkdir()
|
||||
(root / "emulators").mkdir()
|
||||
files = {}
|
||||
for rel, payload in blobs.items():
|
||||
path = root / "bios" / rel
|
||||
path.parent.mkdir(parents=True, exist_ok=True)
|
||||
path.write_bytes(payload)
|
||||
files[rel] = (str(path), compute_hashes(str(path)))
|
||||
by_name: dict[str, list[str]] = {}
|
||||
for rel, (_p, h) in files.items():
|
||||
by_name.setdefault(Path(rel).name, []).append(h["sha1"])
|
||||
db = {
|
||||
"files": {
|
||||
h["sha1"]: {"name": Path(rel).name, "md5": h["md5"], "sha1": h["sha1"],
|
||||
"sha256": h["sha256"], "path": p, "size": 1}
|
||||
for rel, (p, h) in files.items()
|
||||
},
|
||||
"indexes": {
|
||||
"by_md5": {h["md5"]: h["sha1"] for _p, h in files.values()},
|
||||
"by_name": by_name, "by_crc32": {}, "by_path_suffix": {},
|
||||
},
|
||||
}
|
||||
(root / "platforms" / "_registry.yml").write_text(
|
||||
yaml.dump({"platforms": {"plat": {"status": "active"}}})
|
||||
)
|
||||
(root / "platforms" / "plat.yml").write_text(yaml.dump(platform))
|
||||
for name, profile in profiles.items():
|
||||
(root / "emulators" / f"{name}.yml").write_text(yaml.dump(profile))
|
||||
args = dict(
|
||||
emulators_dir=str(root / "emulators"),
|
||||
zip_contents=build_zip_contents_index(db),
|
||||
emu_profiles=load_emulator_profiles(str(root / "emulators")),
|
||||
offline=True,
|
||||
)
|
||||
full = PackRecord()
|
||||
generate_pack(
|
||||
"plat", str(root / "platforms"), db, str(root / "bios"), "", record=full, **args
|
||||
)
|
||||
parts: dict[str, PackRecord] = {}
|
||||
generate_split_packs(
|
||||
"plat", str(root / "platforms"), db, str(root / "bios"), str(root / "dist"),
|
||||
records=parts, **args,
|
||||
)
|
||||
self.assertFalse((root / "dist").exists())
|
||||
return full, parts
|
||||
|
||||
def _assert_parts_add_up(self, full: PackRecord, parts: dict[str, PackRecord]) -> None:
|
||||
notes = {"README.txt"}
|
||||
union = {m for r in parts.values() for m in r.members} - notes
|
||||
self.assertEqual(union, set(full.members) - notes)
|
||||
for record in parts.values():
|
||||
for member, source in record.sources.items():
|
||||
self.assertEqual(
|
||||
compute_hashes(source)["sha1"],
|
||||
compute_hashes(full.sources[member])["sha1"], member,
|
||||
)
|
||||
|
||||
def test_a_file_directory_conflict_stays_out_of_every_part(self):
|
||||
full, parts = self._build(
|
||||
{
|
||||
"platform": "Plat", "verification_mode": "existence", "cores": ["sgb"],
|
||||
"systems": {"snes": {"files": [{"name": "SGB1.sfc"}]}},
|
||||
},
|
||||
{"sgb": {
|
||||
"emulator": "SGB", "type": "libretro", "systems": ["sgb-other"],
|
||||
"files": [{"name": "program.rom", "path": "SGB1.sfc/program.rom"}],
|
||||
}},
|
||||
{"SGB1.sfc": b"cartridge", "sgb/program.rom": b"program"},
|
||||
)
|
||||
self.assertNotIn("SGB1.sfc/program.rom", full.members)
|
||||
self._assert_parts_add_up(full, parts)
|
||||
|
||||
def test_a_case_twin_is_written_once(self):
|
||||
full, parts = self._build(
|
||||
{
|
||||
"platform": "Plat", "verification_mode": "existence",
|
||||
"case_insensitive_fs": True, "cores": ["msxcore"],
|
||||
"systems": {
|
||||
"msx": {"files": [{"name": "disk.rom", "destination": "openMSX/disk.rom"}]},
|
||||
"coleco": {"files": []},
|
||||
},
|
||||
},
|
||||
{"msxcore": {
|
||||
"emulator": "MSX Core", "type": "libretro", "systems": ["msx", "coleco"],
|
||||
"files": [{"name": "disk.rom", "path": "openmsx/disk.rom"}],
|
||||
}},
|
||||
{"MSX/disk.rom": b"disk"},
|
||||
)
|
||||
self.assertNotIn("openmsx/disk.rom", full.members)
|
||||
self._assert_parts_add_up(full, parts)
|
||||
|
||||
def test_a_path_two_systems_declare_holds_one_file(self):
|
||||
full, parts = self._build(
|
||||
{
|
||||
"platform": "Plat", "verification_mode": "existence",
|
||||
"systems": {
|
||||
"coco": {"files": [{
|
||||
"name": "disk.rom", "sha1": hashlib.sha1(b"coco disk").hexdigest(),
|
||||
}]},
|
||||
"pc88": {"files": [{
|
||||
"name": "disk.rom", "sha1": hashlib.sha1(b"pc-88 disk").hexdigest(),
|
||||
}]},
|
||||
},
|
||||
},
|
||||
{},
|
||||
{"CoCo/disk.rom": b"coco disk", "PC88/disk.rom": b"pc-88 disk"},
|
||||
)
|
||||
self._assert_parts_add_up(full, parts)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in new issue
Block a user