From d2a3c0bc3cd6dc0af980a416673522864161e7e1 Mon Sep 17 00:00:00 2001
From: Abdessamad Derraz <3028866+Abdess@users.noreply.github.com>
Date: Sat, 17 Oct 2026 15:12:21 +0200
Subject: [PATCH] feat: show who pins each variant on system pages
---
scripts/generate_site.py | 109 ++++++++++++++++---------------------
tests/test_site_exports.py | 27 +++++++++
2 files changed, 75 insertions(+), 61 deletions(-)
diff --git a/scripts/generate_site.py b/scripts/generate_site.py
index 93b8e63b..8cdda8f9 100644
--- a/scripts/generate_site.py
+++ b/scripts/generate_site.py
@@ -1764,6 +1764,45 @@ def generate_provenance_page(db: dict, report: dict) -> str:
return "\n".join(lines) + "\n"
+def _system_file_card(f: dict, consumers: FileConsumers) -> list[str]:
+ """One file of a system page: hashes, who reads it, its provenance."""
+ name = f["name"]
+ sha1_full = f.get("sha1", "unknown")
+ md5_full = f.get("md5", "unknown")
+ size = _fmt_size(f.get("size", 0))
+ # Who reads this file, not who reads a file of this name
+ plats = sorted(consumers.platforms.get(sha1_full, ()))
+ emus = sorted(consumers.emulators.get(sha1_full, ()))
+ sha1_short = sha1_full[:12] if sha1_full != "unknown" else "-"
+ md5_short = md5_full[:12] if md5_full != "unknown" else "-"
+
+ lines = ['
', ""]
+ lines.append(f'**`{name}`** {size}')
+ lines.append("")
+ if "/.variants/" in f.get("path", ""):
+ lines.append(f"- Stored as: `{f['path'].rsplit('/', 1)[-1]}`")
+ lines.append(f'- SHA1: `{sha1_short}...`')
+ lines.append(f'- MD5: `{md5_short}...`')
+ if plats:
+ plat_badges = " ".join(
+ f'[{p}](../platforms/{p}.md)'
+ for p in plats
+ )
+ lines.append(f"- Platforms: {plat_badges}")
+ if emus:
+ lines.append(f"- Emulators: {', '.join(_emulator_link(e, '../') for e in emus)}")
+ provenance = f.get("provenance", {})
+ if provenance:
+ prov_badges = " ".join(
+ f''
+ f"[{_PROVENANCE_LABELS.get(s, s)}](../provenance.md#{s})"
+ for s, data in sorted(provenance.items())
+ )
+ lines.append(f"- Verified dump: {prov_badges}")
+ lines.extend(["", "
", ""])
+ return lines
+
+
def generate_system_page(
manufacturer: str,
consoles: dict[str, list],
@@ -1785,70 +1824,18 @@ def generate_system_page(
variant_files = [f for f in files if "/.variants/" in f["path"]]
for f in sorted(main_files, key=lambda x: x["name"]):
- name = f["name"]
- sha1_full = f.get("sha1", "unknown")
- md5_full = f.get("md5", "unknown")
- size = _fmt_size(f.get("size", 0))
-
- # Who reads this file, not who reads a file of this name
- plats = sorted(consumers.platforms.get(sha1_full, ()))
- emus = sorted(consumers.emulators.get(sha1_full, ()))
-
- # Truncated hashes for readability
- sha1_short = sha1_full[:12] if sha1_full != "unknown" else "-"
- md5_short = md5_full[:12] if md5_full != "unknown" else "-"
-
- lines.append('')
- lines.append("")
- lines.append(
- f'**`{name}`** '
- f'{size}'
- )
- lines.append("")
- lines.append(
- f'- SHA1: `{sha1_short}...`'
- )
- lines.append(
- f'- MD5: `{md5_short}...`'
- )
- if plats:
- plat_badges = " ".join(
- f''
- f"[{p}](../platforms/{p}.md)"
- for p in plats
- )
- lines.append(f"- Platforms: {plat_badges}")
- if emus:
- emu_links = [_emulator_link(e, "../") for e in emus]
- lines.append(f"- Emulators: {', '.join(emu_links)}")
- provenance = f.get("provenance", {})
- if provenance:
- prov_badges = " ".join(
- f''
- f"[{_PROVENANCE_LABELS.get(s, s)}](../provenance.md#{s})"
- for s, data in sorted(provenance.items())
- )
- lines.append(f"- Verified dump: {prov_badges}")
- lines.append("")
- lines.append("
")
- lines.append("")
+ lines.extend(_system_file_card(f, consumers))
if variant_files:
- lines.append(
- f'??? note "Variants ({len(variant_files)})"'
- )
+ # A variant gets the same card as a primary: the revision a
+ # platform pins is the one a reader comes to find, and showed as
+ # a name and a truncated MD5, nothing said who pins it.
+ lines.append(f'??? note "Variants ({len(variant_files)})"')
lines.append("")
- for v in sorted(variant_files, key=lambda x: x["name"]):
- vname = v["name"]
- vmd5 = v.get("md5", "unknown")
- vmd5_short = vmd5[:12] if vmd5 != "unknown" else "-"
- lines.append(
- f' - `{vname}` '
- f''
- f"MD5: {vmd5_short}..."
+ for v in sorted(variant_files, key=lambda x: (x["name"], x["path"])):
+ lines.extend(
+ f" {line}" if line else ""
+ for line in _system_file_card(v, consumers)
)
lines.append("")
diff --git a/tests/test_site_exports.py b/tests/test_site_exports.py
index 968f0550..bfc12912 100644
--- a/tests/test_site_exports.py
+++ b/tests/test_site_exports.py
@@ -330,5 +330,32 @@ class APlatformPageSaysWhereEachFileGoes(unittest.TestCase):
self.assertIn(f"- `IPL.bin` at `dolphin-emu/Sys/GC/{region}/IPL.bin` - OK",
"\n".join(lines))
+
+class AVariantShowsWhoPinsIt(unittest.TestCase):
+ """A .variants/ file showed a name and a truncated MD5: the advision.zip
+ Batocera and RetroBat pin named no platform."""
+
+ def test_the_variant_card_names_its_readers(self):
+ import types # noqa: PLC0415
+
+ import generate_site # noqa: PLC0415
+
+ primary = {"name": "advision.zip", "path": "bios/Entex/Adventure Vision/advision.zip",
+ "sha1": "a" * 40, "md5": "b" * 32, "size": 3000}
+ variant = {"name": "advision.zip",
+ "path": "bios/Entex/Adventure Vision/.variants/advision.zip.1c086064",
+ "sha1": "c" * 40, "md5": "1c086064" + "0" * 24, "size": 3000,
+ "provenance": {"tosec": {"name": "x"}}}
+ consumers = types.SimpleNamespace(
+ platforms={"c" * 40: {"batocera", "retrobat"}}, emulators={"a" * 40: {"mame"}})
+ page = generate_site.generate_system_page(
+ "Entex", {"Adventure Vision": [primary, variant]}, consumers)
+ block = page[page.index('??? note "Variants (1)"'):]
+ self.assertIn(" - Stored as: `advision.zip.1c086064`", block)
+ self.assertIn("[batocera](../platforms/batocera.md)", block)
+ self.assertIn("[retrobat](../platforms/retrobat.md)", block)
+ self.assertIn('title="' + "c" * 40 + '"', block)
+ self.assertIn("Verified dump", block)
+
if __name__ == "__main__":
unittest.main()