instance parent relations

This commit is contained in:
Jörn-Michael Miehe 2021-12-02 02:38:29 +01:00
parent 15f0ac30b5
commit 0fc55154f2
5 changed files with 25 additions and 36 deletions

View file

@ -150,7 +150,7 @@ class KiwiCommand:
cls.run_for_new_project(instance, project_name, **kwargs) cls.run_for_new_project(instance, project_name, **kwargs)
else: 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}!") cls.print_error(f"Can't interact with disabled project {project_name}!")
return return
@ -166,7 +166,7 @@ class KiwiCommand:
cls.print_error(f"Project '{project_name}' not in kiwi-scp instance at '{instance.directory}'!") cls.print_error(f"Project '{project_name}' not in kiwi-scp instance at '{instance.directory}'!")
else: 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}!") cls.print_error(f"Can't interact with disabled project {project_name}!")
return return

View file

@ -27,11 +27,11 @@ class DisableCommand(KiwiCommand):
@classmethod @classmethod
def run_for_project(cls, instance: Instance, project: Project, **kwargs) -> None: 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!") KiwiCommand.print_error(f"Project {project.name} is already disabled!")
return return
project.project_config.enabled = False project.config.enabled = False
KiwiCommand.print_header(f"Project {project.name} disabled") KiwiCommand.print_header(f"Project {project.name} disabled")
# write out the new kiwi.yml # write out the new kiwi.yml

View file

@ -27,11 +27,11 @@ class DisableCommand(KiwiCommand):
@classmethod @classmethod
def run_for_project(cls, instance: Instance, project: Project, **kwargs) -> None: 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!") KiwiCommand.print_error(f"Project {project.name} is already enabled!")
return return
project.project_config.enabled = True project.config.enabled = True
KiwiCommand.print_header(f"Project {project.name} enabled") KiwiCommand.print_header(f"Project {project.name} enabled")
# write out the new kiwi.yml # write out the new kiwi.yml

View file

@ -1,5 +1,6 @@
import functools import functools
import re import re
import subprocess
from pathlib import Path from pathlib import Path
from typing import Generator, List, Optional, Dict, Any 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 ._constants import COMPOSE_FILE_NAME, CONF_DIRECTORY_NAME
from .config import KiwiConfig, ProjectConfig from .config import KiwiConfig, ProjectConfig
from .executable import COMPOSE_EXE
from .misc import YAML from .misc import YAML
_RE_CONFDIR = re.compile(r"^\s*\$(?:CONFDIR|{CONFDIR})/+(.*)$", flags=re.UNICODE)
@attr.s @attr.s
class Service: class Service:
name: str = attr.ib() name: str = attr.ib()
content: CommentedMap = 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 @property
def configs(self) -> Generator[Path, None, None]: def configs(self) -> Generator[Path, None, None]:
@ -25,7 +28,7 @@ class Service:
for volume in self.content["volumes"]: for volume in self.content["volumes"]:
host_part = volume.split(":")[0] host_part = volume.split(":")[0]
cd_match = _RE_CONFDIR.match(host_part) cd_match = Service._RE_CONFDIR.match(host_part)
if cd_match: if cd_match:
yield Path(cd_match.group(1)) yield Path(cd_match.group(1))
@ -64,7 +67,7 @@ class Services:
@attr.s @attr.s
class Project: class Project:
directory: Path = attr.ib() directory: Path = attr.ib()
config: KiwiConfig = attr.ib() parent: Optional["Instance"] = attr.ib(default=None)
@staticmethod @staticmethod
@functools.lru_cache(maxsize=10) @functools.lru_cache(maxsize=10)
@ -77,15 +80,15 @@ class Project:
return self.directory.name return self.directory.name
@property @property
def project_config(self) -> ProjectConfig: def config(self) -> ProjectConfig:
return self.config.get_project_config(self.name) return self.parent.config.get_project_config(self.name)
@property @property
def process_kwargs(self) -> Dict[str, Any]: def process_kwargs(self) -> Dict[str, Any]:
directory: Path = self.directory directory: Path = self.directory
project_name: str = self.name project_name: str = self.name
kiwi_hub_name: str = self.config.network.name kiwi_hub_name: str = self.parent.config.network.name
target_root_dir: Path = self.config.storage.directory target_root_dir: Path = self.parent.config.storage.directory
conf_dir: Path = target_root_dir.joinpath(CONF_DIRECTORY_NAME) conf_dir: Path = target_root_dir.joinpath(CONF_DIRECTORY_NAME)
target_dir: Path = target_root_dir.joinpath(project_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 return result
@ -109,12 +112,12 @@ class Project:
yml = Project._parse_compose_file(self.directory) yml = Project._parse_compose_file(self.directory)
return Services([ return Services([
Service(name, description) Service(name, content, self)
for name, description in yml["services"].items() for name, content in yml["services"].items()
]) ])
@attr.s @attr.s(frozen=True)
class Instance: class Instance:
directory: Path = attr.ib(default=Path('.')) directory: Path = attr.ib(default=Path('.'))
@ -124,23 +127,11 @@ class Instance:
return KiwiConfig.from_directory(self.directory) return KiwiConfig.from_directory(self.directory)
@staticmethod
@functools.lru_cache(maxsize=None) @functools.lru_cache(maxsize=None)
def __get_project(instance_directory: Path, project_name: str) -> Optional[Project]: def get_project(self, project_name: str) -> Optional[Project]:
instance = Instance(instance_directory) for project in self.config.projects:
config = instance.config
for project in config.projects:
if project.name == project_name: if project.name == project_name:
return Project( return Project(
directory=instance_directory.joinpath(project.name), directory=self.directory.joinpath(project.name),
config=config, 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

View file

@ -13,7 +13,6 @@ class TestDefault:
def test_example(self): def test_example(self):
p = Project( p = Project(
directory=Path("example/hello-world.project"), directory=Path("example/hello-world.project"),
config=TestDefault.cfg,
) )
ss = p.services ss = p.services
@ -31,7 +30,6 @@ class TestDefault:
def test_empty(self): def test_empty(self):
p = Project( p = Project(
directory=Path("nonexistent"), directory=Path("nonexistent"),
config=TestDefault.cfg,
) )
with pytest.raises(FileNotFoundError) as exc_info: with pytest.raises(FileNotFoundError) as exc_info: