mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-11-06 01:53:56 -06:00
feat: refuse an arcade index off its profile pin
This commit is contained in:
1 parent
f0afe6a6fb
commit
673e70d791
3 files changed
+57
No files matched your search
@@ -701,6 +701,34 @@ def _games_source_errors() -> list[str]:
|
||||
return out
|
||||
|
||||
|
||||
def _arcade_pin_errors() -> list[str]:
|
||||
"""games/arcade/<profile>.json read at the revision and version its
|
||||
profile pins. A bump of the profile left the game-to-BIOS map of the old
|
||||
code in place, and the installer kept serving it."""
|
||||
out: list[str] = []
|
||||
for path in sorted((ROOT / "games" / "arcade").glob("*.json")):
|
||||
doc = _load_json(path)
|
||||
profile_path = ROOT / "emulators" / f"{doc.get('profile')}.yml"
|
||||
label = str(path.relative_to(ROOT))
|
||||
if not profile_path.is_file():
|
||||
out.append(f"{label}: no profile emulators/{profile_path.name}")
|
||||
continue
|
||||
profile = _load_source(profile_path) or {}
|
||||
pinned = profile.get("source_commit")
|
||||
pins = set(pinned.values()) if isinstance(pinned, dict) else {pinned}
|
||||
commit = (doc.get("source") or {}).get("commit")
|
||||
drifted = []
|
||||
if commit and commit not in pins:
|
||||
drifted.append(f"read at {commit[:12]}, the profile pins {pinned}")
|
||||
if doc.get("core_version") != profile.get("core_version"):
|
||||
drifted.append(f"core_version {doc.get('core_version')!r}, "
|
||||
f"the profile says {profile.get('core_version')!r}")
|
||||
if drifted:
|
||||
out.append(f"{label}: {'; '.join(drifted)} "
|
||||
f"(python -m scripts.scraper.arcade_parent_importer --profile {doc.get('profile')})")
|
||||
return out
|
||||
|
||||
|
||||
def _games_index_errors() -> list[str]:
|
||||
"""install/games/: each document against its kind, and the index
|
||||
against the files it lists (size and sha256)."""
|
||||
@@ -765,6 +793,7 @@ def main() -> int:
|
||||
errors.extend(_measurement_errors())
|
||||
errors.extend(_romfolder_errors())
|
||||
errors.extend(_games_source_errors())
|
||||
errors.extend(_arcade_pin_errors())
|
||||
|
||||
if not args.source_only:
|
||||
database_path = ROOT / "database.json"
|
||||
|
||||
@@ -401,6 +401,30 @@ class CommittedIndex(unittest.TestCase):
|
||||
errors = list(validator.iter_errors(json.loads(path.read_text(encoding="utf-8"))))
|
||||
self.assertEqual(errors, [])
|
||||
|
||||
@unittest.skipIf(Draft202012Validator is None, "jsonschema not installed")
|
||||
def test_each_file_is_read_at_its_profile_pin(self) -> None:
|
||||
"""A bumped profile kept the game-to-BIOS map of the old code."""
|
||||
import sys
|
||||
from unittest import mock
|
||||
|
||||
sys.path.insert(0, str(ROOT / "scripts"))
|
||||
import validate_schemas
|
||||
|
||||
self.assertEqual(validate_schemas._arcade_pin_errors(), [])
|
||||
with tempfile.TemporaryDirectory(dir=TMP_ROOT) as tmp:
|
||||
root = Path(tmp)
|
||||
(root / "games" / "arcade").mkdir(parents=True)
|
||||
(root / "emulators").mkdir()
|
||||
(root / "emulators" / "core.yml").write_text(
|
||||
f"source_commit: {'b' * 40}\ncore_version: '0.2'\n")
|
||||
(root / "games" / "arcade" / "core.json").write_text(json.dumps(
|
||||
{"profile": "core", "core_version": "0.1", "source": {"commit": COMMIT}}))
|
||||
with mock.patch.object(validate_schemas, "ROOT", root):
|
||||
(error,) = validate_schemas._arcade_pin_errors()
|
||||
self.assertIn("read at aaaaaaaaaaaa", error)
|
||||
self.assertIn("core_version '0.1'", error)
|
||||
self.assertIn("arcade_parent_importer --profile core", error)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -1644,6 +1644,10 @@ keeps, is computed from `install/<platform>.json` with the installer's own
|
||||
core narrowing. Every published file is listed in `install/games/index.json`
|
||||
with its size, its gzip size and its sha256.
|
||||
|
||||
`validate_schemas.py` refuses a `games/arcade/<profile>.json` whose source
|
||||
commit or `core_version` is not the one its profile pins: after a profile's pin
|
||||
moves, rerun `arcade_parent_importer --profile NAME`.
|
||||
|
||||
## Target scrapers
|
||||
|
||||
Located in `scripts/scraper/targets/`. Each inherits `BaseTargetScraper` and implements `fetch_targets()`.
|
||||
|
||||
Reference in new issue
Block a user