mirror of
https://github.com/KingHWJ/WeReadBoard.git
synced 2026-11-03 18:24:58 +08:00
119 lines
3.1 KiB
Python
119 lines
3.1 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
项目配置读取工具。
|
|
|
|
读取顺序:
|
|
1. 当前进程环境变量
|
|
2. 项目根目录下的 .env / .env.local
|
|
3. 用户常见 shell 配置文件中的 export 语句
|
|
"""
|
|
|
|
from pathlib import Path
|
|
import os
|
|
|
|
|
|
PROJECT_DIR = Path(__file__).resolve().parent
|
|
ENV_FILE_NAMES = (".env", ".env.local")
|
|
SHELL_RC_FILES = (
|
|
Path("~/.zshrc").expanduser(),
|
|
Path("~/.zprofile").expanduser(),
|
|
Path("~/.zlogin").expanduser(),
|
|
Path("~/.bash_profile").expanduser(),
|
|
Path("~/.bashrc").expanduser(),
|
|
Path("~/.profile").expanduser(),
|
|
)
|
|
|
|
|
|
def _parse_assignment(line):
|
|
"""解析 KEY=VALUE 或 export KEY=VALUE 形式的配置行。"""
|
|
stripped = line.strip()
|
|
if not stripped or stripped.startswith("#"):
|
|
return None
|
|
|
|
if stripped.startswith("export "):
|
|
stripped = stripped[7:].strip()
|
|
|
|
if "=" not in stripped:
|
|
return None
|
|
|
|
key, value = stripped.split("=", 1)
|
|
key = key.strip()
|
|
value = value.strip()
|
|
|
|
if not key or any(ch.isspace() for ch in key):
|
|
return None
|
|
|
|
if value[:1] in {"'", '"'} and value[-1:] == value[:1]:
|
|
value = value[1:-1]
|
|
else:
|
|
value = value.split(" #", 1)[0].strip()
|
|
|
|
return key, value
|
|
|
|
|
|
def _read_var_from_file(file_path, var_name):
|
|
"""从文本配置文件里读取指定变量,后出现的值优先。"""
|
|
try:
|
|
lines = file_path.read_text(encoding="utf-8").splitlines()
|
|
except OSError:
|
|
return ""
|
|
|
|
result = ""
|
|
for line in lines:
|
|
parsed = _parse_assignment(line)
|
|
if not parsed:
|
|
continue
|
|
key, value = parsed
|
|
if key == var_name and value:
|
|
result = value
|
|
return result
|
|
|
|
|
|
def _project_env_files(project_dir=None):
|
|
base_dir = Path(project_dir) if project_dir else PROJECT_DIR
|
|
return [base_dir / name for name in ENV_FILE_NAMES]
|
|
|
|
|
|
def load_project_env(project_dir=None):
|
|
"""把项目 .env 文件里的变量加载到当前进程环境中。"""
|
|
for file_path in _project_env_files(project_dir):
|
|
if not file_path.exists():
|
|
continue
|
|
try:
|
|
lines = file_path.read_text(encoding="utf-8").splitlines()
|
|
except OSError:
|
|
continue
|
|
for line in lines:
|
|
parsed = _parse_assignment(line)
|
|
if not parsed:
|
|
continue
|
|
key, value = parsed
|
|
if key and value and key not in os.environ:
|
|
os.environ[key] = value
|
|
|
|
|
|
def get_env_value(var_name, default="", project_dir=None):
|
|
"""按项目约定顺序读取配置值,并回填到当前进程环境。"""
|
|
value = os.environ.get(var_name, "")
|
|
if value:
|
|
return value
|
|
|
|
load_project_env(project_dir)
|
|
value = os.environ.get(var_name, "")
|
|
if value:
|
|
return value
|
|
|
|
for file_path in _project_env_files(project_dir):
|
|
value = _read_var_from_file(file_path, var_name)
|
|
if value:
|
|
os.environ[var_name] = value
|
|
return value
|
|
|
|
for file_path in SHELL_RC_FILES:
|
|
value = _read_var_from_file(file_path, var_name)
|
|
if value:
|
|
os.environ[var_name] = value
|
|
return value
|
|
|
|
return default
|