82 lines
2.2 KiB
Python
82 lines
2.2 KiB
Python
"""Resolve myclaude repository and workspace roots."""
|
|
|
|
import os
|
|
from pathlib import Path
|
|
|
|
_MAX_WALK_DEPTH = 16
|
|
_MAX_SOURCE_DEPTH = 8
|
|
|
|
|
|
def _pyproject_names_myclaude(path: Path) -> bool:
|
|
try:
|
|
text = path.read_text(encoding="utf-8", errors="ignore")
|
|
except OSError:
|
|
return False
|
|
return 'name = "myclaude"' in text or "name = 'myclaude'" in text
|
|
|
|
|
|
def _walk_up_for_pyproject(start: Path) -> Path | None:
|
|
p = start.resolve()
|
|
for _ in range(_MAX_WALK_DEPTH):
|
|
candidate = p / "pyproject.toml"
|
|
if candidate.is_file() and _pyproject_names_myclaude(candidate):
|
|
return p
|
|
parent = p.parent
|
|
if parent == p:
|
|
break
|
|
p = parent
|
|
return None
|
|
|
|
|
|
def get_myclaude_project_root() -> Path:
|
|
"""
|
|
Root of the myclaude repo (contains Makefile + pyproject).
|
|
|
|
Order: MYCLAUDE_PROJECT_ROOT > walk from cwd > package source tree > ~/.myclaude
|
|
"""
|
|
env_root = os.environ.get("MYCLAUDE_PROJECT_ROOT")
|
|
if env_root:
|
|
return Path(env_root).expanduser().resolve()
|
|
|
|
try:
|
|
cwd = Path.cwd()
|
|
except (OSError, PermissionError):
|
|
cwd = None
|
|
if cwd is not None:
|
|
found = _walk_up_for_pyproject(cwd)
|
|
if found is not None:
|
|
return found
|
|
|
|
here = Path(__file__).resolve().parent
|
|
for _ in range(_MAX_SOURCE_DEPTH):
|
|
pyproject = here / "pyproject.toml"
|
|
if pyproject.is_file() and _pyproject_names_myclaude(pyproject):
|
|
return here
|
|
if here.parent == here:
|
|
break
|
|
here = here.parent
|
|
|
|
return Path.home() / ".myclaude"
|
|
|
|
|
|
def get_workspace_root() -> Path:
|
|
"""
|
|
Root of the myclaude workspace directory.
|
|
|
|
Order: MYCLAUDE_WORKSPACE_ROOT > project_root/workspace/ > ~/workspace
|
|
Creates the directory if it does not exist.
|
|
"""
|
|
env_root = os.environ.get("MYCLAUDE_WORKSPACE_ROOT")
|
|
if env_root:
|
|
root = Path(env_root).expanduser().resolve()
|
|
else:
|
|
project_root = get_myclaude_project_root()
|
|
project_workspace = project_root / "workspace"
|
|
if project_workspace.is_dir():
|
|
root = project_workspace
|
|
else:
|
|
root = Path.home() / "workspace"
|
|
|
|
root.mkdir(parents=True, exist_ok=True)
|
|
return root
|