|
12 | 12 |
|
13 | 13 | import ast |
14 | 14 | import json |
| 15 | +import sys |
15 | 16 | import subprocess |
16 | 17 | from dataclasses import dataclass, field |
17 | 18 | from pathlib import Path |
@@ -391,6 +392,26 @@ class PlaybookEntry: |
391 | 392 | ] |
392 | 393 |
|
393 | 394 |
|
| 395 | +def validate_playbook_examples(): |
| 396 | + """Check that all curated examples exist and error if any are missing""" |
| 397 | + missing = [] |
| 398 | + for entry in PLAYBOOK_EXAMPLES: |
| 399 | + case_path = EXAMPLES_DIR / entry.case_dir / "case.py" |
| 400 | + if not case_path.exists(): |
| 401 | + missing.append(entry.case_dir) |
| 402 | + |
| 403 | + if missing: |
| 404 | + print("=" * 70, file=sys.stderr) |
| 405 | + print("ERROR: Missing playbook examples:", file=sys.stderr) |
| 406 | + for example in missing: |
| 407 | + print(f" - {example}", file=sys.stderr) |
| 408 | + print("\nPlease update PLAYBOOK_EXAMPLES in:", file=sys.stderr) |
| 409 | + print(f" {Path(__file__).relative_to(REPO_ROOT)}", file=sys.stderr) |
| 410 | + print("\nRemove the missing examples from the list or restore them.", file=sys.stderr) |
| 411 | + print("=" * 70, file=sys.stderr) |
| 412 | + sys.exit(1) |
| 413 | + |
| 414 | + |
394 | 415 | def load_case_params(case_dir: str) -> Dict[str, Any]: |
395 | 416 | """Load parameters from a case.py file""" |
396 | 417 | case_path = EXAMPLES_DIR / case_dir / "case.py" |
@@ -572,6 +593,9 @@ def generate_playbook() -> str: |
572 | 593 | """Generate complete playbook from curated examples""" |
573 | 594 | lines = [] |
574 | 595 |
|
| 596 | + # Validate examples - will exit(1) if any are missing |
| 597 | + validate_playbook_examples() |
| 598 | + |
575 | 599 | lines.append("## 🧩 Case Design Playbook\n") |
576 | 600 | lines.append( |
577 | 601 | "> **Learn by example:** The cases below are curated from MFC's `examples/` " |
|
0 commit comments