import tomllib from pathlib import Path from typing import Any from typing import NamedTuple from typing import Self from many_repos import errors class Source(NamedTuple): source_type: str username: str token: str forks: bool @classmethod def from_dict(cls, _dict: dict[str, Any]) -> Self: return cls( source_type=_dict.get("type"), username=_dict.get("username"), token=_dict.get("token"), forks=_dict.get("forks", False) ) class Config(NamedTuple): output_dir: str | Path sources_configs: dict[str, Source] | None @classmethod def from_dict(cls, _dict: dict[str, Any]) -> Self: output_dir = _dict.get("config").get("output_dir", None) sources = {name: Source.from_dict(src) for name, src in _dict.get("sources").items()} if not output_dir: raise errors.InvalidConfig("`output_dir` needs to be specified!") cfg = cls(output_dir=output_dir, sources_configs=sources) return cfg def load_config(config_path: str | Path) -> Config: config_path = Path(config_path) if not config_path.exists(): raise errors.ConfigNotFound(f"Config at path {config_path} not found!") with config_path.open("rb") as fp: parsed_config = tomllib.load(fp) return Config.from_dict(parsed_config)