78 lines
2.7 KiB
Python
78 lines
2.7 KiB
Python
# -----------------------------------------------------------------------------
|
|
# Description: Build-time mxpic_router runtime dependency validation helpers.
|
|
# Inside functions: ensure_router_path, require_router_stack
|
|
# Developer : Qin Yue @ 2026
|
|
# Organization : OptiHK Limited
|
|
# -----------------------------------------------------------------------------
|
|
import importlib
|
|
import os
|
|
import sys
|
|
from dataclasses import dataclass, field
|
|
from typing import List
|
|
|
|
|
|
@dataclass
|
|
class RouterStackStatus:
|
|
"""Summary of the router stack checks completed for a build action."""
|
|
|
|
ok: bool
|
|
router_root: str
|
|
checked: List[str] = field(default_factory=list)
|
|
|
|
|
|
class RouterStackUnavailable(RuntimeError):
|
|
"""Raised when a build action needs the external router stack but it is absent."""
|
|
pass
|
|
|
|
|
|
def ensure_router_path() -> str:
|
|
"""Add the sibling mxpic_router checkout to import resolution when present."""
|
|
router_root = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", "mxpic_router"))
|
|
if os.path.isdir(router_root) and router_root not in sys.path:
|
|
sys.path.insert(0, router_root)
|
|
return router_root
|
|
|
|
|
|
def require_router_stack(require_gdstk: bool = False) -> RouterStackStatus:
|
|
"""Validate the runtime stack required for build-time router actions."""
|
|
router_root = ensure_router_path()
|
|
checked = []
|
|
missing = []
|
|
|
|
try:
|
|
importlib.import_module("mxpic_router")
|
|
checked.append("mxpic_router")
|
|
except Exception as exc:
|
|
missing.append(f"mxpic_router: {exc}")
|
|
|
|
try:
|
|
importlib.import_module("nazca")
|
|
checked.append("nazca")
|
|
except Exception as exc:
|
|
missing.append(f"nazca: {exc}")
|
|
|
|
if require_gdstk:
|
|
try:
|
|
importlib.import_module("gdstk")
|
|
checked.append("gdstk")
|
|
except Exception as exc:
|
|
missing.append(f"gdstk: {exc}")
|
|
|
|
try:
|
|
router_builder = importlib.import_module("mxpic_router.builder")
|
|
route_factory = getattr(router_builder, "_import_route_backend")
|
|
route_backend = route_factory()
|
|
checked.append(getattr(route_backend, "backend_name", "route backend"))
|
|
except Exception as exc:
|
|
missing.append(f"route backend: {exc}")
|
|
|
|
if missing:
|
|
details = "; ".join(missing)
|
|
raise RouterStackUnavailable(
|
|
"Required mxpic_router runtime stack is unavailable. "
|
|
"Build actions require mxpic_router, Nazca, and either mxpic_forge Route "
|
|
f"or the Nazca Interconnect fallback. gdstk is also required for SVG preview generation. Details: {details}"
|
|
)
|
|
|
|
return RouterStackStatus(ok=True, router_root=router_root, checked=checked)
|