kiwi-scp/kiwi_scp/instance.py

90 lines
2.3 KiB
Python
Raw Normal View History

2021-10-22 15:50:26 +00:00
import functools
import re
from pathlib import Path
2021-10-28 14:48:54 +00:00
from typing import Generator, List, Tuple, Optional
2021-10-22 15:50:26 +00:00
import attr
2021-10-25 11:29:12 +00:00
import click
2021-10-28 13:53:32 +00:00
from ruamel.yaml.comments import CommentedMap
2021-10-22 15:50:26 +00:00
from ._constants import COMPOSE_FILE_NAME
2021-10-27 11:33:26 +00:00
from .config import KiwiConfig
from .misc import YAML
2021-10-22 15:50:26 +00:00
_RE_CONFDIR = re.compile(r"^\s*\$(?:CONFDIR|{CONFDIR})/+(.*)$", flags=re.UNICODE)
@attr.s
class Service:
name: str = attr.ib()
2021-10-28 13:53:32 +00:00
description: CommentedMap = attr.ib()
2021-10-22 15:50:26 +00:00
2021-10-28 13:53:32 +00:00
def __str__(self) -> str:
return YAML().dump({
"service": {
self.name: self.description
}
2021-10-28 14:48:54 +00:00
}).strip()
2021-10-22 15:50:26 +00:00
2021-10-28 13:53:32 +00:00
@property
def configs(self) -> Generator[Path, None, None]:
if "volumes" not in self.description:
return
2021-10-22 15:50:26 +00:00
2021-10-28 13:53:32 +00:00
for volume in self.description["volumes"]:
host_part = volume.split(":")[0]
cd_match = _RE_CONFDIR.match(host_part)
2021-10-22 15:50:26 +00:00
2021-10-28 13:53:32 +00:00
if cd_match:
2021-10-28 14:48:54 +00:00
yield Path(cd_match.group(1))
2021-10-22 15:50:26 +00:00
2021-10-28 13:53:32 +00:00
@attr.s
class Services:
project_name: str = attr.ib()
content: List[Service] = attr.ib()
def __str__(self) -> str:
return YAML().dump({
"services": {
service.name: service.description
for service in self.content
}
2021-10-28 14:48:54 +00:00
}).strip()
2021-10-22 15:50:26 +00:00
@attr.s
class Instance:
directory: Path = attr.ib(default=Path('.'))
@property
2021-10-26 13:59:38 +00:00
def config(self) -> KiwiConfig:
2021-10-22 15:50:26 +00:00
"""shorthand: get the current configuration"""
2021-10-26 13:59:38 +00:00
return KiwiConfig.from_directory(self.directory)
2021-10-26 10:28:06 +00:00
2021-10-28 13:53:32 +00:00
@staticmethod
2021-10-26 13:59:38 +00:00
@functools.lru_cache(maxsize=10)
2021-10-28 13:53:32 +00:00
def _parse_compose_file(directory: Path):
2021-10-26 13:59:38 +00:00
with open(directory.joinpath(COMPOSE_FILE_NAME), "r") as cf:
2021-10-27 11:33:26 +00:00
return YAML().load(cf)
2021-10-26 13:59:38 +00:00
2021-10-28 14:48:54 +00:00
def get_services(self, project_name: str, service_names: Optional[Tuple[str]] = None) -> Services:
2021-10-26 13:59:38 +00:00
yml = Instance._parse_compose_file(self.directory.joinpath(project_name))
2021-10-28 14:48:54 +00:00
services = [
2021-10-28 13:53:32 +00:00
Service(name, description)
2021-10-26 13:59:38 +00:00
for name, description in yml["services"].items()
2021-10-28 14:48:54 +00:00
]
if service_names is None:
return Services(project_name, services)
else:
return Services(project_name, [
service
for service in services
if service.name in service_names
])
2021-10-25 11:29:12 +00:00
pass_instance = click.make_pass_decorator(Instance, ensure=True)