File size: 1,799 Bytes
22b729d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
from __future__ import annotations

import json
from pathlib import Path

from jsonschema import Draft202012Validator

ROOT = Path(__file__).resolve().parents[1]
SCHEMA_DIR = ROOT / "packages" / "contracts" / "schemas"
EXAMPLE_DIR = ROOT / "packages" / "contracts" / "examples"

EXAMPLE_TO_SCHEMA = {
    "idea-request.json": "idea-request.schema.json",
    "blueprint-candidate.json": "blueprint-candidate.schema.json",
    "blueprint-result.json": "blueprint-result.schema.json",
    "matrix-bundle.json": "matrix-bundle.schema.json",
    "bundle.json": "matrix-bundle.schema.json",
    "bundle-manifest.json": "bundle-manifest.schema.json",
    "prompt-pack.json": "prompt-pack.schema.json",
    "validation-report.json": "validation-report.schema.json",
    "publication.json": "publication.schema.json",
}


def load_json(path: Path) -> object:
    return json.loads(path.read_text(encoding="utf-8"))


def main() -> None:
    for schema_path in sorted(SCHEMA_DIR.glob("*.schema.json")):
        schema = load_json(schema_path)
        Draft202012Validator.check_schema(schema)

    for example_name, schema_name in EXAMPLE_TO_SCHEMA.items():
        example_path = EXAMPLE_DIR / example_name
        schema_path = SCHEMA_DIR / schema_name
        if not example_path.exists():
            raise SystemExit(f"Missing example: {example_path}")
        validator = Draft202012Validator(load_json(schema_path))
        errors = sorted(validator.iter_errors(load_json(example_path)), key=lambda error: list(error.path))
        if errors:
            formatted = "\n".join(f"{example_name}: {'/'.join(map(str, error.path))}: {error.message}" for error in errors)
            raise SystemExit(formatted)

    print("Contract schemas and examples are valid.")


if __name__ == "__main__":
    main()