From 0fc55154f2258f84b7f4b0fbe21ce765383946ce Mon Sep 17 00:00:00 2001 From: ldericher <40151420+ldericher@users.noreply.github.com> Date: Thu, 2 Dec 2021 02:38:29 +0100 Subject: [PATCH] instance parent relations --- kiwi_scp/commands/cli.py | 4 +-- kiwi_scp/commands/cmd_disable.py | 4 +-- kiwi_scp/commands/cmd_enable.py | 4 +-- kiwi_scp/instance.py | 47 +++++++++++++------------------- tests/test_project.py | 2 -- 5 files changed, 25 insertions(+), 36 deletions(-) diff --git a/kiwi_scp/commands/cli.py b/kiwi_scp/commands/cli.py index 2d987fb..01e2087 100644 --- a/kiwi_scp/commands/cli.py +++ b/kiwi_scp/commands/cli.py @@ -150,7 +150,7 @@ class KiwiCommand: cls.run_for_new_project(instance, project_name, **kwargs) else: - if cls.enabled_only and not project.project_config.enabled: + if cls.enabled_only and not project.config.enabled: cls.print_error(f"Can't interact with disabled project {project_name}!") return @@ -166,7 +166,7 @@ class KiwiCommand: cls.print_error(f"Project '{project_name}' not in kiwi-scp instance at '{instance.directory}'!") else: - if cls.enabled_only and not project.project_config.enabled: + if cls.enabled_only and not project.config.enabled: cls.print_error(f"Can't interact with disabled project {project_name}!") return diff --git a/kiwi_scp/commands/cmd_disable.py b/kiwi_scp/commands/cmd_disable.py index adb1687..6a146d0 100644 --- a/kiwi_scp/commands/cmd_disable.py +++ b/kiwi_scp/commands/cmd_disable.py @@ -27,11 +27,11 @@ class DisableCommand(KiwiCommand): @classmethod def run_for_project(cls, instance: Instance, project: Project, **kwargs) -> None: - if not project.project_config.enabled: + if not project.config.enabled: KiwiCommand.print_error(f"Project {project.name} is already disabled!") return - project.project_config.enabled = False + project.config.enabled = False KiwiCommand.print_header(f"Project {project.name} disabled") # write out the new kiwi.yml diff --git a/kiwi_scp/commands/cmd_enable.py b/kiwi_scp/commands/cmd_enable.py index 580644a..9f7eadc 100644 --- a/kiwi_scp/commands/cmd_enable.py +++ b/kiwi_scp/commands/cmd_enable.py @@ -27,11 +27,11 @@ class DisableCommand(KiwiCommand): @classmethod def run_for_project(cls, instance: Instance, project: Project, **kwargs) -> None: - if project.project_config.enabled: + if project.config.enabled: KiwiCommand.print_error(f"Project {project.name} is already enabled!") return - project.project_config.enabled = True + project.config.enabled = True KiwiCommand.print_header(f"Project {project.name} enabled") # write out the new kiwi.yml diff --git a/kiwi_scp/instance.py b/kiwi_scp/instance.py index 47453c9..3d47c87 100644 --- a/kiwi_scp/instance.py +++ b/kiwi_scp/instance.py @@ -1,5 +1,6 @@ import functools import re +import subprocess from pathlib import Path from typing import Generator, List, Optional, Dict, Any @@ -8,15 +9,17 @@ from ruamel.yaml.comments import CommentedMap from ._constants import COMPOSE_FILE_NAME, CONF_DIRECTORY_NAME from .config import KiwiConfig, ProjectConfig +from .executable import COMPOSE_EXE from .misc import YAML -_RE_CONFDIR = re.compile(r"^\s*\$(?:CONFDIR|{CONFDIR})/+(.*)$", flags=re.UNICODE) - @attr.s class Service: name: str = attr.ib() content: CommentedMap = attr.ib() + parent: Optional["Project"] = attr.ib(default=None) + + _RE_CONFDIR = re.compile(r"^\s*\$(?:CONFDIR|{CONFDIR})/+(.*)$", flags=re.UNICODE) @property def configs(self) -> Generator[Path, None, None]: @@ -25,7 +28,7 @@ class Service: for volume in self.content["volumes"]: host_part = volume.split(":")[0] - cd_match = _RE_CONFDIR.match(host_part) + cd_match = Service._RE_CONFDIR.match(host_part) if cd_match: yield Path(cd_match.group(1)) @@ -64,7 +67,7 @@ class Services: @attr.s class Project: directory: Path = attr.ib() - config: KiwiConfig = attr.ib() + parent: Optional["Instance"] = attr.ib(default=None) @staticmethod @functools.lru_cache(maxsize=10) @@ -77,15 +80,15 @@ class Project: return self.directory.name @property - def project_config(self) -> ProjectConfig: - return self.config.get_project_config(self.name) + def config(self) -> ProjectConfig: + return self.parent.config.get_project_config(self.name) @property def process_kwargs(self) -> Dict[str, Any]: directory: Path = self.directory project_name: str = self.name - kiwi_hub_name: str = self.config.network.name - target_root_dir: Path = self.config.storage.directory + kiwi_hub_name: str = self.parent.config.network.name + target_root_dir: Path = self.parent.config.storage.directory conf_dir: Path = target_root_dir.joinpath(CONF_DIRECTORY_NAME) target_dir: Path = target_root_dir.joinpath(project_name) @@ -100,7 +103,7 @@ class Project: }, } - result["env"].update(self.config.environment) + result["env"].update(self.parent.config.environment) return result @@ -109,12 +112,12 @@ class Project: yml = Project._parse_compose_file(self.directory) return Services([ - Service(name, description) - for name, description in yml["services"].items() + Service(name, content, self) + for name, content in yml["services"].items() ]) -@attr.s +@attr.s(frozen=True) class Instance: directory: Path = attr.ib(default=Path('.')) @@ -124,23 +127,11 @@ class Instance: return KiwiConfig.from_directory(self.directory) - @staticmethod @functools.lru_cache(maxsize=None) - def __get_project(instance_directory: Path, project_name: str) -> Optional[Project]: - instance = Instance(instance_directory) - config = instance.config - - for project in config.projects: + def get_project(self, project_name: str) -> Optional[Project]: + for project in self.config.projects: if project.name == project_name: return Project( - directory=instance_directory.joinpath(project.name), - config=config, + directory=self.directory.joinpath(project.name), + parent=self, ) - - def get_project(self, project_name: str) -> Optional[Project]: - project = Instance.__get_project(self.directory, project_name) - if project is None: - return - - project.instance = self - return project diff --git a/tests/test_project.py b/tests/test_project.py index 72fcf79..aef5915 100644 --- a/tests/test_project.py +++ b/tests/test_project.py @@ -13,7 +13,6 @@ class TestDefault: def test_example(self): p = Project( directory=Path("example/hello-world.project"), - config=TestDefault.cfg, ) ss = p.services @@ -31,7 +30,6 @@ class TestDefault: def test_empty(self): p = Project( directory=Path("nonexistent"), - config=TestDefault.cfg, ) with pytest.raises(FileNotFoundError) as exc_info: