✨ feat(cli): parse toml config and dispatch actions
This commit is contained in:
parent
05903c33ae
commit
8cfcc25f98
|
|
@ -52,6 +52,12 @@ Playbook:TSL(`.tsl`/`.tsf`)+ C++ + Python + Markdown(代码格式化)
|
|||
|
||||
### 快速部署
|
||||
|
||||
统一入口(配置驱动,示例见 `playbook.toml.example`):
|
||||
|
||||
```bash
|
||||
python scripts/playbook.py -config playbook.toml
|
||||
```
|
||||
|
||||
使用 `sync_templates` 脚本一键部署项目架构:
|
||||
|
||||
```bash
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
Loading…
Reference in New Issue