diff options
| author | godosa <godosa@godosa.eu> | 2026-10-07 09:12:20 +0200 |
|---|---|---|
| committer | godosa <godosa@godosa.eu> | 2026-10-07 09:12:20 +0200 |
| commit | 0f6857c26e5b2777c6be927dbc75fdcdbfe0e750 (patch) | |
| tree | 14639121dce67e928a80c23914f783e5c4e8eec8 /wflib/config.py | |
| parent | ec091e7df0ef0804d12cc49d09b2f88c19cc6534 (diff) | |
| download | workflow-0f6857c26e5b2777c6be927dbc75fdcdbfe0e750.tar.gz workflow-0f6857c26e5b2777c6be927dbc75fdcdbfe0e750.zip | |
split projects 1/6: Config.split, push key, .wf-home discovery
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JEAjUkQRrCYX5MZhWxdtj2
Diffstat (limited to 'wflib/config.py')
| -rw-r--r-- | wflib/config.py | 24 |
1 files changed, 22 insertions, 2 deletions
diff --git a/wflib/config.py b/wflib/config.py index 8f75c89..5339313 100644 --- a/wflib/config.py +++ b/wflib/config.py @@ -8,10 +8,11 @@ from pathlib import Path from . import lanes as lanes_mod NAME = "workflow.toml" +WF_HOME = ".wf-home" FORMAT = 1 KEYS = {"format", "tasks", "archive", "docs", "verify", "done", "ledgers", "anchors", "ctx_hint", "worktree_setup", "quick_gate", "slice_above", "lanes", "areas", "code_root", "area_stale_commits", "area_ignore", - "cloud", "cloud_include", "cloud_note"} + "cloud", "cloud_include", "cloud_note", "push"} AREA_IGNORE = ("tests", "test", "docs", "doc") ANCHOR_KEYS = {"index", "index_section", "specs"} @@ -46,12 +47,18 @@ class Config: cloud: bool = False # cloud lane opt-in (wf cloud send) cloud_include: list[str] = field(default_factory=list) # git-ignored paths force-added to the snapshot cloud_note: str | None = None # appended to the cloud prompt + push: list[str] = field(default_factory=list) # wf finish/merge/push: run in root after a merge (else push home) @property def areas_file(self) -> Path: return self.areas or (self.local or self.root) / "CLAUDE.md" @property + def split(self) -> bool: + """code_root is another git repo than root: private home repo + code repo (split project).""" + return bool(self.code_root) and git_top(self.code_root) not in (None, git_top(self.root)) + + @property def code(self) -> Path: return self.code_root or self.root @@ -104,8 +111,15 @@ def linked_worktree(folder: Path) -> tuple[Path, Path, Path] | None: def find_root(start: Path) -> Path: """Folder with workflow.toml at or above start; in a linked git worktree the main tree's - same folder, when it is a project too (one TASKS.md for all worktrees).""" + same folder, when it is a project too (one TASKS.md for all worktrees). A code worktree of a + split project: its .wf-home.""" start = start.resolve() + top = git_top(start) + if top and (top / WF_HOME).is_file(): + home = Path((top / WF_HOME).read_text().strip()) + if not (home / NAME).is_file(): + raise ConfigError(f"{WF_HOME} points to {home}: no {NAME} there (fix or delete {top / WF_HOME})") + return home for folder in (start, *start.parents): if (folder / NAME).is_file(): wt = linked_worktree(folder) @@ -117,6 +131,11 @@ def find_root(start: Path) -> Path: raise ConfigError(f"no {NAME} in {start} or above: not a wf project (wf init makes one)") +def code_main(cfg: "Config") -> Path | None: + """Main tree top of the code repo of a split project, else None.""" + return git_top(cfg.code_root) if cfg.split else None + + def find_local(start: Path) -> Path | None: """In a linked worktree whose project root is the main tree's (find_root): the worktree's own copy of that folder when it has a workflow.toml, else None.""" @@ -222,4 +241,5 @@ def load(root: Path, local: Path | None = None) -> Config: local=local, cloud=data.get("cloud", False), cloud_include=_strings(data, "cloud_include"), cloud_note=_string(data, "cloud_note"), + push=_strings(data, "push"), ) |
