mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-10-25 13:19:03 -05:00
chore: merge the engine options round
This commit is contained in:
commit
6f958382b7
12 files changed
+1581
-47
No files matched your search
@@ -0,0 +1,114 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Write schemas/install-events.schema.json from install.py's EVENT_KEYS.
|
||||
|
||||
python scripts/generate_event_schema.py rewrite the schema
|
||||
python scripts/generate_event_schema.py --check exit 1 when it is stale
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import importlib.util
|
||||
import json
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parent.parent
|
||||
OUTPUT = ROOT / "schemas" / "install-events.schema.json"
|
||||
|
||||
_spec = importlib.util.spec_from_file_location("install", ROOT / "install.py")
|
||||
_install = importlib.util.module_from_spec(_spec)
|
||||
_spec.loader.exec_module(_install)
|
||||
|
||||
EVENT_KEYS: dict[str, tuple[str, ...]] = _install.EVENT_KEYS
|
||||
EVENT_SCHEMA: int = _install.EVENT_SCHEMA
|
||||
|
||||
_TEXT = {"type": "string"}
|
||||
_COUNT = {"type": "integer", "minimum": 0}
|
||||
_FLAG = {"type": "boolean"}
|
||||
_NAMES = {"type": "array", "items": {"type": "string"}}
|
||||
_RECORDS = {"type": "array", "items": {"type": "object"}}
|
||||
|
||||
# The JSON type of each key, whatever kind carries it. A key EVENT_KEYS
|
||||
# gains without a line here stops the generator.
|
||||
KEY_TYPES: dict[str, dict] = {
|
||||
**dict.fromkeys((
|
||||
"installer", "os", "os_name", "stage", "reason", "platform", "message",
|
||||
"folder", "dest", "system", "name", "bios_dir", "path", "member",
|
||||
), _TEXT),
|
||||
"mode": {"enum": ["install", "check", "dry-run", "list"]},
|
||||
"state": {"enum": ["present", "wrong_hash", "missing"]},
|
||||
**dict.fromkeys((
|
||||
"files", "files_done", "files_total", "bytes", "bytes_done", "bytes_total",
|
||||
"bytes_local", "bytes_network", "size", "present", "missing", "wrong_hash",
|
||||
"bytes_needed", "data_missing", "not_installable", "installed", "up_to_date",
|
||||
"pending", "code",
|
||||
), _COUNT),
|
||||
**dict.fromkeys(("truncated", "ok", "interrupted"), _FLAG),
|
||||
**dict.fromkeys(("systems", "other_drives", "dests"), _NAMES),
|
||||
**dict.fromkeys(("platforms", "failed", "skipped", "left_out", "kept"), _RECORDS),
|
||||
}
|
||||
|
||||
|
||||
def _kind(kind: str, keys: tuple[str, ...]) -> dict:
|
||||
properties: dict[str, dict] = {"event": {"const": kind}}
|
||||
for key in keys:
|
||||
properties[key] = (
|
||||
{"const": EVENT_SCHEMA} if (kind, key) == ("start", "schema") else KEY_TYPES[key]
|
||||
)
|
||||
return {
|
||||
"type": "object",
|
||||
"additionalProperties": False,
|
||||
"required": ["event", *keys],
|
||||
"properties": properties,
|
||||
}
|
||||
|
||||
|
||||
def build_schema() -> dict:
|
||||
"""One line of the stream: an object of one of the kinds, with exactly its keys."""
|
||||
return {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://abdess.github.io/retrobios/api/v1/schemas/install-events.schema.json",
|
||||
"title": "RetroBIOS installer event",
|
||||
"description": (
|
||||
f"One line of install.py --events, event schema {EVENT_SCHEMA}. Written from "
|
||||
"EVENT_KEYS in install.py by scripts/generate_event_schema.py. The schema "
|
||||
"gains kinds, never keys on an existing kind: a reader skips a kind it "
|
||||
"does not know."
|
||||
),
|
||||
"type": "object",
|
||||
"required": ["event"],
|
||||
"properties": {"event": {"enum": list(EVENT_KEYS)}},
|
||||
"oneOf": [{"$ref": f"#/$defs/{kind}"} for kind in EVENT_KEYS],
|
||||
"$defs": {kind: _kind(kind, keys) for kind, keys in EVENT_KEYS.items()},
|
||||
}
|
||||
|
||||
|
||||
def render(schema: dict) -> str:
|
||||
return json.dumps(schema, indent=2, ensure_ascii=False) + "\n"
|
||||
|
||||
|
||||
def main(argv: list[str] | None = None) -> int:
|
||||
parser = argparse.ArgumentParser(allow_abbrev=False, description=__doc__,
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter)
|
||||
parser.add_argument("--check", action="store_true",
|
||||
help="exit 1 when the file differs from EVENT_KEYS, writing nothing")
|
||||
parser.add_argument("--output", type=Path, default=OUTPUT, help=argparse.SUPPRESS)
|
||||
args = parser.parse_args(argv)
|
||||
text = render(build_schema())
|
||||
current = args.output.read_text(encoding="utf-8") if args.output.is_file() else None
|
||||
if current == text:
|
||||
return 0
|
||||
if args.check:
|
||||
print(f"{args.output} differs from EVENT_KEYS: run "
|
||||
"python scripts/generate_event_schema.py", file=sys.stderr)
|
||||
return 1
|
||||
args.output.write_text(text, encoding="utf-8")
|
||||
print(f"Wrote {args.output}")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
from common import run_cli
|
||||
|
||||
run_cli(main)
|
||||
@@ -554,6 +554,23 @@ def _semantic_install_checks(path: Path, manifest: dict) -> list[str]:
|
||||
return out
|
||||
|
||||
|
||||
def _event_schema_errors() -> list[str]:
|
||||
"""install-events.schema.json is EVENT_KEYS written out, and a valid schema."""
|
||||
import generate_event_schema # noqa: PLC0415
|
||||
|
||||
path = ROOT / "schemas" / generate_event_schema.OUTPUT.name
|
||||
label = path.relative_to(ROOT).as_posix()
|
||||
if not path.is_file():
|
||||
return [f"{label}: missing, run python scripts/generate_event_schema.py"]
|
||||
if path.read_text(encoding="utf-8") != generate_event_schema.render(
|
||||
generate_event_schema.build_schema()
|
||||
):
|
||||
return [f"{label}: differs from EVENT_KEYS in install.py, run "
|
||||
"python scripts/generate_event_schema.py"]
|
||||
Draft202012Validator.check_schema(_load_json(path))
|
||||
return []
|
||||
|
||||
|
||||
def unchecked_formats() -> list[str]:
|
||||
"""Formats the schemas declare that this jsonschema install cannot check.
|
||||
|
||||
@@ -598,6 +615,7 @@ def main() -> int:
|
||||
errors.extend(_repository_layout_in_profiles())
|
||||
errors.extend(_save_directory_blocks())
|
||||
errors.extend(_registry_contract())
|
||||
errors.extend(_event_schema_errors())
|
||||
|
||||
if not args.source_only:
|
||||
database_path = ROOT / "database.json"
|
||||
|
||||
Reference in new issue
Block a user