52 lines
1.4 KiB
Python
52 lines
1.4 KiB
Python
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] | dict
|
|
|
|
@classmethod
|
|
def from_dict(cls, _dict: dict[str, Any]) -> Self:
|
|
|
|
if not (cfg := _dict.get("config")):
|
|
raise errors.InvalidConfig("`[config]` cannot be empty!")
|
|
|
|
output_dir = cfg.get("output_dir", None)
|
|
sources = {name: Source.from_dict(src) for name, src in _dict.get("sources", dict()).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)
|