From 8380f63f9765586d2976e022e798923c0d01ea04 Mon Sep 17 00:00:00 2001 From: Abdessamad Derraz <3028866+Abdess@users.noreply.github.com> Date: Sat, 10 Oct 2026 12:11:16 +0200 Subject: [PATCH] fix: write one romm entry per key --- scripts/exporter/romm_exporter.py | 29 +++++++++++++++++++++++++---- tests/test_export_counts.py | 22 ++++++++++++++++++++++ 2 files changed, 47 insertions(+), 4 deletions(-) diff --git a/scripts/exporter/romm_exporter.py b/scripts/exporter/romm_exporter.py index 29e88c9f..c1b2f9a0 100644 --- a/scripts/exporter/romm_exporter.py +++ b/scripts/exporter/romm_exporter.py @@ -29,8 +29,12 @@ SOURCE_URL = ( class Exporter(BaseExporter): """Write RomM's known_bios_files.json, corrected.""" - # (system, filename) keys the platform itself declares, set by render. - _platform_keys: frozenset[tuple[str, str]] = frozenset() + def __init__(self) -> None: + super().__init__() + # (system, filename) keys the platform itself declares, and the + # addition that claims each other key first: both set by render. + self._platform_keys: set[tuple[str, str]] = set() + self._first_addition: dict[tuple[str, str], int] = {} @staticmethod def platform_name() -> str: @@ -75,9 +79,15 @@ class Exporter(BaseExporter): """ if fe.platform is not None: return True - if (fe.native_system, fe.name) in self._platform_keys: + key = (fe.native_system, fe.name) + if key in self._platform_keys: return False - return self._verifiable(fe) and self._known_platform(fe.native_system) + if not (self._verifiable(fe) and self._known_platform(fe.native_system)): + return False + # Two additions under one key: the second would overwrite the first + # in the dict and both were counted landed. The first one in render + # order is written, the other is not. + return self._first_addition.get(key, id(fe)) == id(fe) def render( self, @@ -93,6 +103,17 @@ class Exporter(BaseExporter): for fe in system.files if fe.platform is not None } + self._first_addition = {} + for system in sorted(systems.values(), key=lambda s: s.native_id): + for fe in sorted(system.files, key=lambda f: f.name): + key = (fe.native_system, fe.name) + if ( + fe.platform is None + and key not in self._platform_keys + and self._verifiable(fe) + and self._known_platform(fe.native_system) + ): + self._first_addition.setdefault(key, id(fe)) for system in sorted(systems.values(), key=lambda s: s.native_id): for fe in sorted(system.files, key=lambda f: f.name): diff --git a/tests/test_export_counts.py b/tests/test_export_counts.py index eb8ca7f1..e4df63c9 100644 --- a/tests/test_export_counts.py +++ b/tests/test_export_counts.py @@ -362,6 +362,28 @@ class RecalboxKeepsItsOwnNotes(unittest.TestCase): truth={"md5": A, "note": "Loaded at libretro.c:120"}) self.assertNotIn("note=", Recalbox()._bios_element(fe, "psx")) +class RommWritesOneEntryPerKey(unittest.TestCase): + """Two additions under one slug:filename key: the second overwrote the + first in RomM's dict and both were counted landed.""" + + def test_the_second_addition_under_a_key_is_not_writable(self): + from exporter.romm_exporter import Exporter as Romm # noqa: PLC0415 + + first = NativeFile("basic.rom", "Acorn/basic.rom", "acpc", + truth={"size": 16384, "md5": A}) + second = NativeFile("basic.rom", "Electron/basic.rom", "acpc", + truth={"size": 16384, "md5": B}) + exporter = Romm() + produced = exporter.render( + {"acpc": NativeSystem("acpc", files=[first, second])}, None, {}, None + ) + data = json.loads(produced[exporter.native_filename()]) + self.assertEqual(list(data), ["acpc:basic.rom"]) + self.assertEqual( + [exporter.writable(first), exporter.writable(second)], [True, False] + ) + + class RetroPieProposals(unittest.TestCase): def test_required_is_read_for_the_package_core(self): fe = NativeFile("scph5501.bin", "scph5501.bin", "psx",