Files
ecm_sync_system/sync_state_machine/config/run_presets.py
T
strepsiades 4a9c444b10 first commit
2026-03-09 16:31:42 +08:00

87 lines
2.9 KiB
Python

from __future__ import annotations
import json
from pathlib import Path
from typing import Any, Dict, List, Tuple
PRESET_FILES: Dict[str, str] = {
"jsonl_sm": "jsonl_to_jsonl",
"simple_sm": "jsonl_to_api",
}
def _run_profiles_dir() -> Path:
return Path(__file__).resolve().parents[2] / "run_profiles"
def _preset_templates_dir() -> Path:
return _run_profiles_dir() / "preset"
def _replace_placeholders(value: Any, project_root: Path) -> Any:
if isinstance(value, str):
return value.replace("${PROJECT_ROOT}", str(project_root))
if isinstance(value, dict):
return {k: _replace_placeholders(v, project_root) for k, v in value.items()}
if isinstance(value, list):
return [_replace_placeholders(v, project_root) for v in value]
return value
def list_preset_names() -> List[str]:
return sorted(PRESET_FILES.keys())
def get_preset_file_candidates(preset_name: str) -> List[Path]:
if preset_name not in PRESET_FILES:
raise ValueError(f"Unknown preset: {preset_name}. Available: {list_preset_names()}")
base = PRESET_FILES[preset_name]
run_profiles_root = _run_profiles_dir()
preset_templates_root = _preset_templates_dir()
return [
run_profiles_root / f"{base}.local.yaml",
run_profiles_root / f"{base}.local.yml",
run_profiles_root / f"{base}.local.json",
preset_templates_root / f"{base}.default.yaml",
preset_templates_root / f"{base}.default.yml",
preset_templates_root / f"{base}.default.json",
]
def resolve_preset_file(preset_name: str) -> Tuple[Path, bool]:
candidates = get_preset_file_candidates(preset_name)
for idx, path in enumerate(candidates):
if path.exists() and path.is_file():
return path, idx > 0
raise FileNotFoundError(
f"No preset file found for {preset_name}. Tried: {[str(p) for p in candidates]}"
)
def load_overrides_from_file(file_path: Path, project_root: Path) -> Dict[str, Any]:
suffix = file_path.suffix.lower()
text = file_path.read_text(encoding="utf-8")
if suffix in {".yaml", ".yml"}:
try:
import yaml # type: ignore
except Exception as exc:
raise RuntimeError(
"YAML config requires PyYAML. Install with: pip install pyyaml"
) from exc
payload = yaml.safe_load(text)
else:
payload = json.loads(text)
resolved = _replace_placeholders(payload, project_root)
if not isinstance(resolved, dict):
raise ValueError(f"Preset file must contain object mapping: {file_path}")
return resolved
def load_named_preset_overrides(project_root: Path, preset_name: str) -> Tuple[Dict[str, Any], Path, bool]:
file_path, used_default = resolve_preset_file(preset_name)
overrides = load_overrides_from_file(file_path, project_root)
return overrides, file_path, used_default