mirror of
https://github.com/yavook/kiwi-scp.git
synced 2024-11-22 04:43:00 +00:00
89 lines
2.3 KiB
Python
89 lines
2.3 KiB
Python
import functools
|
|
import re
|
|
from pathlib import Path
|
|
from typing import Generator, List, Tuple, Optional
|
|
|
|
import attr
|
|
import click
|
|
from ruamel.yaml.comments import CommentedMap
|
|
|
|
from ._constants import COMPOSE_FILE_NAME
|
|
from .config import KiwiConfig
|
|
from .misc import YAML
|
|
|
|
_RE_CONFDIR = re.compile(r"^\s*\$(?:CONFDIR|{CONFDIR})/+(.*)$", flags=re.UNICODE)
|
|
|
|
|
|
@attr.s
|
|
class Service:
|
|
name: str = attr.ib()
|
|
description: CommentedMap = attr.ib()
|
|
|
|
def __str__(self) -> str:
|
|
return YAML().dump({
|
|
"service": {
|
|
self.name: self.description
|
|
}
|
|
}).strip()
|
|
|
|
@property
|
|
def configs(self) -> Generator[Path, None, None]:
|
|
if "volumes" not in self.description:
|
|
return
|
|
|
|
for volume in self.description["volumes"]:
|
|
host_part = volume.split(":")[0]
|
|
cd_match = _RE_CONFDIR.match(host_part)
|
|
|
|
if cd_match:
|
|
yield Path(cd_match.group(1))
|
|
|
|
|
|
@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
|
|
}
|
|
}).strip()
|
|
|
|
|
|
@attr.s
|
|
class Instance:
|
|
directory: Path = attr.ib(default=Path('.'))
|
|
|
|
@property
|
|
def config(self) -> KiwiConfig:
|
|
"""shorthand: get the current configuration"""
|
|
|
|
return KiwiConfig.from_directory(self.directory)
|
|
|
|
@staticmethod
|
|
@functools.lru_cache(maxsize=10)
|
|
def _parse_compose_file(directory: Path):
|
|
with open(directory.joinpath(COMPOSE_FILE_NAME), "r") as cf:
|
|
return YAML().load(cf)
|
|
|
|
def get_services(self, project_name: str, service_names: Optional[Tuple[str]] = None) -> Services:
|
|
yml = Instance._parse_compose_file(self.directory.joinpath(project_name))
|
|
services = [
|
|
Service(name, description)
|
|
for name, description in yml["services"].items()
|
|
]
|
|
|
|
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
|
|
])
|
|
|
|
|
|
pass_instance = click.make_pass_decorator(Instance, ensure=True)
|