feat(cli): parse toml config and dispatch actions

This commit is contained in:
csh 2026-01-23 14:24:07 +08:00
parent 05903c33ae
commit 8cfcc25f98
3 changed files with 66 additions and 0 deletions

View File

@ -52,6 +52,12 @@ PlaybookTSL`.tsl`/`.tsf`+ C++ + Python + Markdown代码格式化
### 快速部署
统一入口(配置驱动,示例见 `playbook.toml.example`
```bash
python scripts/playbook.py -config playbook.toml
```
使用 `sync_templates` 脚本一键部署项目架构:
```bash

View File

@ -1,11 +1,26 @@
#!/usr/bin/env python3
import sys
from pathlib import Path
import tomllib
ORDER = ["vendor", "sync_templates", "sync_standards", "install_skills", "format_md"]
def usage() -> str:
return "Usage:\n python scripts/playbook.py -config <path>\n python scripts/playbook.py -h"
def load_config(path: Path) -> dict:
return tomllib.loads(path.read_text(encoding="utf-8"))
def run_action(name: str, config: dict, context: dict) -> int:
_ = config, context
print(f"[action] {name}")
return 0
def main(argv: list[str]) -> int:
if "-h" in argv or "-help" in argv:
print(usage())
@ -13,6 +28,31 @@ def main(argv: list[str]) -> int:
if "-config" not in argv:
print("ERROR: -config is required.\n" + usage(), file=sys.stderr)
return 2
idx = argv.index("-config")
if idx + 1 >= len(argv) or not argv[idx + 1]:
print("ERROR: -config requires a path.\n" + usage(), file=sys.stderr)
return 2
config_path = Path(argv[idx + 1]).expanduser()
if not config_path.is_file():
print(f"ERROR: config not found: {config_path}", file=sys.stderr)
return 2
config = load_config(config_path)
playbook_config = config.get("playbook", {})
project_root = playbook_config.get("project_root")
if project_root:
root = Path(project_root).expanduser()
else:
root = config_path.parent
context = {"project_root": root.resolve(), "config_path": config_path.resolve()}
for name in ORDER:
if name in config:
result = run_action(name, config[name], context)
if result != 0:
return result
return 0

View File

@ -1,5 +1,6 @@
import subprocess
import sys
import tempfile
import unittest
from pathlib import Path
@ -26,6 +27,25 @@ class PlaybookCliTests(unittest.TestCase):
self.assertNotEqual(result.returncode, 0)
self.assertIn("-config", result.stdout + result.stderr)
def test_action_order(self):
config_body = """
[playbook]
project_root = "."
[format_md]
[sync_standards]
langs = ["tsl"]
"""
with tempfile.TemporaryDirectory() as tmp_dir:
config_path = Path(tmp_dir) / "playbook.toml"
config_path.write_text(config_body, encoding="utf-8")
result = run_cli("-config", str(config_path))
self.assertEqual(result.returncode, 0)
output = result.stdout + result.stderr
self.assertIn("sync_standards", output)
self.assertIn("format_md", output)
if __name__ == "__main__":
unittest.main()