"""Repo-relative path resolution. No absolute user paths in committed code.""" from __future__ import annotations import os from functools import lru_cache from pathlib import Path import yaml @lru_cache(maxsize=1) def repo_root() -> Path: """Walk up from this file until a directory containing pyproject.toml.""" p = Path(__file__).resolve() for parent in p.parents: if (parent / "pyproject.toml").exists(): return parent raise RuntimeError("repo root not found (no pyproject.toml above package)") @lru_cache(maxsize=1) def path_config() -> dict: with open(repo_root() / "config" / "paths.yaml") as f: return yaml.safe_load(f) def get(key: str) -> Path: """Resolve a named path from config/paths.yaml, honoring IFRAG_DATA_ROOT.""" rel = path_config()[key] override = os.environ.get("IFRAG_DATA_ROOT") if override and (rel == "data" or rel.startswith("data/")): return Path(override) / rel[len("data"):].lstrip("/") return repo_root() / rel def base_config() -> dict: with open(repo_root() / "config" / "base.yaml") as f: return yaml.safe_load(f)