Files
le-mystere-professeur-zacus/tools/printables/validate_manifest.py
T

81 lines
2.5 KiB
Python
Executable File

#!/usr/bin/env python3
"""Validate printable manifest YAML files against expected prompts."""
from __future__ import annotations
import argparse
import sys
from pathlib import Path
try:
import yaml
except ImportError: # pragma: no cover
print("Missing dependency: install PyYAML (pip install pyyaml) to validate printables manifests.")
sys.exit(1)
BASE_DIR = Path("printables")
REQUIRED_MANIFEST_KEYS = ["manifest_id", "version", "scenario_id", "items"]
def load_manifest(path: Path) -> dict:
try:
return yaml.safe_load(path.read_text())
except yaml.YAMLError as exc:
raise ValueError(f"Invalid YAML in {path}: {exc}")
def validate_manifest(path: Path) -> list[str]:
manifest = load_manifest(path)
missing = [key for key in REQUIRED_MANIFEST_KEYS if key not in manifest]
if missing:
raise ValueError(f"Manifest missing keys: {', '.join(missing)}")
items = manifest.get("items")
if not isinstance(items, list) or not items:
raise ValueError("`items` must be a non-empty list")
errors: list[str] = []
for entry in items:
if not isinstance(entry, dict):
errors.append("manifest item must be a mapping")
continue
if "id" not in entry:
errors.append("manifest item missing `id`")
continue
if "prompt" not in entry:
errors.append(f"item {entry.get('id', '<unknown>')} missing `prompt`")
continue
prompt_path = BASE_DIR / entry["prompt"]
if not prompt_path.exists():
errors.append(f"missing prompt file for {entry['id']}: {prompt_path}")
return errors
def main() -> int:
parser = argparse.ArgumentParser(description="Validate printables manifest YAML files.")
parser.add_argument("manifest", nargs="?", default="printables/manifests/zacus_v1_printables.yaml")
args = parser.parse_args()
manifest_path = Path(args.manifest)
if not manifest_path.exists():
print(f"Manifest file not found: {manifest_path}")
return 1
try:
errors = validate_manifest(manifest_path)
except ValueError as exc:
print(f"[printables-validate] error: {exc}")
return 1
if errors:
for error in errors:
print(f"[printables-validate] missing: {error}")
return 1
print(f"[printables-validate] OK {manifest_path.name} items={len(load_manifest(manifest_path)['items'])}")
return 0
if __name__ == "__main__":
sys.exit(main())