diff --git a/platforms/_data_dirs.yml b/platforms/_data_dirs.yml index 731e8b72..2d0acd79 100644 --- a/platforms/_data_dirs.yml +++ b/platforms/_data_dirs.yml @@ -65,6 +65,16 @@ data_directories: local_cache: data/pcsx2-resources description: "PCSX2 resources (GameIndex.yaml, RedumpDatabase.yaml, fonts, shaders, icons, sounds)" + # ref: pcsx2-libretro/Main.cpp:157-158 (yaps2) - system/pcsx2/resources/ + # yaps2's own bin/resources at the revision its profile is pinned to. + yaps2-resources: + source_url: "https://github.com/yaps2/yaps2/archive/{version}.tar.gz" + source_type: tarball + source_path: "yaps2-{version}/bin/resources" + version: 57ea93c0ce8306063b31fe6658dab6b492bbedfe + local_cache: data/yaps2-resources + description: "yaps2 resources (GameIndex.yaml, RedumpDatabase.yaml, fonts, shaders, icons, sounds)" + # ref: src/Cafe/GameProfile/GameProfile.cpp:181-195 — Cemu/gameProfiles/default/ cemu-gameprofiles: source_url: "https://github.com/cemu-project/Cemu/archive/{version}.tar.gz" diff --git a/scripts/validate_schemas.py b/scripts/validate_schemas.py index 952884da..8f7c30ed 100644 --- a/scripts/validate_schemas.py +++ b/scripts/validate_schemas.py @@ -165,6 +165,38 @@ def _unreachable_citations(path: Path, document: object) -> list[str]: return out +def _unknown_data_dir_refs() -> list[str]: + """data_directories refs the registry does not define. + + A ref nobody registers is never fetched: yaps2 named yaps2-resources and + every run printed "not cached" while refresh_data_dirs had nothing to + refresh. + """ + registry_path = ROOT / "platforms" / "_data_dirs.yml" + with registry_path.open(encoding="utf-8") as handle: + registered = set((yaml_load(handle) or {}).get("data_directories", {})) + out: list[str] = [] + for directory in (ROOT / "emulators", ROOT / "platforms"): + for path in sorted(directory.glob("*.yml")): + if path.name.startswith("_"): + continue + with path.open(encoding="utf-8") as handle: + document = yaml_load(handle) or {} + systems = document.get("systems") + holders = [document, *(systems.values() if isinstance(systems, dict) else [])] + for holder in holders: + if not isinstance(holder, dict): + continue + for entry in holder.get("data_directories") or []: + ref = entry.get("ref") if isinstance(entry, dict) else None + if ref and ref not in registered: + out.append( + f"{path.relative_to(ROOT)}: data directory {ref!r} " + f"is not in platforms/_data_dirs.yml" + ) + return out + + def _semantic_envelope_checks(path: Path, document: dict) -> list[str]: if document.get("count") != len(document.get("items", [])): return [f"{path.relative_to(ROOT)}: count does not equal len(items)"] @@ -240,6 +272,7 @@ def main() -> int: ROOT / "platforms", "platform.schema.json", skip_private=True ) ) + errors.extend(_unknown_data_dir_refs()) if not args.source_only: database_path = ROOT / "database.json" diff --git a/tests/test_data_dir_refs.py b/tests/test_data_dir_refs.py new file mode 100644 index 00000000..ae9fc4f7 --- /dev/null +++ b/tests/test_data_dir_refs.py @@ -0,0 +1,27 @@ +"""Every data_directories ref names a registered data directory. + +yaps2 referenced yaps2-resources, absent from _data_dirs.yml: the pack and +verify only said "not cached" and refresh_data_dirs had nothing to fetch. +""" + +from __future__ import annotations + +import sys +import unittest +from pathlib import Path + +REPO_ROOT = Path(__file__).resolve().parents[1] +sys.path.insert(0, str(REPO_ROOT / "scripts")) + + +class DataDirRefsAreRegistered(unittest.TestCase): + def test_no_unknown_ref(self): + try: + import validate_schemas + except ImportError as exc: + self.skipTest(f"validate_schemas needs jsonschema: {exc}") + self.assertEqual(validate_schemas._unknown_data_dir_refs(), []) + + +if __name__ == "__main__": + unittest.main()