mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-10-18 01:13:30 -05:00
fix: name custom and system packs by their selection
Two --from-md5 runs with different hash lists wrote the same file, the second replacing the first, and a pack limited to thirty systems built a name longer than a file name may be. The custom pack now carries a digest of its hash list, and a long system list keeps its first system, a count and a digest, as the emulator pack does.
This commit is contained in:
1 parent
3f68547dc3
commit
7a6e494597
2 files changed
+44
-3
No files matched your search
@@ -203,7 +203,25 @@ def _system_tag(system_filter: list[str] | None) -> str:
|
||||
s = s[len(prefix) :]
|
||||
break
|
||||
display_parts.append("_".join(p.title() for p in s.split("-") if p))
|
||||
return "_" + "_".join(display_parts)
|
||||
return "_" + _bounded_join(display_parts, system_filter)
|
||||
|
||||
|
||||
# A system list long enough to push a pack name past this falls back to the
|
||||
# first system, a count and a digest of the list.
|
||||
MAX_SYSTEM_TAG_BYTES = 120
|
||||
|
||||
|
||||
def _bounded_join(parts: list[str], keys: list[str]) -> str:
|
||||
"""Parts joined while they fit, else the first, a count and a digest.
|
||||
|
||||
Thirty systems joined made a 261-byte file name and the ZIP could not
|
||||
be opened; the digest keeps two different selections apart.
|
||||
"""
|
||||
joined = "_".join(parts)
|
||||
if len(joined.encode("utf-8")) <= MAX_SYSTEM_TAG_BYTES:
|
||||
return joined
|
||||
digest = hashlib.sha1("\n".join(sorted(keys)).encode("utf-8")).hexdigest()[:8]
|
||||
return f"{parts[0]}_and_{len(parts) - 1}_more_{digest}"
|
||||
|
||||
|
||||
_UNSAFE_IN_NAME = re.compile(r'[/\\:*?"<>|]')
|
||||
@@ -1634,7 +1652,9 @@ def generate_system_pack(
|
||||
|
||||
# Named like the platform's --system tag: one spelling of a system is
|
||||
# one file name, and one selection.
|
||||
sys_display = "_".join(_system_display_name(sid) for sid in system_ids)
|
||||
sys_display = _bounded_join(
|
||||
[_system_display_name(sid) for sid in system_ids], list(system_ids)
|
||||
)
|
||||
# Built in a scratch directory: under its emulator name in output_dir it
|
||||
# overwrote, then carried away, an --emulator pack already there.
|
||||
os.makedirs(output_dir, exist_ok=True)
|
||||
@@ -1925,8 +1945,13 @@ def generate_md5_pack(
|
||||
"full", None, None, False, False, standalone=standalone
|
||||
)
|
||||
)
|
||||
# The hash list is what chooses the content: two lists under one name
|
||||
# overwrote each other in the same output directory.
|
||||
selection = hashlib.sha1(
|
||||
"\n".join(sorted(f"{kind}:{value.lower()}" for kind, value in hashes)).encode()
|
||||
).hexdigest()[:8]
|
||||
zip_name = (
|
||||
f"{_name_part(context_name, '_')}_Custom{custom_tags}_BIOS_Pack.zip"
|
||||
f"{_name_part(context_name, '_')}_Custom_{selection}{custom_tags}_BIOS_Pack.zip"
|
||||
)
|
||||
zip_path = os.path.join(output_dir, zip_name)
|
||||
os.makedirs(output_dir, exist_ok=True)
|
||||
|
||||
@@ -2238,6 +2238,22 @@ class APackNameFitsAFileName(unittest.TestCase):
|
||||
self.assertNotEqual(long_name, other)
|
||||
self.assertEqual(_bounded_pack_name(["A", "B"], ["a", "b"], ".zip"), "A_B.zip")
|
||||
|
||||
def test_a_long_system_list_is_bounded(self):
|
||||
"""Thirty systems joined made a 261-byte platform pack name."""
|
||||
from scripts.generate_pack import MAX_SYSTEM_TAG_BYTES, _system_tag
|
||||
|
||||
systems = [f"vendor-console-number-{i}" for i in range(30)]
|
||||
tag = _system_tag(systems)
|
||||
self.assertLessEqual(len(tag.encode()), MAX_SYSTEM_TAG_BYTES + 1)
|
||||
self.assertNotEqual(tag, _system_tag(systems[:-1] + ["other-console"]))
|
||||
self.assertEqual(_system_tag(["sony-playstation"]), "_Playstation")
|
||||
|
||||
def test_two_hash_lists_get_two_names(self):
|
||||
"""--from-md5 named its pack after the context only: a second list
|
||||
overwrote the first pack in the same directory."""
|
||||
source = (ROOT / "scripts" / "generate_pack.py").read_text(encoding="utf-8")
|
||||
self.assertIn('_Custom_{selection}', source)
|
||||
|
||||
def test_the_system_pack_names_itself(self):
|
||||
source = (ROOT / "scripts" / "generate_pack.py").read_text(encoding="utf-8")
|
||||
self.assertIn("pack_name=final_name", source)
|
||||
|
||||
Reference in new issue
Block a user