From d430d361d9dc0f9831ddd293ae770e9f939aaa70 Mon Sep 17 00:00:00 2001 From: Abdessamad Derraz <3028866+Abdess@users.noreply.github.com> Date: Sun, 18 Oct 2026 17:24:53 +0200 Subject: [PATCH] feat: link each emulator page to its profile --- scripts/generate_site.py | 14 ++++++++++++++ tests/test_site_exports.py | 15 +++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/scripts/generate_site.py b/scripts/generate_site.py index d3728a53..b151ec42 100644 --- a/scripts/generate_site.py +++ b/scripts/generate_site.py @@ -2960,6 +2960,12 @@ def generate_emulator_page( if revision: lines.append(f"| Revision | {revision} |") lines.append(f"| Profiled | {profiled} |") + # The YAML is the reusable document this site renders; the JSON is the + # same profile for a program. + lines.append( + f"| Profile | [YAML]({REPO_URL}/blob/main/emulators/{name}.yml), " + f"[JSON](../api/v1/emulators/{name}.json) |" + ) if cores: lines.append(f"| Cores | {', '.join(str(c) for c in cores)} |") if systems: @@ -4400,7 +4406,15 @@ def _generate(args: argparse.Namespace) -> None: for name, profile in profiles.items() if profile.get("type") not in ("alias", "test") } + (docs / "api" / "v1" / "emulators").mkdir(parents=True, exist_ok=True) for name, profile in public_profiles.items(): + # The profile itself, one small document per core: reusing one + # meant downloading emulators.json (5.9 MB) and filtering it. + write_if_changed( + str(docs / "api" / "v1" / "emulators" / f"{name}.json"), + json.dumps({"id": name, **profile}, indent=2, sort_keys=True, + ensure_ascii=False, default=str) + "\n", + ) page = generate_emulator_page(name, profile, db, consumers, suppl_names) PAGE_DATA[f"emulators/{name}.md"] = emulator_structured_data(profile) write_if_changed(str(docs / "emulators" / f"{name}.md"), page) diff --git a/tests/test_site_exports.py b/tests/test_site_exports.py index 97ec14ae..212af212 100644 --- a/tests/test_site_exports.py +++ b/tests/test_site_exports.py @@ -494,5 +494,20 @@ class PlatformPagesCarryTheirDeclarations(unittest.TestCase): self.assertTrue(part["url"].endswith("platforms/batocera/#sony-playstation")) + +class AnEmulatorPageLinksItsProfile(unittest.TestCase): + """A page rendered a profile without linking it: reusing raze.yml meant + guessing its path or filtering the 5.9 MB emulators.json.""" + + def test_links(self): + import generate_site + + page = generate_site.generate_emulator_page( + "raze", {"emulator": "Raze", "type": "standalone", "systems": [], "files": []}, + {"files": {}, "indexes": {}}, {}) + self.assertIn("/blob/main/emulators/raze.yml", page) + self.assertIn("(../api/v1/emulators/raze.json)", page) + + if __name__ == "__main__": unittest.main()