🔧 chore(playbook): split sync_templates into sections
This commit is contained in:
parent
278750e3c9
commit
73d5c261b1
19
README.md
19
README.md
|
|
@ -64,17 +64,20 @@ python scripts/playbook.py -config playbook.toml
|
|||
[playbook]
|
||||
project_root = "/path/to/project"
|
||||
|
||||
[sync_templates]
|
||||
[sync_rules]
|
||||
# force = true # 可选
|
||||
|
||||
[sync_memory_bank]
|
||||
project_name = "MyProject"
|
||||
full = false
|
||||
|
||||
[sync_prompts]
|
||||
```
|
||||
|
||||
**部署行为**:
|
||||
|
||||
- **新项目**:创建完整的 `AGENTS.md`、`AGENT_RULES.md`、`memory-bank/`、`docs/prompts/`
|
||||
- **已有 AGENTS.md**:追加路由链接(使用 `<!-- playbook:templates:start/end -->` 标记)
|
||||
- **full = true**:追加完整框架(规则优先级 + 新会话开始时)到已有 AGENTS.md
|
||||
- **其他文件**:如果已存在则跳过(使用 `force = true` 覆盖)
|
||||
- **配置节存在即启用**:只写需要同步的配置节
|
||||
- **AGENTS.md**:始终按区块更新(`<!-- playbook:xxx:start/end -->`)
|
||||
- **force**:默认 false,已存在则跳过;设为 true 时强制覆盖(会先备份)
|
||||
|
||||
详见:`templates/README.md`
|
||||
|
||||
|
|
@ -226,7 +229,9 @@ git commit -m ":package: deps(playbook): add tsl standards"
|
|||
[sync_standards]
|
||||
langs = ["tsl", "cpp"]
|
||||
|
||||
[sync_templates]
|
||||
[sync_rules]
|
||||
|
||||
[sync_memory_bank]
|
||||
project_name = "MyProject"
|
||||
```
|
||||
|
||||
|
|
|
|||
|
|
@ -11,13 +11,20 @@
|
|||
# langs = ["tsl"] # 可选:默认仅 tsl
|
||||
# target_dir = "docs/standards/playbook"
|
||||
|
||||
[sync_templates]
|
||||
[sync_rules]
|
||||
# 同步 AGENT_RULES.md(配置节存在即启用)
|
||||
# force = false # 可选:覆盖已有文件
|
||||
|
||||
[sync_memory_bank]
|
||||
# 同步 memory-bank/(配置节存在即启用)
|
||||
# project_name = "MyProject" # 可选:替换 {{PROJECT_NAME}}
|
||||
# main_language = "tsl" # 可选:替换 {{MAIN_LANGUAGE}}(未配置时取 sync_standards.langs[0],否则 tsl)
|
||||
# date = "2026-01-23" # 可选:替换 {{DATE}},默认今天
|
||||
# force = false # 可选:覆盖已有目录
|
||||
# force = false # 可选:覆盖已有目录(会先备份)
|
||||
# no_backup = false # 可选:跳过备份
|
||||
|
||||
[sync_prompts]
|
||||
# 同步 docs/prompts/(配置节存在即启用)
|
||||
# force = false # 可选:覆盖已有目录(会先备份)
|
||||
# no_backup = false # 可选:跳过备份
|
||||
# full = false # 可选:写入 framework 区块
|
||||
|
||||
[sync_standards]
|
||||
# langs = ["tsl", "cpp"] # 必填:要同步的语言
|
||||
|
|
|
|||
|
|
@ -10,7 +10,15 @@ try:
|
|||
except ModuleNotFoundError: # Python < 3.11
|
||||
tomllib = None
|
||||
|
||||
ORDER = ["vendor", "sync_templates", "sync_standards", "install_skills", "format_md"]
|
||||
ORDER = [
|
||||
"vendor",
|
||||
"sync_rules",
|
||||
"sync_memory_bank",
|
||||
"sync_prompts",
|
||||
"sync_standards",
|
||||
"install_skills",
|
||||
"format_md",
|
||||
]
|
||||
SCRIPT_DIR = Path(__file__).resolve().parent
|
||||
PLAYBOOK_ROOT = SCRIPT_DIR.parent
|
||||
|
||||
|
|
@ -503,15 +511,125 @@ def update_agents_section(
|
|||
log("Appended: AGENTS.md (section)")
|
||||
|
||||
|
||||
def sync_templates_action(config: dict, context: dict) -> int:
|
||||
def resolve_project_name(context: dict) -> str | None:
|
||||
config = context.get("config", {})
|
||||
if not isinstance(config, dict):
|
||||
return None
|
||||
memory_conf = config.get("sync_memory_bank")
|
||||
if isinstance(memory_conf, dict):
|
||||
raw = memory_conf.get("project_name")
|
||||
if raw is not None and str(raw).strip():
|
||||
return str(raw).strip()
|
||||
return None
|
||||
|
||||
|
||||
def resolve_template_date(context: dict) -> str:
|
||||
config = context.get("config", {})
|
||||
if isinstance(config, dict):
|
||||
for key in ("sync_rules", "sync_memory_bank", "sync_prompts"):
|
||||
section = config.get(key)
|
||||
if isinstance(section, dict):
|
||||
value = section.get("date")
|
||||
if value:
|
||||
return str(value)
|
||||
return datetime.now().strftime("%Y-%m-%d")
|
||||
|
||||
|
||||
def sync_agents_template(context: dict) -> int:
|
||||
project_root: Path = context["project_root"]
|
||||
if project_root.resolve() == PLAYBOOK_ROOT.resolve():
|
||||
log("Skip: playbook root equals project root.")
|
||||
return 0
|
||||
|
||||
templates_dir = PLAYBOOK_ROOT / "templates"
|
||||
if not templates_dir.is_dir():
|
||||
print(f"ERROR: templates not found: {templates_dir}", file=sys.stderr)
|
||||
agents_src = templates_dir / "AGENTS.template.md"
|
||||
if not agents_src.is_file():
|
||||
return 0
|
||||
|
||||
project_name = resolve_project_name(context)
|
||||
main_language = resolve_main_language({}, context)
|
||||
playbook_scripts = resolve_playbook_scripts(project_root, context)
|
||||
date_value = resolve_template_date(context)
|
||||
|
||||
agents_dst = project_root / "AGENTS.md"
|
||||
if agents_dst.exists():
|
||||
agents_text = agents_dst.read_text(encoding="utf-8")
|
||||
if "<!-- playbook:framework:start -->" in agents_text:
|
||||
start_marker = "<!-- playbook:framework:start -->"
|
||||
end_marker = "<!-- playbook:framework:end -->"
|
||||
elif "<!-- playbook:templates:start -->" in agents_text:
|
||||
start_marker = "<!-- playbook:templates:start -->"
|
||||
end_marker = "<!-- playbook:templates:end -->"
|
||||
else:
|
||||
start_marker = "<!-- playbook:templates:start -->"
|
||||
end_marker = "<!-- playbook:templates:end -->"
|
||||
else:
|
||||
start_marker = "<!-- playbook:framework:start -->"
|
||||
end_marker = "<!-- playbook:framework:end -->"
|
||||
|
||||
update_agents_section(
|
||||
agents_dst,
|
||||
agents_src,
|
||||
start_marker,
|
||||
end_marker,
|
||||
project_name,
|
||||
date_value,
|
||||
main_language,
|
||||
playbook_scripts,
|
||||
)
|
||||
return 0
|
||||
|
||||
|
||||
def should_sync_agents(config: dict) -> bool:
|
||||
for key in ("sync_rules", "sync_memory_bank", "sync_prompts", "sync_standards"):
|
||||
if key in config:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def sync_rules_action(config: dict, context: dict) -> int:
|
||||
project_root: Path = context["project_root"]
|
||||
if project_root.resolve() == PLAYBOOK_ROOT.resolve():
|
||||
log("Skip: playbook root equals project root.")
|
||||
return 0
|
||||
|
||||
templates_dir = PLAYBOOK_ROOT / "templates"
|
||||
rules_src = templates_dir / "AGENT_RULES.template.md"
|
||||
if not rules_src.is_file():
|
||||
print(f"ERROR: template not found: {rules_src}", file=sys.stderr)
|
||||
return 2
|
||||
|
||||
rules_dst = project_root / "AGENT_RULES.md"
|
||||
force = bool(config.get("force", False))
|
||||
if rules_dst.exists() and not force:
|
||||
log("AGENT_RULES.md already exists. Use force to overwrite.")
|
||||
return 0
|
||||
|
||||
project_name = resolve_project_name(context)
|
||||
main_language = resolve_main_language(config, context)
|
||||
playbook_scripts = resolve_playbook_scripts(project_root, context)
|
||||
date_value = config.get("date") or datetime.now().strftime("%Y-%m-%d")
|
||||
|
||||
backup_path(rules_dst, False)
|
||||
text = rules_src.read_text(encoding="utf-8")
|
||||
text = replace_placeholders(
|
||||
text, project_name, date_value, main_language, playbook_scripts
|
||||
)
|
||||
rules_dst.write_text(text + "\n", encoding="utf-8")
|
||||
log("Synced: AGENT_RULES.md")
|
||||
return 0
|
||||
|
||||
|
||||
def sync_memory_bank_action(config: dict, context: dict) -> int:
|
||||
project_root: Path = context["project_root"]
|
||||
if project_root.resolve() == PLAYBOOK_ROOT.resolve():
|
||||
log("Skip: playbook root equals project root.")
|
||||
return 0
|
||||
|
||||
templates_dir = PLAYBOOK_ROOT / "templates"
|
||||
memory_src = templates_dir / "memory-bank"
|
||||
if not memory_src.is_dir():
|
||||
print(f"ERROR: templates not found: {memory_src}", file=sys.stderr)
|
||||
return 2
|
||||
|
||||
project_name = config.get("project_name")
|
||||
|
|
@ -520,80 +638,62 @@ def sync_templates_action(config: dict, context: dict) -> int:
|
|||
date_value = config.get("date") or datetime.now().strftime("%Y-%m-%d")
|
||||
force = bool(config.get("force", False))
|
||||
no_backup = bool(config.get("no_backup", False))
|
||||
full = bool(config.get("full", False))
|
||||
|
||||
memory_src = templates_dir / "memory-bank"
|
||||
memory_dst = project_root / "memory-bank"
|
||||
if memory_dst.exists() and not force:
|
||||
log("memory-bank/ already exists. Use force to overwrite.")
|
||||
return 0
|
||||
|
||||
backup_path(memory_dst, no_backup)
|
||||
copytree(memory_src, memory_dst)
|
||||
rename_template_files(memory_dst)
|
||||
replace_placeholders_in_dir(
|
||||
memory_dst,
|
||||
project_name,
|
||||
date_value,
|
||||
main_language,
|
||||
playbook_scripts,
|
||||
)
|
||||
log("Synced: memory-bank/")
|
||||
return 0
|
||||
|
||||
|
||||
def sync_prompts_action(config: dict, context: dict) -> int:
|
||||
project_root: Path = context["project_root"]
|
||||
if project_root.resolve() == PLAYBOOK_ROOT.resolve():
|
||||
log("Skip: playbook root equals project root.")
|
||||
return 0
|
||||
|
||||
templates_dir = PLAYBOOK_ROOT / "templates"
|
||||
prompts_src = templates_dir / "prompts"
|
||||
agents_src = templates_dir / "AGENTS.template.md"
|
||||
rules_src = templates_dir / "AGENT_RULES.template.md"
|
||||
if not prompts_src.is_dir():
|
||||
print(f"ERROR: templates not found: {prompts_src}", file=sys.stderr)
|
||||
return 2
|
||||
|
||||
if memory_src.is_dir():
|
||||
memory_dst = project_root / "memory-bank"
|
||||
if memory_dst.exists() and not force:
|
||||
log("memory-bank/ already exists. Use force to overwrite.")
|
||||
else:
|
||||
backup_path(memory_dst, no_backup)
|
||||
copytree(memory_src, memory_dst)
|
||||
rename_template_files(memory_dst)
|
||||
replace_placeholders_in_dir(
|
||||
memory_dst,
|
||||
project_name,
|
||||
date_value,
|
||||
main_language,
|
||||
playbook_scripts,
|
||||
)
|
||||
log("Synced: memory-bank/")
|
||||
project_name = resolve_project_name(context)
|
||||
main_language = resolve_main_language(config, context)
|
||||
playbook_scripts = resolve_playbook_scripts(project_root, context)
|
||||
date_value = config.get("date") or datetime.now().strftime("%Y-%m-%d")
|
||||
force = bool(config.get("force", False))
|
||||
no_backup = bool(config.get("no_backup", False))
|
||||
|
||||
if prompts_src.is_dir():
|
||||
prompts_dst = project_root / "docs/prompts"
|
||||
if prompts_dst.exists() and not force:
|
||||
log("docs/prompts/ already exists. Use force to overwrite.")
|
||||
else:
|
||||
backup_path(prompts_dst, no_backup)
|
||||
ensure_dir(prompts_dst.parent)
|
||||
copytree(prompts_src, prompts_dst)
|
||||
rename_template_files(prompts_dst)
|
||||
replace_placeholders_in_dir(
|
||||
prompts_dst,
|
||||
project_name,
|
||||
date_value,
|
||||
main_language,
|
||||
playbook_scripts,
|
||||
)
|
||||
log("Synced: docs/prompts/")
|
||||
|
||||
if agents_src.is_file():
|
||||
agents_dst = project_root / "AGENTS.md"
|
||||
if full:
|
||||
start_marker = "<!-- playbook:framework:start -->"
|
||||
end_marker = "<!-- playbook:framework:end -->"
|
||||
else:
|
||||
start_marker = "<!-- playbook:templates:start -->"
|
||||
end_marker = "<!-- playbook:templates:end -->"
|
||||
update_agents_section(
|
||||
agents_dst,
|
||||
agents_src,
|
||||
start_marker,
|
||||
end_marker,
|
||||
project_name,
|
||||
date_value,
|
||||
main_language,
|
||||
playbook_scripts,
|
||||
)
|
||||
|
||||
if rules_src.is_file():
|
||||
rules_dst = project_root / "AGENT_RULES.md"
|
||||
if rules_dst.exists() and not force:
|
||||
log("AGENT_RULES.md already exists. Use force to overwrite.")
|
||||
else:
|
||||
backup_path(rules_dst, no_backup)
|
||||
text = rules_src.read_text(encoding="utf-8")
|
||||
text = replace_placeholders(
|
||||
text, project_name, date_value, main_language, playbook_scripts
|
||||
)
|
||||
rules_dst.write_text(text + "\n", encoding="utf-8")
|
||||
log("Synced: AGENT_RULES.md")
|
||||
prompts_dst = project_root / "docs/prompts"
|
||||
if prompts_dst.exists() and not force:
|
||||
log("docs/prompts/ already exists. Use force to overwrite.")
|
||||
return 0
|
||||
|
||||
backup_path(prompts_dst, no_backup)
|
||||
ensure_dir(prompts_dst.parent)
|
||||
copytree(prompts_src, prompts_dst)
|
||||
rename_template_files(prompts_dst)
|
||||
replace_placeholders_in_dir(
|
||||
prompts_dst,
|
||||
project_name,
|
||||
date_value,
|
||||
main_language,
|
||||
playbook_scripts,
|
||||
)
|
||||
log("Synced: docs/prompts/")
|
||||
return 0
|
||||
|
||||
|
||||
|
|
@ -959,8 +1059,12 @@ def run_action(name: str, config: dict, context: dict) -> int:
|
|||
print(f"[action] {name}")
|
||||
if name == "vendor":
|
||||
return vendor_action(config, context)
|
||||
if name == "sync_templates":
|
||||
return sync_templates_action(config, context)
|
||||
if name == "sync_rules":
|
||||
return sync_rules_action(config, context)
|
||||
if name == "sync_memory_bank":
|
||||
return sync_memory_bank_action(config, context)
|
||||
if name == "sync_prompts":
|
||||
return sync_prompts_action(config, context)
|
||||
if name == "sync_standards":
|
||||
return sync_standards_action(config, context)
|
||||
if name == "install_skills":
|
||||
|
|
@ -1002,6 +1106,11 @@ def main(argv: list[str]) -> int:
|
|||
"config": config,
|
||||
}
|
||||
|
||||
if should_sync_agents(config):
|
||||
result = sync_agents_template(context)
|
||||
if result != 0:
|
||||
return result
|
||||
|
||||
for name in ORDER:
|
||||
if name in config:
|
||||
result = run_action(name, config[name], context)
|
||||
|
|
|
|||
|
|
@ -37,16 +37,25 @@ templates/
|
|||
|
||||
## 快速部署
|
||||
|
||||
使用统一入口 `playbook.py`:
|
||||
使用统一入口 `playbook.py`,配置节存在即启用:
|
||||
|
||||
```toml
|
||||
# playbook.toml
|
||||
[playbook]
|
||||
project_root = "/path/to/project"
|
||||
|
||||
[sync_templates]
|
||||
# 同步 AGENT_RULES.md(配置节存在即启用)
|
||||
[sync_rules]
|
||||
# force = true # 可选,强制覆盖已存在的文件
|
||||
|
||||
# 同步 memory-bank/(配置节存在即启用)
|
||||
[sync_memory_bank]
|
||||
project_name = "MyProject"
|
||||
full = false
|
||||
# force = true # 可选,强制覆盖(会先备份)
|
||||
|
||||
# 同步 docs/prompts/(配置节存在即启用)
|
||||
[sync_prompts]
|
||||
# force = true # 可选,强制覆盖(会先备份)
|
||||
```
|
||||
|
||||
```bash
|
||||
|
|
@ -55,14 +64,37 @@ python docs/standards/playbook/scripts/playbook.py -config playbook.toml
|
|||
|
||||
参数说明见 `playbook.toml.example`(仓库根目录)或 vendoring 后的 `docs/standards/playbook/playbook.toml.example`。
|
||||
|
||||
### 部署行为
|
||||
### 配置节说明
|
||||
|
||||
- **新项目**:创建完整的 AGENTS.md、AGENT_RULES.md、memory-bank/、docs/prompts/
|
||||
- **已有 AGENTS.md**:
|
||||
- 默认:追加路由链接(`<!-- playbook:templates:start/end -->`)
|
||||
- `full = true`:追加完整框架(规则优先级 + 路由 + 新会话开始时)
|
||||
- **其他文件**:如果已存在则跳过(使用 `force = true` 覆盖)
|
||||
- **占位符替换**:自动替换 `{{DATE}}` 为当前日期
|
||||
| 配置节 | 部署内容 | 选项 |
|
||||
| -------------------- | -------------- | ----------------------- |
|
||||
| `[sync_rules]` | AGENT_RULES.md | `force` |
|
||||
| `[sync_memory_bank]` | memory-bank/ | `project_name`, `force` |
|
||||
| `[sync_prompts]` | docs/prompts/ | `force` |
|
||||
|
||||
- **配置节存在即启用**:只写需要同步的配置节
|
||||
- **AGENTS.md**:始终按区块更新(`<!-- playbook:xxx:start/end -->`),不受配置节控制
|
||||
- **force**:默认 false,已存在则跳过;设为 true 时强制覆盖(memory-bank/ 和 prompts/ 会先备份)
|
||||
- **占位符替换**:自动替换 `{{DATE}}`、`{{PLAYBOOK_SCRIPTS}}` 等
|
||||
|
||||
### 典型场景
|
||||
|
||||
```toml
|
||||
# 场景 1:初次部署(全部)
|
||||
[sync_rules]
|
||||
[sync_memory_bank]
|
||||
project_name = "MyProject"
|
||||
[sync_prompts]
|
||||
|
||||
# 场景 2:框架升级(只更新规则)
|
||||
[sync_rules]
|
||||
force = true
|
||||
|
||||
# 场景 3:重置项目上下文
|
||||
[sync_memory_bank]
|
||||
project_name = "MyProject"
|
||||
force = true
|
||||
```
|
||||
|
||||
### 部署后的目录结构
|
||||
|
||||
|
|
@ -99,9 +131,8 @@ project/
|
|||
| `{{PLAYBOOK_SCRIPTS}}` | 脚本路径 | ✅ 是 |
|
||||
| 其他 `{{...}}` | 项目特定内容 | ❌ 手动 |
|
||||
|
||||
`{{PROJECT_NAME}}` 可通过 `sync_templates.project_name` 自动替换;未配置时保持原样。
|
||||
`{{MAIN_LANGUAGE}}` 可通过 `sync_templates.main_language` 或 `sync_standards.langs[0]` 自动替换;
|
||||
未配置时默认 `tsl`。
|
||||
`{{PROJECT_NAME}}` 可通过 `sync_memory_bank.project_name` 自动替换;未配置时保持原样。
|
||||
`{{MAIN_LANGUAGE}}` 可通过 `sync_standards.langs[0]` 自动替换;未配置时默认 `tsl`。
|
||||
`{{PLAYBOOK_SCRIPTS}}` 自动替换为 Playbook 脚本路径(默认 `docs/standards/playbook/scripts`)。
|
||||
|
||||
## 模板说明
|
||||
|
|
@ -170,11 +201,11 @@ project/
|
|||
|
||||
**playbook 标记**(用于自动更新):
|
||||
|
||||
| 标记 | 用途 | 管理入口 |
|
||||
| --------------------------------------- | --------------------- | ------------------------------ |
|
||||
| `<!-- playbook:agents:start/end -->` | 语言规则链接 | playbook.py `[sync_standards]` |
|
||||
| `<!-- playbook:templates:start/end -->` | 路由链接(默认追加) | playbook.py `[sync_templates]` |
|
||||
| `<!-- playbook:framework:start/end -->` | 完整框架(full 追加) | playbook.py `[sync_templates]` |
|
||||
| 标记 | 用途 | 说明 |
|
||||
| --------------------------------------- | ------------ | -------------------------- |
|
||||
| `<!-- playbook:agents:start/end -->` | 语言规则链接 | 由 `[sync_standards]` 管理 |
|
||||
| `<!-- playbook:templates:start/end -->` | 路由链接 | AGENTS.md 始终按区块更新 |
|
||||
| `<!-- playbook:framework:start/end -->` | 完整框架 | AGENTS.md 始终按区块更新 |
|
||||
|
||||
### ci/、cpp/、python/
|
||||
|
||||
|
|
@ -213,7 +244,7 @@ playbook/
|
|||
├── docs/ # 权威静态文档
|
||||
├── templates/ # 本目录:项目架构模板 → 部署到 memory-bank/ 等
|
||||
└── scripts/
|
||||
├── playbook.py # 统一入口:vendor/sync_templates/sync_standards/...
|
||||
├── playbook.py # 统一入口:vendor/sync_rules/sync_memory_bank/sync_prompts/sync_standards/...
|
||||
└── plan_progress.py # Plan 选择与进度记录
|
||||
```
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ tests/
|
|||
├── test_gitattributes_modes.py # gitattr_mode 行为测试
|
||||
├── test_plan_progress_cli.py # plan_progress CLI 测试
|
||||
├── test_superpowers_list_sync.py # superpowers 列表一致性测试
|
||||
├── test_sync_templates_placeholders.py # 占位符替换测试
|
||||
├── test_sync_templates_placeholders.py # 占位符替换测试(sync_rules/sync_standards)
|
||||
├── test_toml_edge_cases.py # TOML 解析边界测试
|
||||
├── templates/ # 模板验证测试
|
||||
│ ├── validate_python_templates.sh # Python 模板验证
|
||||
|
|
@ -64,7 +64,7 @@ sh tests/integration/check_doc_links.sh
|
|||
|
||||
- CLI 参数解析与帮助信息
|
||||
- TOML 配置解析与动作顺序
|
||||
- vendor/sync/install 等基础动作落地
|
||||
- vendor/sync_rules/sync_memory_bank/sync_prompts/sync_standards 等基础动作落地
|
||||
|
||||
### 2. 模板验证测试 (templates/)
|
||||
|
||||
|
|
|
|||
|
|
@ -65,13 +65,13 @@ langs = ["tsl"]
|
|||
self.assertEqual(result.returncode, 0)
|
||||
self.assertTrue(snapshot.is_file())
|
||||
|
||||
def test_sync_templates_creates_memory_bank(self):
|
||||
def test_sync_memory_bank_creates_memory_bank(self):
|
||||
with tempfile.TemporaryDirectory() as tmp_dir:
|
||||
config_body = f"""
|
||||
[playbook]
|
||||
project_root = "{tmp_dir}"
|
||||
|
||||
[sync_templates]
|
||||
[sync_memory_bank]
|
||||
project_name = "Demo"
|
||||
"""
|
||||
config_path = Path(tmp_dir) / "playbook.toml"
|
||||
|
|
|
|||
|
|
@ -23,9 +23,7 @@ class SyncTemplatesPlaceholdersTests(unittest.TestCase):
|
|||
[playbook]
|
||||
project_root = \"{tmp_dir}\"
|
||||
|
||||
[sync_templates]
|
||||
project_name = \"Demo\"
|
||||
full = true
|
||||
[sync_rules]
|
||||
|
||||
[sync_standards]
|
||||
langs = [\"cpp\", \"tsl\"]
|
||||
|
|
|
|||
Loading…
Reference in New Issue