fix: give no second-pass copy to unsourceable files

This commit is contained in:
Abdessamad Derraz committed 2026-10-15 22:45:42 +02:00
1 parent 12f362dfb9
commit 2fb49d0658
3 files changed
+43 -4

No files matched your search

+4 -2
View File
@@ -604,8 +604,10 @@ def _collect_emulator_extras(
fname = f.get("name", "")
if not fname:
continue
# Only duplicate files already covered at another destination
if fname not in covered_names:
# Only duplicate files already covered at another destination.
# An unsourceable entry is a file no collection holds: the name
# covered elsewhere belongs to another program's file.
if fname not in covered_names or f.get("unsourceable"):
continue
file_mode = f.get("mode")
if file_mode == "standalone" and not is_standalone:
+35
View File
@@ -62,5 +62,40 @@ class IdentityTravels(unittest.TestCase):
self.assertIn("validation", PROFILE_IDENTITY_FIELDS)
class UnsourceableIsNoCopy(unittest.TestCase):
"""The second pass copies a covered file to another core's path by name.
zc210 ships its own default.sf2; dosbox-staging reads a default.sf2 that
the operating system links to its SoundFont, which no collection holds.
The name was enough to give dosbox-staging a slot, recorded as missing
while zc210 was in the pack and absent once it was not, so a pack built
for a target disagreed with the installer narrowing the full list.
"""
def test_an_unsourceable_entry_gets_no_copy(self):
profiles = {
"zc210": {"emulator": "ZC", "type": "libretro", "systems": ["zc"],
"files": [{"name": "default.sf2", "path": "zc210/sf2/default.sf2"}]},
"dosbox-staging": {
"emulator": "DOSBox Staging", "type": "libretro", "systems": ["dos"],
"files": [{"name": "default.sf2", "path": "soundfonts/default.sf2",
"required": False, "unsourceable": "the system's own link"}],
},
}
config = {"cores": ["zc210", "dosbox-staging"], "systems": {}}
db = {
"files": {"s1": {"name": "default.sf2", "path": "bios/ZC/default.sf2",
"size": 10, "sha1": "s1", "md5": "m1", "crc32": "c1"}},
"indexes": {"by_name": {"default.sf2": ["s1"]}, "by_md5": {"m1": "s1"},
"by_crc32": {"c1": "s1"},
"by_path_suffix": {"zc210/sf2/default.sf2": ["s1"]}},
}
extras = _collect_emulator_extras(config, "emulators", db, set(), "", profiles)
self.assertEqual(
[(e["source_profile"], e["destination"]) for e in extras],
[("zc210", "zc210/sf2/default.sf2")],
)
if __name__ == "__main__":
unittest.main()
+4 -2
View File
@@ -153,7 +153,8 @@ class SecondPassKeepsIdentity(unittest.TestCase):
The second extras pass copied a name the baseline already covers to the
profile's own path, without its hashes or its `unsourceable:` flag, so
the copy resolved on the name: RetroBat's pack carried Quake III's
baseq3/pak1.pk3 as MOHAA's mainta/pak1.pk3.
baseq3/pak1.pk3 as MOHAA's mainta/pak1.pk3. An unsourceable entry is
settled, as the first pass treats it, and gets no copy.
"""
def test_flag_and_hashes_reach_the_alternative_destination(self):
@@ -182,7 +183,8 @@ class SecondPassKeepsIdentity(unittest.TestCase):
}}
extras = {e["destination"]: e for e in _collect_emulator_extras(
config, "emulators", db, set(), "", profiles)}
self.assertEqual(extras["mainta/pak1.pk3"].get("unsourceable"), "retail")
# Unsourceable is settled, as in the first pass: no copy at all.
self.assertNotIn("mainta/pak1.pk3", extras)
self.assertEqual(extras["maintt/pak1.pk3"].get("sha1"), "c" * 40)