playbook/tests/cli/test_claude_md_sync.py

164 lines
5.2 KiB
Python

import subprocess
import sys
import tempfile
import unittest
from pathlib import Path
ROOT = Path(__file__).resolve().parents[2]
SCRIPT = ROOT / "scripts" / "playbook.py"
CUSTOM_DEPLOY_ROOT = "custom/playbook"
def run_cli(*args):
return subprocess.run(
[sys.executable, str(SCRIPT), *args],
capture_output=True,
text=True,
)
class ClaudeMdSyncTests(unittest.TestCase):
def test_sync_claude_md_creates_when_no_claude_md(self):
with tempfile.TemporaryDirectory() as tmp_dir:
config_body = f"""
[playbook]
project_root = "{tmp_dir}"
playbook_root = "{CUSTOM_DEPLOY_ROOT}"
install_mode = "snapshot"
[sync_memory_bank]
project_name = "Demo"
"""
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)
claude_md = Path(tmp_dir) / "CLAUDE.md"
self.assertTrue(claude_md.exists())
text = claude_md.read_text(encoding="utf-8")
self.assertTrue(text.startswith("# CLAUDE.md\n\n"))
self.assertIn("@AGENTS.md", text)
self.assertIn("<!-- playbook:claude:start -->", text)
def test_sync_claude_md_appends_block_to_existing_claude_md(self):
with tempfile.TemporaryDirectory() as tmp_dir:
claude_md = Path(tmp_dir) / "CLAUDE.md"
claude_md.write_text(
"# My project\n\nSome existing content.\n", encoding="utf-8"
)
config_body = f"""
[playbook]
project_root = "{tmp_dir}"
playbook_root = "{CUSTOM_DEPLOY_ROOT}"
install_mode = "snapshot"
[sync_memory_bank]
project_name = "Demo"
"""
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)
text = claude_md.read_text(encoding="utf-8")
self.assertIn("@AGENTS.md", text)
self.assertIn("@AGENT_RULES.md", text)
self.assertIn("<!-- playbook:claude:start -->", text)
self.assertIn("Some existing content.", text)
def test_sync_claude_md_updates_existing_block(self):
with tempfile.TemporaryDirectory() as tmp_dir:
claude_md = Path(tmp_dir) / "CLAUDE.md"
claude_md.write_text(
"# My project\n\n"
"<!-- playbook:claude:start -->\n"
"@AGENTS.md\n"
"<!-- playbook:claude:end -->\n",
encoding="utf-8",
)
config_body = f"""
[playbook]
project_root = "{tmp_dir}"
playbook_root = "{CUSTOM_DEPLOY_ROOT}"
install_mode = "snapshot"
[sync_memory_bank]
project_name = "Demo"
"""
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)
text = claude_md.read_text(encoding="utf-8")
self.assertIn("@AGENTS.md", text)
self.assertIn("@AGENT_RULES.md", text)
self.assertEqual(text.count("<!-- playbook:claude:start -->"), 1)
def test_sync_claude_md_adds_heading_to_generated_block(self):
with tempfile.TemporaryDirectory() as tmp_dir:
claude_md = Path(tmp_dir) / "CLAUDE.md"
claude_md.write_text(
"<!-- playbook:claude:start -->\n"
"\n"
"@AGENTS.md\n"
"@AGENT_RULES.md\n"
"\n"
"<!-- playbook:claude:end -->\n",
encoding="utf-8",
)
config_body = f"""
[playbook]
project_root = "{tmp_dir}"
playbook_root = "{CUSTOM_DEPLOY_ROOT}"
install_mode = "snapshot"
[sync_memory_bank]
project_name = "Demo"
"""
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)
text = claude_md.read_text(encoding="utf-8")
self.assertTrue(text.startswith("# CLAUDE.md\n\n"))
self.assertIn("@AGENTS.md", text)
self.assertIn("@AGENT_RULES.md", text)
self.assertEqual(text.count("<!-- playbook:claude:start -->"), 1)
def test_sync_claude_md_skips_when_already_references_agents(self):
with tempfile.TemporaryDirectory() as tmp_dir:
claude_md = Path(tmp_dir) / "CLAUDE.md"
original = "# My project\n\n@AGENTS.md\n"
claude_md.write_text(original, encoding="utf-8")
config_body = f"""
[playbook]
project_root = "{tmp_dir}"
playbook_root = "{CUSTOM_DEPLOY_ROOT}"
install_mode = "snapshot"
[sync_memory_bank]
project_name = "Demo"
"""
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)
self.assertEqual(claude_md.read_text(encoding="utf-8"), original)
if __name__ == "__main__":
unittest.main()