From e3c5d97b94f2b8cff7e93e8834c21968243e2ce4 Mon Sep 17 00:00:00 2001 From: Abdessamad Derraz <3028866+Abdess@users.noreply.github.com> Date: Sat, 17 Oct 2026 08:51:45 +0200 Subject: [PATCH] fix: free a path the builder refuses to fill verify counted a declaration whose hash the frontend refuses as occupying its path, while the builder leaves it out and a core file takes the place; the report then called that core file missing from the pack. It now reads the builder's verdict. The hidden-extras tests move to RetroArch and RetroBat, which still fold case, and test the same-bytes twin again instead of skipping. --- scripts/verify.py | 10 +++++++++- tests/test_hidden_extras.py | 30 ++++++++++++++++++++++++------ 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/scripts/verify.py b/scripts/verify.py index 2aef7ddf..295ea503 100644 --- a/scripts/verify.py +++ b/scripts/verify.py @@ -72,6 +72,7 @@ from nativemode import ( reads_file_contents, ) from validation import ( + baseline_verdict, declaration_settles, frontend_digest_matches, existence_discrepancy, @@ -1027,7 +1028,14 @@ def verify_platform( validation_index, ) details.append(result) - if local_path and result["status"] != Status.MISSING: + # Occupied only where the builder ships the declaration: a hash + # the frontend refuses is left out, and the destination stays free + # for a core's file the pack does carry. + if ( + local_path + and result["status"] != Status.MISSING + and baseline_verdict(file_entry, local_path, resolve_status, mode)[1] is None + ): shipped.setdefault( f"{base_dest}/{destination}" if base_dest else destination, local_path, diff --git a/tests/test_hidden_extras.py b/tests/test_hidden_extras.py index ddc4e70c..c16e4491 100644 --- a/tests/test_hidden_extras.py +++ b/tests/test_hidden_extras.py @@ -49,6 +49,16 @@ class OneRule(unittest.TestCase): ) self.assertNotIn("if full_dest.lower() in seen_lower and case_insensitive", builder) + def test_a_refused_declaration_occupies_nothing(self): + """verify counted a declaration whose hash the frontend refuses as + occupying its path; the builder leaves it out, and the core file + that then takes the path was reported missing from the pack.""" + source = (REPO_ROOT / "scripts" / "verify.py").read_text(encoding="utf-8") + self.assertIn( + "baseline_verdict(file_entry, local_path, resolve_status, mode)[1] is None", + source, + ) + class TheReportSaysSo(unittest.TestCase): """Reads the repository: skips when the database is absent.""" @@ -66,24 +76,32 @@ class TheReportSaysSo(unittest.TestCase): db = load_database("database.json") profiles = load_emulator_profiles("emulators") - config = load_platform_config("retropie", "platforms") - cls.result = verify_platform(config, db, "emulators", profiles) + # Platforms whose filesystem folds case; RetroPie and Lakka run on + # Linux and keep both names. + cls.results = { + name: verify_platform( + load_platform_config(name, "platforms"), db, "emulators", profiles + ) + for name in ("retroarch", "retrobat") + } finally: os.chdir(previous) - def _entry(self, emulator: str, path: str) -> dict: - for u in self.result["undeclared_files"]: + def _entry(self, emulator: str, path: str, platform: str = "retroarch") -> dict: + for u in self.results[platform]["undeclared_files"]: if u.get("emulator") == emulator and (u.get("path") or u.get("name")) == path: return u self.skipTest(f"{emulator} {path} is not in the cross-reference") def test_a_case_twin_with_other_bytes_is_left_out(self): - entry = self._entry("openMSX", "fmpac.rom") + entry = self._entry("NP2kai", "np2kai/bios.rom", "retrobat") self.assertIs(entry.get("in_pack"), False) self.assertIn("another case", entry.get("omitted", "")) def test_a_twin_with_the_same_bytes_serves_the_core(self): - entry = self._entry("Stella 2023", "KVS1.WAV") + # MesenCE opens bios.col; RetroArch's pack folds it onto BIOS.col, + # the same bytes, which serves the core on a folding filesystem. + entry = self._entry("MesenCE", "bios.col") self.assertIsNot(entry.get("in_pack"), False) def test_a_directory_under_a_packed_file_is_left_out(self):