mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-07 19:32:17 +00:00
45 lines
1.3 KiB
Python
45 lines
1.3 KiB
Python
from __future__ import annotations
|
|
|
|
import os
|
|
from pathlib import Path
|
|
from typing import Dict
|
|
|
|
|
|
def detect_project_root(start_file: Path) -> Path:
|
|
"""
|
|
Detect repo root by walking upwards from a file path until we find a typical repo layout.
|
|
|
|
We require:
|
|
- cli/ directory
|
|
- roles/ directory
|
|
- group_vars/ directory
|
|
|
|
This avoids brittle parents[N] assumptions and fixes "cli/cli/..." path bugs.
|
|
"""
|
|
here = start_file.resolve()
|
|
for p in [here, *here.parents]:
|
|
if (
|
|
(p / "cli").is_dir()
|
|
and (p / "roles").is_dir()
|
|
and (p / "group_vars").is_dir()
|
|
):
|
|
return p
|
|
raise SystemExit(f"Could not detect project root from: {here}")
|
|
|
|
|
|
def build_env_with_project_root(project_root: Path) -> Dict[str, str]:
|
|
"""
|
|
Return an environment dict where PYTHONPATH includes the project root.
|
|
This makes `utils` and other top-level packages importable in subprocesses.
|
|
"""
|
|
env = os.environ.copy()
|
|
root_str = str(project_root)
|
|
existing = env.get("PYTHONPATH")
|
|
if existing:
|
|
parts = existing.split(os.pathsep)
|
|
if root_str not in parts:
|
|
env["PYTHONPATH"] = root_str + os.pathsep + existing
|
|
else:
|
|
env["PYTHONPATH"] = root_str
|
|
return env
|