env_loader.py 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. """Environment bootstrap helpers for zhuce6 entrypoints."""
  2. from __future__ import annotations
  3. import os
  4. from pathlib import Path
  5. _BOOTSTRAPPED = False
  6. def _resolve_project_root(project_root: Path | None = None) -> Path:
  7. if project_root is not None:
  8. return project_root.expanduser().resolve()
  9. raw = str(os.getenv("ZHUCE6_PROJECT_ROOT", "")).strip()
  10. if raw:
  11. return Path(raw).expanduser().resolve()
  12. return Path(__file__).resolve().parents[1]
  13. def load_env_file(path: Path) -> None:
  14. if not path.is_file():
  15. return
  16. for raw_line in path.read_text(encoding="utf-8").splitlines():
  17. line = raw_line.strip()
  18. if not line or line.startswith("#"):
  19. continue
  20. if line.startswith("export "):
  21. line = line[7:]
  22. key, sep, value = line.partition("=")
  23. if not sep:
  24. continue
  25. key = key.strip()
  26. value = value.strip().strip('"').strip("'")
  27. if key and key not in os.environ:
  28. os.environ[key] = value
  29. def bootstrap_env(project_root: Path | None = None, *, force: bool = False) -> tuple[Path, Path, Path]:
  30. global _BOOTSTRAPPED
  31. if _BOOTSTRAPPED and not force:
  32. resolved_root = _resolve_project_root(project_root)
  33. config_dir = Path(
  34. str(os.getenv("ZHUCE6_CONFIG_DIR", resolved_root / "config")).strip() or str(resolved_root / "config")
  35. ).expanduser().resolve()
  36. env_file = Path(
  37. str(os.getenv("ZHUCE6_ENV_FILE", resolved_root / ".env")).strip() or str(resolved_root / ".env")
  38. ).expanduser().resolve()
  39. cfmail_env_file = Path(
  40. str(os.getenv("ZHUCE6_CFMAIL_ENV_FILE", config_dir / "cfmail_provision.env")).strip()
  41. or str(config_dir / "cfmail_provision.env")
  42. ).expanduser().resolve()
  43. return resolved_root, env_file, cfmail_env_file
  44. resolved_root = _resolve_project_root(project_root)
  45. os.environ.setdefault("ZHUCE6_PROJECT_ROOT", str(resolved_root))
  46. env_file = Path(
  47. str(os.getenv("ZHUCE6_ENV_FILE", resolved_root / ".env")).strip() or str(resolved_root / ".env")
  48. ).expanduser().resolve()
  49. load_env_file(env_file)
  50. config_dir = Path(
  51. str(os.getenv("ZHUCE6_CONFIG_DIR", resolved_root / "config")).strip() or str(resolved_root / "config")
  52. ).expanduser().resolve()
  53. cfmail_env_file = Path(
  54. str(os.getenv("ZHUCE6_CFMAIL_ENV_FILE", config_dir / "cfmail_provision.env")).strip()
  55. or str(config_dir / "cfmail_provision.env")
  56. ).expanduser().resolve()
  57. load_env_file(cfmail_env_file)
  58. _BOOTSTRAPPED = True
  59. return resolved_root, env_file, cfmail_env_file