fix: show unsourceable entries apart on the site

This commit is contained in:
Abdessamad Derraz committed 2026-10-06 12:53:10 +02:00
1 parent 0f293b6c14
commit 0b46880604
2 files changed
+77 -5

No files matched your search

+15 -5
View File
@@ -1873,11 +1873,15 @@ def _file_badges(f: dict, in_repo: bool) -> list[str]:
badges.append(
'<span class="rb-badge rb-badge-muted">optional</span>'
)
if not in_repo:
if not in_repo and f.get("unsourceable"):
badges.append(
'<span class="rb-badge rb-badge-muted">unsourceable</span>'
)
elif not in_repo:
badges.append(
'<span class="rb-badge rb-badge-warning">missing</span>'
)
elif in_repo:
else:
badges.append(
'<span class="rb-badge rb-badge-success">in repo</span>'
)
@@ -2236,7 +2240,9 @@ def _availability_check(db: dict, data_names):
def _file_available(f: dict) -> bool:
"""Check if a file is available using the same resolution as cross_reference."""
if not f.get("name"):
# cross_reference sets these aside before resolving: the file found
# under the name belongs to another game or release.
if not f.get("name") or f.get("unsourceable"):
return False
if f.get("storage", "") in ("release", "large_file"):
return True
@@ -2367,14 +2373,18 @@ def generate_emulator_page(
bios_zips = [f for f in files if f.get("category") == "bios_zip"]
in_repo_count = sum(1 for f in files if _file_available(f))
missing_count = len(files) - in_repo_count
unsourceable_count = sum(1 for f in files if f.get("unsourceable"))
missing_count = len(files) - in_repo_count - unsourceable_count
req_count = sum(1 for f in files if f.get("required"))
opt_count = len(files) - req_count
hle_count = sum(1 for f in files if f.get("hle_fallback"))
parts = [f"**{len(files)} files**"]
parts.append(f"{req_count} required, {opt_count} optional")
parts.append(f"{in_repo_count} in repo, {missing_count} missing")
held = f"{in_repo_count} in repo, {missing_count} missing"
if unsourceable_count:
held += f", {unsourceable_count} unsourceable"
parts.append(held)
if hle_count:
parts.append(f"{hle_count} with HLE fallback")
lines.append(" | ".join(parts))
+62
View File
@@ -0,0 +1,62 @@
"""An emulator page never shows an unsourceable entry as held.
The page resolved each entry by name without the `unsourceable:` check
cross_reference runs first: ioquake3's pak0.pk3 wore a green "in repo"
badge, served by the pak0.pk3 of another game, and 52 such entries read as
held across the site while the gaps page listed them as known absences.
"""
from __future__ import annotations
import sys
import unittest
from pathlib import Path
import yaml
REPO_ROOT = Path(__file__).resolve().parent.parent
sys.path.insert(0, str(REPO_ROOT / "scripts"))
from generate_site import _availability_check, _file_badges
SHA1 = "a" * 40
DB = {
"files": {SHA1: {"name": "pak0.pk3", "sha1": SHA1, "path": "bios/x/pak0.pk3"}},
"indexes": {"by_name": {"pak0.pk3": [SHA1]}},
}
class UnsourceableIsNotHeld(unittest.TestCase):
def test_a_homonym_does_not_stand_in(self):
available = _availability_check(DB, set())
self.assertTrue(available({"name": "pak0.pk3"}))
self.assertFalse(available({"name": "pak0.pk3", "unsourceable": "retail data"}))
def test_the_badge_says_why(self):
entry = {"name": "pak0.pk3", "unsourceable": "retail data"}
badges = " ".join(_file_badges(entry, False))
self.assertIn("unsourceable", badges)
self.assertNotIn(">missing<", badges)
self.assertNotIn("in repo", badges)
def test_no_profile_entry_is_shown_held(self):
from common import load_database
db_path = REPO_ROOT / "database.json"
if not db_path.exists():
self.skipTest("database.json is not built")
available = _availability_check(load_database(str(db_path)), set())
shown_held = []
for path in sorted((REPO_ROOT / "emulators").glob("*.yml")):
document = yaml.safe_load(path.read_text(encoding="utf-8")) or {}
shown_held.extend(
f"{path.stem}: {entry['name']}"
for entry in document.get("files") or []
if isinstance(entry, dict) and entry.get("unsourceable")
and available(entry)
)
self.assertEqual(shown_held, [])
if __name__ == "__main__":
unittest.main()