65 lines
1.8 KiB
Python
65 lines
1.8 KiB
Python
from __future__ import annotations
|
|
|
|
import argparse
|
|
import asyncio
|
|
import logging
|
|
from pathlib import Path
|
|
|
|
from .config import build_config, load_overrides_from_file
|
|
from .pipeline import run_pipeline_from_config
|
|
|
|
|
|
def package_project_root() -> Path:
|
|
return Path(__file__).resolve().parents[1]
|
|
|
|
|
|
def resolve_config_path(raw_path: str, *, project_root: Path) -> Path:
|
|
path = Path(raw_path)
|
|
if not path.is_absolute():
|
|
path = project_root / path
|
|
return path.resolve()
|
|
|
|
|
|
async def _main() -> int:
|
|
project_root = package_project_root()
|
|
|
|
parser = argparse.ArgumentParser(description="Run sync pipeline from config override file")
|
|
parser.add_argument(
|
|
"--config_path",
|
|
required=True,
|
|
help="Path to a JSON/YAML run profile. Relative paths are resolved from the repository root.",
|
|
)
|
|
args = parser.parse_args()
|
|
|
|
cfg_path = resolve_config_path(args.config_path, project_root=project_root)
|
|
if not cfg_path.exists() or not cfg_path.is_file():
|
|
raise FileNotFoundError(f"Config file not found: {cfg_path}")
|
|
|
|
overrides = load_overrides_from_file(cfg_path, project_root)
|
|
config = build_config(project_root=project_root, overrides=overrides)
|
|
|
|
mode = f"{config.local_datasource.type}->{config.remote_datasource.type}"
|
|
print(f"🧩 Loaded config file: {cfg_path}")
|
|
await run_pipeline_from_config(
|
|
config,
|
|
title=f"sync_state_machine pipeline ({mode})",
|
|
print_summary=True,
|
|
)
|
|
return 0
|
|
|
|
|
|
def main() -> int:
|
|
try:
|
|
return asyncio.run(_main())
|
|
except KeyboardInterrupt:
|
|
print("\n⚠️ Interrupted by user")
|
|
return 130
|
|
except Exception as exc:
|
|
print(f"\n❌ Pipeline failed: {type(exc).__name__}: {exc}")
|
|
return 1
|
|
finally:
|
|
logging.shutdown()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main()) |