From baf5962f34697d4e5e0bf63fc5ace657020088c3 Mon Sep 17 00:00:00 2001 From: Cian Hughes Date: Wed, 1 Nov 2023 15:33:40 +0000 Subject: [PATCH] Cleaned up lazy/messy config implementation --- src/node_deployer/__main__.py | 4 +- src/node_deployer/autoignition.py | 2 +- src/node_deployer/cli.py | 2 +- src/node_deployer/config.py | 175 ++++++++++++++--------------- src/node_deployer/create_disk.py | 2 +- src/node_deployer/create_img.py | 2 +- src/node_deployer/debug.py | 2 +- src/node_deployer/node_deployer.py | 2 +- src/node_deployer/utils.py | 2 +- 9 files changed, 95 insertions(+), 98 deletions(-) diff --git a/src/node_deployer/__main__.py b/src/node_deployer/__main__.py index 6aa97e1..d9b2e25 100644 --- a/src/node_deployer/__main__.py +++ b/src/node_deployer/__main__.py @@ -3,7 +3,7 @@ def main() -> None: """Entry point for the CLI """ - from . import config + from .config import config config.update_config("cli") from .node_deployer import app app() @@ -11,7 +11,7 @@ def main() -> None: def debug() -> None: """Entry point for the debug CLI """ - from . import config + from .config import config config.update_config("debug") from .node_deployer import app diff --git a/src/node_deployer/autoignition.py b/src/node_deployer/autoignition.py index 07d8c6d..d40a776 100644 --- a/src/node_deployer/autoignition.py +++ b/src/node_deployer/autoignition.py @@ -13,7 +13,7 @@ from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.support.ui import WebDriverWait import typer -from . import config +from .config import config from .cli import cli_spinner from .debug import debug_guard from .utils import ensure_build_dir diff --git a/src/node_deployer/cli.py b/src/node_deployer/cli.py index d1f69f6..fc9d39a 100644 --- a/src/node_deployer/cli.py +++ b/src/node_deployer/cli.py @@ -4,7 +4,7 @@ from typing import Callable from rich.progress import Progress, SpinnerColumn, TextColumn -from . import config +from .config import config from .utils import Singleton diff --git a/src/node_deployer/config.py b/src/node_deployer/config.py index bc6565d..9df19b3 100644 --- a/src/node_deployer/config.py +++ b/src/node_deployer/config.py @@ -1,10 +1,5 @@ -# flake8: noqa: F821 -# type: ignore -#* This file sets a number of config constants by modifying its own globals -#* As a result, F821 and typing is disabled as the interpreter cannot be -#* trusted to know when F821 or UndefinedVeriable errors should be raised. - from pathlib import Path +from types import SimpleNamespace import docker import tomllib @@ -17,90 +12,92 @@ PROJECT_ROOT: Path = Path(__file__).parent.parent.parent.absolute() type ConfigLabel = str | list[str] -def get_config(config_label: ConfigLabel = "default") -> dict: - """Gets the specified configuration from config.toml +class Config(SimpleNamespace): + def __init__(self, config_label: ConfigLabel, **kwargs) -> None: + """Initialises the configuration object - Args: - config_label (ConfigLabel, optional): - The label of the configuration to get. - Defaults to "default". + Args: + config_label (ConfigLabel): The configuration to initialise with + **kwargs: Additional keyword arguments to become attributes + """ + self.__dict__.update(self.get_config(config_label)) + self.update_config() + _kwargs = { + "CLIENT": CLIENT, + "MAX_PORT": MAX_PORT, + "PROJECT_ROOT": PROJECT_ROOT, + } + _kwargs.update(kwargs) + super().__init__(**_kwargs) - Returns: - dict: The specified configuration - """ - if isinstance(config_label, str): - config_label = [config_label] - with open(PROJECT_ROOT / "config.toml", "rb") as f: - configs: dict = tomllib.load(f) - out_config: dict = {} - for c in config_label: - out_config.update(configs[c]) - return out_config + @staticmethod + def get_config(config_label: ConfigLabel = "default") -> dict: + """Gets the specified configuration from config.toml + + Args: + config_label (ConfigLabel, optional): + The label of the configuration to get. + Defaults to "default". + + Returns: + dict: The specified configuration + """ + if isinstance(config_label, str): + config_label = [config_label] + with open(PROJECT_ROOT / "config.toml", "rb") as f: + configs: dict = tomllib.load(f) + out_config: dict = {} + for c in config_label: + out_config.update(configs[c]) + return out_config + + def finalise_config(self, config: dict) -> None: + """Finalises the configuration by converting paths to Path objects and + appropriately setting secondary parameters such as relative paths + + Args: + config (dict): The configuration to finalise + """ + # First, convert base paths to Path objects + for k, v in config.items(): + match k: + case "SRC_DIR" | "BUILD_DIR": + config[k] = Path(v).absolute() + case "CWD_MOUNTDIR": + config[k] = Path(v) + # Then, get required paths from config or globals if not present + build_dir = config.get("BUILD_DIR", self.BUILD_DIR) + cwd_mountdir = config.get("CWD_MOUNTDIR", self.CWD_MOUNTDIR) + src_dir = config.get("SRC_DIR", self.SRC_DIR) + # Finally, construct the secondary parameters + config["FUELIGNITION_BUILD_DIR"] = build_dir / config.get( + "FUELIGNITION_BUILD_DIR", self.FUELIGNITION_BUILD_DIR + ) + config["DOCKERFILE_DIR"] = src_dir / config.get("DOCKERFILE_DIR", self.DOCKERFILE_DIR) + config["CWD_MOUNT"] = docker.types.Mount( + target=str(cwd_mountdir), + source=str(PROJECT_ROOT), + type="bind", + ) + + def apply_config(self, config: dict) -> None: + """Applies the specified configuration to this object's attributes + + Args: + config (dict): The configuration to apply + """ + self.finalise_config(config) + self.__dict__.update(config) + + def update_config(self, config_label: ConfigLabel = "default") -> None: + """Updates the configuration to the specified configuration + + Args: + config_label (ConfigLabel, optional): + The label of the configuration to update to. + Defaults to "default". + """ + self.apply_config(self.get_config(config_label)) -def finalise_config(config: dict) -> None: - """Finalises the configuration by converting paths to Path objects and - appropriately setting secondary parameters such as relative paths - - Args: - config (dict): The configuration to finalise - """ - # First, convert base paths to Path objects - for k, v in config.items(): - match k: - case "SRC_DIR" | "BUILD_DIR": - config[k] = Path(v).absolute() - case "CWD_MOUNTDIR": - config[k] = Path(v) - # Then, get required paths from config or globals if not present - build_dir = config.get("BUILD_DIR", BUILD_DIR) - cwd_mountdir = config.get("CWD_MOUNTDIR", CWD_MOUNTDIR) - src_dir = config.get("SRC_DIR", SRC_DIR) - # Finally, construct the secondary parameters - config["FUELIGNITION_BUILD_DIR"] = build_dir / config.get( - "FUELIGNITION_BUILD_DIR", - FUELIGNITION_BUILD_DIR - ) - config["DOCKERFILE_DIR"] = src_dir / config.get( - "DOCKERFILE_DIR", - DOCKERFILE_DIR - ) - config["CWD_MOUNT"] = docker.types.Mount( - target=str(cwd_mountdir), - source=str(PROJECT_ROOT), - type="bind", - ) - - -def apply_config(config: dict) -> None: - """Applies the specified configuration to this module's globals - - Args: - config (dict): The configuration to apply - """ - finalise_config(config) - globals().update(config) - - -def update_config(config_label: ConfigLabel = "default") -> None: - """Updates the configuration to the specified configuration - - Args: - config_label (ConfigLabel, optional): - The label of the configuration to update to. - Defaults to "default". - """ - apply_config(get_config(config_label)) - - -def init(config_label: ConfigLabel) -> None: - """Initialises the configuration module - - Args: - config_label (ConfigLabel): The configuration to initialise with - """ - globals().update(get_config(config_label)) - update_config() - - -init(config_label="default") \ No newline at end of file +config = Config(config_label="default") diff --git a/src/node_deployer/create_disk.py b/src/node_deployer/create_disk.py index 2a7b571..595ebc4 100644 --- a/src/node_deployer/create_disk.py +++ b/src/node_deployer/create_disk.py @@ -6,7 +6,7 @@ from docker.types import Mount import typer from typing import Tuple -from . import config +from .config import config from .cli import cli_spinner from .create_img import create_img from .debug import debug_guard diff --git a/src/node_deployer/create_img.py b/src/node_deployer/create_img.py index 035baa8..44df6a6 100644 --- a/src/node_deployer/create_img.py +++ b/src/node_deployer/create_img.py @@ -5,7 +5,7 @@ from typing import Annotated import typer -from . import config +from .config import config from .autoignition import json_to_img from .cli import cli_spinner from .debug import debug_guard diff --git a/src/node_deployer/debug.py b/src/node_deployer/debug.py index e910904..5449fba 100644 --- a/src/node_deployer/debug.py +++ b/src/node_deployer/debug.py @@ -4,7 +4,7 @@ from typing import Callable import typer -from . import config +from .config import config def debug_guard(f: Callable) -> Callable: diff --git a/src/node_deployer/node_deployer.py b/src/node_deployer/node_deployer.py index 2f65c5a..63717ad 100755 --- a/src/node_deployer/node_deployer.py +++ b/src/node_deployer/node_deployer.py @@ -1,6 +1,6 @@ import typer -from . import config +from .config import config from .autoignition import json_to_img from .create_disk import create_ignition_disk from .create_img import create_img diff --git a/src/node_deployer/utils.py b/src/node_deployer/utils.py index b334302..4da6c04 100644 --- a/src/node_deployer/utils.py +++ b/src/node_deployer/utils.py @@ -2,7 +2,7 @@ from functools import wraps from pathlib import Path from typing import Callable -from . import config +from .config import config def ensure_build_dir(f: Callable) -> Callable: