feat: add contributor credit to site platform pages

This commit is contained in:
Abdessamad Derraz
2026-04-02 11:42:31 +02:00
parent ded903ed7a
commit fd4606885e

View File

@@ -497,6 +497,17 @@ def generate_platform_page(
lines.append(f"| BIOS path | `{base_dest}/` |") lines.append(f"| BIOS path | `{base_dest}/` |")
if homepage: if homepage:
lines.append(f"| Homepage | [{homepage}]({homepage}) |") lines.append(f"| Homepage | [{homepage}]({homepage}) |")
contrib_list = (registry or {}).get(name, {}).get("contributed_by", [])
if contrib_list:
for cb in contrib_list:
username = cb.get("username", "")
contribution = cb.get("contribution", "")
pr = cb.get("pr")
pr_link = f" ([#{pr}]({REPO_URL}/pull/{pr}))" if pr else ""
lines.append(
f"| Contributed by | [@{username}](https://github.com/{username})"
f" - {contribution}{pr_link} |"
)
lines.extend( lines.extend(
[ [
"", "",
@@ -865,7 +876,11 @@ def generate_emulators_index(profiles: dict) -> str:
def generate_emulator_page( def generate_emulator_page(
name: str, profile: dict, db: dict, platform_files: dict | None = None name: str,
profile: dict,
db: dict,
platform_files: dict | None = None,
data_names: set[str] | None = None,
) -> str: ) -> str:
if profile.get("type") == "alias": if profile.get("type") == "alias":
parent = profile.get("alias_of", profile.get("bios_identical_to", "unknown")) parent = profile.get("alias_of", profile.get("bios_identical_to", "unknown"))
@@ -1022,15 +1037,52 @@ def generate_emulator_page(
] ]
) )
else: else:
from cross_reference import _resolve_source
by_name = db.get("indexes", {}).get("by_name", {}) by_name = db.get("indexes", {}).get("by_name", {})
db.get("files", {}) by_name_lower = {k.lower(): k for k in by_name}
by_path_suffix = db.get("indexes", {}).get("by_path_suffix", {})
by_md5 = db.get("indexes", {}).get("by_md5", {})
db_files = db.get("files", {})
def _file_available(f: dict) -> bool:
"""Check if a file is available using the same resolution as cross_reference."""
fname = f.get("name", "")
if not fname:
return False
storage = f.get("storage", "")
if storage in ("release", "large_file"):
return True
src = _resolve_source(
fname, by_name, by_name_lower, data_names, by_path_suffix,
)
if src is not None:
return True
path_field = f.get("path", "")
if path_field and path_field != fname:
src = _resolve_source(
path_field, by_name, by_name_lower, data_names,
by_path_suffix,
)
if src is not None:
return True
md5_raw = f.get("md5", "")
if md5_raw:
for md5_val in md5_raw.split(","):
md5_val = md5_val.strip().lower()
if md5_val and by_md5.get(md5_val):
return True
sha1 = f.get("sha1", "")
if sha1 and sha1 in db_files:
return True
return False
# Stats by category # Stats by category
bios_files = [f for f in files if f.get("category", "bios") == "bios"] bios_files = [f for f in files if f.get("category", "bios") == "bios"]
game_data = [f for f in files if f.get("category") == "game_data"] game_data = [f for f in files if f.get("category") == "game_data"]
bios_zips = [f for f in files if f.get("category") == "bios_zip"] bios_zips = [f for f in files if f.get("category") == "bios_zip"]
in_repo_count = sum(1 for f in files if f.get("name", "") in by_name) in_repo_count = sum(1 for f in files if _file_available(f))
missing_count = len(files) - in_repo_count missing_count = len(files) - in_repo_count
req_count = sum(1 for f in files if f.get("required")) req_count = sum(1 for f in files if f.get("required"))
opt_count = len(files) - req_count opt_count = len(files) - req_count
@@ -1058,7 +1110,7 @@ def generate_emulator_page(
for f in files: for f in files:
fname = f.get("name", "") fname = f.get("name", "")
required = f.get("required", False) required = f.get("required", False)
in_repo = fname in by_name in_repo = _file_available(f)
source_ref = f.get("source_ref", "") source_ref = f.get("source_ref", "")
mode = f.get("mode", "") mode = f.get("mode", "")
hle = f.get("hle_fallback", False) hle = f.get("hle_fallback", False)
@@ -1504,19 +1556,32 @@ def generate_gap_analysis(
# ---- Section 3: Core complement (cross-reference provenance) ---- # ---- Section 3: Core complement (cross-reference provenance) ----
from common import expand_platform_declared_names
all_declared: set[str] = set() all_declared: set[str] = set()
declared: dict[str, set[str]] = {} declared: dict[str, set[str]] = {}
for _name, cov in coverages.items(): for _name, cov in coverages.items():
config = cov["config"] config = cov["config"]
# Enrich with alias resolution (MD5 -> SHA1 -> canonical name + aliases)
all_declared.update(expand_platform_declared_names(config, db))
for sys_id, system in config.get("systems", {}).items(): for sys_id, system in config.get("systems", {}).items():
for fe in system.get("files", []): for fe in system.get("files", []):
fname = fe.get("name", "") fname = fe.get("name", "")
if fname: if fname:
declared.setdefault(sys_id, set()).add(fname) declared.setdefault(sys_id, set()).add(fname)
all_declared.add(fname)
# Only include profiles relevant to at least one platform
unique_profiles = {
k: v
for k, v in profiles.items()
if v.get("type") not in ("alias", "test")
}
relevant_set: set[str] = set()
for _name, cov in coverages.items():
matched = resolve_platform_cores(cov["config"], unique_profiles)
relevant_set.update(matched)
active_profiles = { active_profiles = {
k: v for k, v in profiles.items() if v.get("type") != "alias" k: v for k, v in unique_profiles.items() if k in relevant_set
} }
report = run_cross_reference( report = run_cross_reference(
@@ -2190,7 +2255,7 @@ def main():
str(docs / "emulators" / "index.md"), generate_emulators_index(profiles) str(docs / "emulators" / "index.md"), generate_emulators_index(profiles)
) )
for name, profile in profiles.items(): for name, profile in profiles.items():
page = generate_emulator_page(name, profile, db, platform_files) page = generate_emulator_page(name, profile, db, platform_files, suppl_names)
write_if_changed(str(docs / "emulators" / f"{name}.md"), page) write_if_changed(str(docs / "emulators" / f"{name}.md"), page)
# Generate cross-reference page # Generate cross-reference page