This commit is contained in:
2026-01-09 15:41:38 -08:00
parent 94aca4d3d4
commit a70482fdf1
2 changed files with 68 additions and 11 deletions

View File

@@ -11,6 +11,7 @@ from __future__ import annotations
from typing import Optional, List, Tuple
import importlib
import importlib.util
import os
import sys
from pathlib import Path
import shlex
@@ -25,7 +26,7 @@ def _ensure_repo_root_on_sys_path(pkg_file: Optional[Path] = None) -> Optional[P
not necessarily on `sys.path`, which breaks `import CLI`.
We infer the repo root by walking up from this package location and looking
for a sibling `CLI.py`.
for a sibling `CLI.py` or checking parent directories.
`pkg_file` exists for unit tests; production uses this module's `__file__`.
"""
@@ -34,6 +35,7 @@ def _ensure_repo_root_on_sys_path(pkg_file: Optional[Path] = None) -> Optional[P
except Exception:
return
# Strategy 1: Look for CLI.py in parent directories (starting from scripts parent)
for parent in pkg_dir.parents:
try:
if (parent / "CLI.py").exists():
@@ -43,6 +45,22 @@ def _ensure_repo_root_on_sys_path(pkg_file: Optional[Path] = None) -> Optional[P
return parent
except Exception:
continue
# Strategy 2: If in a venv, check the .venv/.. path (project root)
try:
# If this file is in .../venv/lib/python3.x/site-packages/scripts/
# then we want to go up to find the project root
current = pkg_dir.resolve()
for _ in range(20): # Safety limit
current = current.parent
if (current / "CLI.py").exists():
parent_str = str(current)
if parent_str not in sys.path:
sys.path.insert(0, parent_str)
return current
except Exception:
pass
return None
@@ -165,13 +183,35 @@ def _run_cli(clean_args: List[str]) -> int:
# 2) If no in-memory module provided the class, try importing the repo-root CLI
if MedeiaCLI is None:
try:
_ensure_repo_root_on_sys_path()
repo_root = _ensure_repo_root_on_sys_path()
from CLI import MedeiaCLI as _M # type: ignore
MedeiaCLI = _M
except Exception:
raise ImportError(
"Could not import 'MedeiaCLI'. This often means the project is not available on sys.path (run 'pip install -e scripts' or re-run the bootstrap script)."
except Exception as exc:
# Provide diagnostic information
import traceback
error_msg = (
"Could not import 'MedeiaCLI'. This often means the project is not available on sys.path.\n"
"Diagnostic info:\n"
f" - sys.executable: {sys.executable}\n"
f" - sys.path (first 5): {sys.path[:5]}\n"
f" - current working directory: {Path.cwd()}\n"
f" - this file: {Path(__file__).resolve()}\n"
)
try:
repo = _ensure_repo_root_on_sys_path()
if repo:
error_msg += f" - detected repo root: {repo}\n"
cli_path = repo / "CLI.py"
error_msg += f" - CLI.py exists at {cli_path}: {cli_path.exists()}\n"
except:
pass
error_msg += (
"\nRemedy: Run 'pip install -e scripts' from the project root or re-run the bootstrap script.\n"
"Set MM_DEBUG=1 to enable detailed diagnostics."
)
if os.environ.get("MM_DEBUG"):
error_msg += f"\n\nTraceback:\n{traceback.format_exc()}"
raise ImportError(error_msg) from exc
try:
app = MedeiaCLI()