refactor: make simple write to CI, no check

This commit is contained in:
Musa 2026-02-17 12:37:33 -08:00
parent 7036c4597d
commit c435de3ffb
3 changed files with 18 additions and 68 deletions

View file

@ -46,8 +46,8 @@ jobs:
- name: Install plano tools - name: Install plano tools
run: uv sync --extra dev run: uv sync --extra dev
- name: Run CLI template/demo sync check - name: Sync CLI templates to demos
run: uv run python -m planoai.template_sync --check run: uv run python -m planoai.template_sync
- name: Run tests - name: Run tests
run: uv run pytest run: uv run pytest

View file

@ -76,16 +76,10 @@ uv run planoai <command> [options]
The CLI templates in `cli/planoai/templates/` are the source of truth for mapped The CLI templates in `cli/planoai/templates/` are the source of truth for mapped
demo `config.yaml` files. demo `config.yaml` files.
Use the sync utility to check drift: Use the sync utility to write mapped demo configs from templates:
```bash ```bash
uv run python -m planoai.template_sync --check uv run python -m planoai.template_sync
```
Auto-fix mapped demo configs:
```bash
uv run python -m planoai.template_sync --write
``` ```
### Optional: Manual Virtual Environment Activation ### Optional: Manual Virtual Environment Activation

View file

@ -1,10 +1,8 @@
from __future__ import annotations from __future__ import annotations
import argparse import argparse
import json
from dataclasses import dataclass from dataclasses import dataclass
from pathlib import Path from pathlib import Path
from typing import Any
import yaml import yaml
@ -40,10 +38,6 @@ def _load_sync_entries() -> list[SyncEntry]:
return entries return entries
def _normalize_yaml(text: str) -> Any:
return yaml.safe_load(text) if text.strip() else None
def _render_for_demo(template_text: str, transform: str) -> str: def _render_for_demo(template_text: str, transform: str) -> str:
if transform == "none": if transform == "none":
rendered = template_text rendered = template_text
@ -81,7 +75,7 @@ def _validate_manifest(entries: list[SyncEntry]) -> list[str]:
return errors return errors
def run_sync(*, write: bool, verbose: bool = False) -> int: def write_mapped_demo_configs(*, verbose: bool = False) -> int:
entries = _load_sync_entries() entries = _load_sync_entries()
manifest_errors = _validate_manifest(entries) manifest_errors = _validate_manifest(entries)
if manifest_errors: if manifest_errors:
@ -89,77 +83,39 @@ def run_sync(*, write: bool, verbose: bool = False) -> int:
print(f"[manifest] {error}") print(f"[manifest] {error}")
return 2 return 2
drift_count = 0 write_count = 0
for entry in entries: for entry in entries:
template_text = (TEMPLATES_DIR / entry.template_file).read_text( template_text = (TEMPLATES_DIR / entry.template_file).read_text(
encoding="utf-8" encoding="utf-8"
) )
expected_text = _render_for_demo(template_text, entry.transform) expected_text = _render_for_demo(template_text, entry.transform)
expected_yaml = _normalize_yaml(expected_text)
for demo_rel_path in entry.demo_configs: for demo_rel_path in entry.demo_configs:
demo_path = REPO_ROOT / demo_rel_path demo_path = REPO_ROOT / demo_rel_path
actual_text = demo_path.read_text(encoding="utf-8") # Keep this as a write-only sync step so CI behavior is deterministic.
actual_yaml = _normalize_yaml(actual_text) demo_path.write_text(expected_text, encoding="utf-8")
write_count += 1
if verbose:
print(
f"[wrote] {demo_rel_path} <- {entry.template_id} ({entry.template_file})"
)
if actual_yaml == expected_yaml: print(f"Wrote {write_count} mapped demo config(s) from CLI templates.")
if verbose: return 0
print(f"[ok] {demo_rel_path}")
continue
drift_count += 1
print(
f"[drift] {demo_rel_path} differs from template '{entry.template_id}' "
f"({entry.template_file})"
)
if write:
demo_path.write_text(expected_text, encoding="utf-8")
print(f"[fixed] wrote {demo_rel_path}")
elif verbose:
actual_repr = json.dumps(actual_yaml, indent=2, sort_keys=True)
expected_repr = json.dumps(expected_yaml, indent=2, sort_keys=True)
print(f"[actual]\n{actual_repr}\n[expected]\n{expected_repr}")
if drift_count == 0:
print("All mapped demo configs are in sync with CLI templates.")
return 0
if write:
print(f"Updated {drift_count} out-of-sync demo config(s).")
return 0
print(
f"Found {drift_count} out-of-sync demo config(s). "
"Run `python -m planoai.template_sync --write` to update."
)
return 1
def main() -> int: def main() -> int:
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
description="Check or sync CLI templates to demo config.yaml files." description="Sync CLI templates to mapped demo config.yaml files (write-only)."
)
mode_group = parser.add_mutually_exclusive_group()
mode_group.add_argument(
"--write",
action="store_true",
help="Write template content to mapped demo configs when drift is found.",
)
mode_group.add_argument(
"--check",
action="store_true",
help="Check for drift and return non-zero if any mapped demos are out of sync.",
) )
parser.add_argument( parser.add_argument(
"--verbose", "--verbose",
action="store_true", action="store_true",
help="Print per-file status and parsed YAML when drift is detected.", help="Print each file written during sync.",
) )
args = parser.parse_args() args = parser.parse_args()
write_mode = bool(args.write) return write_mapped_demo_configs(verbose=bool(args.verbose))
return run_sync(write=write_mode, verbose=bool(args.verbose))
if __name__ == "__main__": if __name__ == "__main__":