mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-10-29 15:17:20 -05:00
feat: draw site images from data, host them
scripts/sitediagrams.py writes the explainer, install flow, verification modes, MinUI card, pipeline and data layer diagrams as inline SVG from the registry, the platform files, the install manifests and the pipeline step list. A page asks for one with an image comment, which the decoration pass resolves. The two mermaid diagrams of the architecture page are replaced, so no page loads mermaid from unpkg. Platform logos and system icons are copied once by fetch_site_images.py with their source and owner recorded, and the build rewrites the remote links to the copies. validate_site refuses an image from another host. Three registry logos named a personal avatar instead of the project's (RomM, ROCKNIX, MiSTer FPGA) and MyMinUI's was a GitHub identicon, now dropped. One 1200x630 sharing card per section, a 404 page with search and the two entry pages, and a list of screenshots that need a real device.
This commit is contained in:
1 parent
f1c58820d1
commit
1b9ea86e1b
120 files changed
+1963
-176
No files matched your search
+18
-56
@@ -1,15 +1,10 @@
|
||||
"""Renderings shared by the site pages, and the icon cache they read.
|
||||
|
||||
No network: icon checks are answered by a stub.
|
||||
"""
|
||||
"""Renderings shared by the site pages, and the icon copies they read."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import sys
|
||||
import tempfile
|
||||
import unittest
|
||||
import urllib.error
|
||||
from pathlib import Path
|
||||
from unittest import mock
|
||||
|
||||
@@ -19,65 +14,32 @@ sys.path.insert(0, str(REPO_ROOT / "scripts"))
|
||||
import siterender # noqa: E402
|
||||
|
||||
|
||||
class _Served:
|
||||
status = 200
|
||||
|
||||
def __enter__(self) -> "_Served":
|
||||
return self
|
||||
|
||||
def __exit__(self, *exc: object) -> None:
|
||||
return None
|
||||
|
||||
|
||||
class IconCacheIsReplacedWhole(unittest.TestCase):
|
||||
"""The cache was truncated then dumped in place: a concurrent reader saw
|
||||
half a file, took it for empty, and an offline run then wrote ``{}``
|
||||
over every recorded icon."""
|
||||
class IconsComeFromTheLocalCopies(unittest.TestCase):
|
||||
"""Icons were checked against upstream with a HEAD request per system on
|
||||
every build, and linked from a branch tip. The build now reads the copies
|
||||
in docs_assets/system-icons and makes no request."""
|
||||
|
||||
def setUp(self) -> None:
|
||||
tmp = tempfile.TemporaryDirectory()
|
||||
self.addCleanup(tmp.cleanup)
|
||||
self.path = Path(tmp.name) / "system_icons.json"
|
||||
patcher = mock.patch.object(siterender, "ICON_CACHE_PATH", self.path)
|
||||
patcher.start()
|
||||
self.addCleanup(patcher.stop)
|
||||
saved = dict(siterender._icon_available)
|
||||
self.addCleanup(lambda: (siterender._icon_available.clear(),
|
||||
siterender._icon_available.update(saved)))
|
||||
|
||||
def test_an_offline_run_leaves_an_unreadable_cache_untouched(self):
|
||||
self.path.write_text('{"Sega - Mega Drive": tr')
|
||||
offline = mock.patch.object(
|
||||
siterender.urllib.request, "urlopen",
|
||||
side_effect=urllib.error.URLError("offline"))
|
||||
with offline, mock.patch("sys.stderr"), mock.patch("builtins.print"):
|
||||
siterender.prime_system_icons({"Sega - Mega Drive"})
|
||||
self.assertEqual(self.path.read_text(), '{"Sega - Mega Drive": tr')
|
||||
|
||||
def test_names_another_run_recorded_meanwhile_are_kept(self):
|
||||
self.path.write_text(json.dumps({"A - One": True}))
|
||||
|
||||
def answer(*_args: object, **_kwargs: object) -> _Served:
|
||||
# A second build records its own check while this one runs.
|
||||
self.path.write_text(json.dumps({"A - One": True, "C - Three": False}))
|
||||
return _Served()
|
||||
|
||||
with mock.patch.object(siterender.urllib.request, "urlopen", side_effect=answer), \
|
||||
def test_availability_is_the_folder(self):
|
||||
tmp = tempfile.TemporaryDirectory()
|
||||
self.addCleanup(tmp.cleanup)
|
||||
folder = Path(tmp.name) / "docs_assets" / "system-icons"
|
||||
folder.mkdir(parents=True)
|
||||
(folder / "A - One.png").write_bytes(b"png")
|
||||
with mock.patch.object(siterender, "ICON_DIR", folder), \
|
||||
mock.patch("builtins.print"):
|
||||
siterender.prime_system_icons({"A - One", "B - Two"})
|
||||
self.assertEqual(json.loads(self.path.read_text()),
|
||||
{"A - One": True, "B - Two": True, "C - Three": False})
|
||||
self.assertEqual(sorted(p.name for p in self.path.parent.iterdir()),
|
||||
["system_icons.json"])
|
||||
self.assertTrue(siterender._icon_available["A - One"])
|
||||
self.assertFalse(siterender._icon_available["B - Two"])
|
||||
self.assertEqual(siterender.system_icon_markdown("B", "Two"), "")
|
||||
self.assertIn("A%20-%20One.png", siterender.system_icon_markdown("A", "One"))
|
||||
|
||||
def test_the_write_goes_through_a_scratch_file(self):
|
||||
with mock.patch.object(siterender.urllib.request, "urlopen",
|
||||
return_value=_Served()), \
|
||||
mock.patch.object(siterender, "write_text_atomic",
|
||||
wraps=siterender.write_text_atomic) as atomic, \
|
||||
mock.patch("builtins.print"):
|
||||
siterender.prime_system_icons({"B - Two"})
|
||||
atomic.assert_called_once()
|
||||
def test_no_request_is_made(self):
|
||||
self.assertNotIn("urllib.request", (REPO_ROOT / "scripts" / "siterender.py").read_text())
|
||||
|
||||
|
||||
class EveryPageAddressesPlatformsAsPeers(unittest.TestCase):
|
||||
|
||||
Reference in new issue
Block a user