from typing import Any, cast import yaml from config import validator from config.dtype import ArchMgrConfig from config.merger import merge_configs def _load_config_file(file: str): with open(file, "r") as f: parsed = yaml.load(f, Loader=yaml.FullLoader) return parsed def default_config() -> ArchMgrConfig: """Get the default configuration Returns: The default config """ return { "pkgs": { "individual": [], "bundles": [], "repos": { "enabled_repos": [ { "name": "core", "setup_cmds": [], "mirrors": {"use_default": True, "extra_mirrors": []}, } ], "reflector": { "enabled": False, "count": 0, "countries": [], "interval": 1, }, }, }, "boot": { "managed": False, "bootloader": "grub", "esp_dir": "/boot", "os_prober": False, "theme_folder": "/usr/share/themes/grub", }, "cmds": {"always": [], "once": []}, "git": { "repos": [], "creds": {"manager": "git-credential-manager"}, }, "users": [], "symlinks": [], "template_data": [], "themes": { "cursor_theme": "oreo_spark_blue_cursor", "font": "Comfortaa 11", "gtk": "Adaptive-Theme", "qt": "gtk3", "icon_theme": "candy-icons" }, } def load_config(file: str) -> ArchMgrConfig: """Load the configuration from the specified file path Args: file: Path to the file to be loaded Returns: The loaded, validated and parsed config """ # Load and validate initial config try: loaded_conf = _load_config_file(file) except Exception: return default_config() if not validator.validate(loaded_conf): return default_config() configuration = cast(dict[str, Any], loaded_conf) requires = cast(list[str], configuration.pop("requires")) conf = cast(ArchMgrConfig, configuration) # Recursively load files for conf_file in requires: conf = merge_configs(conf, load_config(conf_file)) return conf