From 3a306d0970799c929f5863803516b3f09e9e3772 Mon Sep 17 00:00:00 2001 From: Abdessamad Derraz <3028866+Abdess@users.noreply.github.com> Date: Thu, 5 Nov 2026 12:00:45 +0100 Subject: [PATCH] feat: link each missing file to its platform entry --- scripts/generate_site.py | 27 +++++++++++++++++++++++++-- tests/test_audit_regressions.py | 22 ++++++++++++++++++++++ 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/scripts/generate_site.py b/scripts/generate_site.py index f6fff2aae..de984fe3d 100644 --- a/scripts/generate_site.py +++ b/scripts/generate_site.py @@ -10022,6 +10022,16 @@ def _declared_hashes(config: dict, detail: dict) -> dict[str, list[str]]: return {} +def _declared_destination(config: dict, detail: dict) -> str: + """Where the platform's list puts a reported file, its name when the + entry names no folder.""" + system = (config.get("systems") or {}).get(detail.get("system", "")) or {} + for entry in system.get("files") or []: + if isinstance(entry, dict) and entry.get("name") == detail.get("name"): + return str(entry.get("destination") or detail.get("name", "")) + return str(detail.get("name", "")) + + def short_hash(value: str) -> str: """A hash in a table cell: its first 12 characters, the whole value in the title. Full MD5 and SHA1 values pushed the gaps tables past the @@ -10081,8 +10091,13 @@ def _render_problem_files( entry = missing_files.setdefault(fname, { "name": fname, "required": p["required"], "platforms": [], "reason": p["reason"], "categories": set(), + "where": {}, }) entry["platforms"].append(p["platform"]) + # The platform's entry for the file, and the folder it expects. + entry["where"].setdefault( + (p["platform"], p.get("platform_key", ""), p.get("system", "")), set(), + ).add(p.get("destination") or fname) entry["categories"].add(p.get("category", "bios")) if p["required"]: entry["required"] = True @@ -10130,7 +10145,9 @@ def _render_problem_files( "load, `game_data` comes from a copy of the game, `unread` is " "opened by none of them. Only a missing `bios` entry stops a " "console from starting. A name a list declares in several " - "folders is one row.", + "folders is one row. Each platform links to its entry, which " + "names the cores examined, and is followed by where its list " + "puts the file.", "", "| File | Category | Required | Platforms |", "|------|----------|----------|-----------|", @@ -10138,7 +10155,12 @@ def _render_problem_files( for fname in sorted(missing_files): f = missing_files[fname] req = "yes" if f["required"] else "no" - plats = ", ".join(sorted(set(f["platforms"]))) + plats = "; ".join( + (f"[{display}](platforms/{key}.md#{system.replace(' ', '-')})" + if key and system else display) + + " " + ", ".join(_code(dest) for dest in sorted(dests)) + for (display, key, system), dests in sorted(f["where"].items()) + ) cats = f["categories"] category = "bios" if "bios" in cats else ", ".join(sorted(cats)) lines.append(f"| `{fname}` | {category} | {req} | {plats} |") @@ -10377,6 +10399,7 @@ def generate_gap_analysis( "discrepancy": d.get("discrepancy", ""), "system": d.get("system", ""), "declared": _declared_hashes(cov.get("config") or {}, d), + "destination": _declared_destination(cov.get("config") or {}, d), "path": d.get("path") or "", }) diff --git a/tests/test_audit_regressions.py b/tests/test_audit_regressions.py index 4f18a8ca8..7c71c3c5a 100644 --- a/tests/test_audit_regressions.py +++ b/tests/test_audit_regressions.py @@ -5015,6 +5015,28 @@ class GapsPageCountsOneWay(unittest.TestCase): self.assertIn('rb-badge-danger">1 name', text) self.assertNotIn("1 missing", text) + def test_a_missing_row_links_each_entry_and_names_its_folder(self): + """The row said `N88_KNJ1.ROM | unread | yes | AmberELEC` in plain text: + neither where the list puts it nor which cores were examined.""" + from scripts.generate_site import _render_problem_files + + problems = [{"platform": "AmberELEC", "platform_key": "amberelec", "name": "N88_KNJ1.ROM", + "status": "missing", "required": True, "reason": "", "discrepancy": "", + "category": "unread", "system": "nec-pc-88", + "destination": "bios/quasi88/N88_KNJ1.ROM"}] + text = "\n".join(_render_problem_files(problems)) + self.assertIn("| [AmberELEC](platforms/amberelec.md#nec-pc-88) " + "`bios/quasi88/N88_KNJ1.ROM` |", text) + + def test_the_destination_is_the_list_entrys(self): + from scripts.generate_site import _declared_destination + sys.path.insert(0, str(ROOT / "scripts")) + from common import load_platform_config + + config = load_platform_config("amberelec", str(ROOT / "platforms")) + detail = {"name": "N88_KNJ1.ROM", "system": "nec-pc-88"} + self.assertEqual(_declared_destination(config, detail), "bios/quasi88/N88_KNJ1.ROM") + def test_verify_marks_the_settled_entry(self): sys.path.insert(0, str(ROOT / "scripts")) import verify