"""Same-filesystem staging for plugin skill writes.""" from __future__ import annotations import filecmp import os from pathlib import Path import shutil from uuid import uuid4 class PluginSkillTransaction: def __init__(self, workspace: str | Path) -> None: self.workspace = Path(workspace) self.transaction_id = uuid4().hex self.root = self.workspace / ".beaver" / "staging" / "plugin-skills" / self.transaction_id self.root.mkdir(parents=True, exist_ok=True) def stage_upstream_snapshot(self, skill_name: str, source_id: str, tree_hash: str) -> Path: path = self.root / "upstreams" / skill_name / source_id / tree_hash path.mkdir(parents=True, exist_ok=True) return path def stage_skill_version(self, skill_name: str, version: str) -> Path: path = self.root / "versions" / skill_name / version path.mkdir(parents=True, exist_ok=True) return path def promote_directory(self, staged: Path, final: Path) -> None: if final.exists(): if _directories_identical(staged, final): return raise ValueError(f"Immutable directory already exists with different content: {final}") final.parent.mkdir(parents=True, exist_ok=True) os.replace(staged, final) def cleanup(self) -> None: shutil.rmtree(self.root, ignore_errors=True) def _directories_identical(left: Path, right: Path) -> bool: comparison = filecmp.dircmp(left, right) if comparison.left_only or comparison.right_only or comparison.funny_files: return False for filename in comparison.common_files: if not filecmp.cmp(left / filename, right / filename, shallow=False): return False return all(_directories_identical(left / name, right / name) for name in comparison.common_dirs)