k
This commit is contained in:
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user