import subprocess import tempfile import unittest from pathlib import Path class LocalStateTest(unittest.TestCase): """验证 `.craftkit/` 能同时承载共享资料和本地状态。""" def run_git(self, root: Path, *args: str) -> subprocess.CompletedProcess[str]: """在隔离仓库执行 Git,并保留输出供断言使用。""" return subprocess.run( ["git", "-C", str(root), *args], check=False, capture_output=True, text=True, encoding="utf-8", ) def test_nested_gitignore_separates_shared_and_local_content(self) -> None: """共享资料应可提交,本地目录和缓存应由嵌套规则排除。""" with tempfile.TemporaryDirectory() as temp: root = Path(temp) initialized = self.run_git(root, "init") self.assertEqual(initialized.returncode, 0, initialized.stderr) craftkit = root / ".craftkit" craftkit.mkdir() (craftkit / ".gitignore").write_text( "# Local CraftKit data\n/local/\n/cache/\n", encoding="utf-8", ) (craftkit / "README.md").write_text("# 项目资料\n", encoding="utf-8") shared = craftkit / "standards" / "coding" / "rules.md" shared.parent.mkdir(parents=True) shared.write_text("# 编码规范\n", encoding="utf-8") local = craftkit / "local" / "handoff" / "current.md" local.parent.mkdir(parents=True) local.write_text("# 本地交接\n", encoding="utf-8") cache = craftkit / "cache" / "result.json" cache.parent.mkdir(parents=True) cache.write_text("{}\n", encoding="utf-8") ignored = self.run_git( root, "check-ignore", "--no-index", "-v", ".craftkit/local/handoff/current.md", ) self.assertEqual(ignored.returncode, 0, ignored.stderr) self.assertIn(".craftkit/.gitignore", ignored.stdout.replace("\\", "/")) cache_ignored = self.run_git( root, "check-ignore", "--no-index", ".craftkit/cache/result.json", ) self.assertEqual(cache_ignored.returncode, 0, cache_ignored.stderr) status = self.run_git(root, "status", "--short", "--untracked-files=all") self.assertEqual(status.returncode, 0, status.stderr) normalized = status.stdout.replace("\\", "/") self.assertIn(".craftkit/.gitignore", normalized) self.assertIn(".craftkit/README.md", normalized) self.assertIn(".craftkit/standards/coding/rules.md", normalized) self.assertNotIn(".craftkit/local", normalized) self.assertNotIn(".craftkit/cache", normalized) self.assertFalse((root / ".gitignore").exists()) if __name__ == "__main__": unittest.main()