mirror of
https://github.com/yavook/kiwi-scp.git
synced 2024-11-22 04:43:00 +00:00
82 lines
2 KiB
Python
82 lines
2 KiB
Python
import functools
|
|
import re
|
|
from pathlib import Path
|
|
from typing import List, Dict, Any, Generator
|
|
|
|
import attr
|
|
import click
|
|
import ruamel.yaml
|
|
|
|
from ._constants import COMPOSE_FILE_NAME
|
|
from .config import Config
|
|
|
|
_RE_CONFDIR = re.compile(r"^\s*\$(?:CONFDIR|{CONFDIR})/+(.*)$", flags=re.UNICODE)
|
|
|
|
|
|
@attr.s
|
|
class Service:
|
|
name: str = attr.ib()
|
|
configs: List[Path] = attr.ib()
|
|
|
|
@classmethod
|
|
def from_description(cls, name: str, description: Dict[str, Any]):
|
|
configs: List[Path] = []
|
|
|
|
if "volumes" in description:
|
|
volumes: List[str] = description["volumes"]
|
|
|
|
for volume in volumes:
|
|
host_part = volume.split(":")[0]
|
|
confdir = _RE_CONFDIR.match(host_part)
|
|
|
|
if confdir:
|
|
configs.append(Path(confdir.group(1)))
|
|
|
|
return cls(
|
|
name=name,
|
|
configs=configs,
|
|
)
|
|
|
|
|
|
@attr.s
|
|
class Project:
|
|
directory: Path = attr.ib()
|
|
services: List[Service] = attr.ib()
|
|
|
|
@classmethod
|
|
@functools.lru_cache(maxsize=10)
|
|
def from_directory(cls, directory: Path):
|
|
with open(directory.joinpath(COMPOSE_FILE_NAME), "r") as cf:
|
|
yml = ruamel.yaml.round_trip_load(cf)
|
|
|
|
return cls(
|
|
directory=directory,
|
|
services=[
|
|
Service.from_description(name, description)
|
|
for name, description in yml["services"].items()
|
|
],
|
|
)
|
|
|
|
|
|
@attr.s
|
|
class Instance:
|
|
directory: Path = attr.ib(default=Path('.'))
|
|
|
|
@property
|
|
def config(self) -> Config:
|
|
"""shorthand: get the current configuration"""
|
|
|
|
return Config.from_directory(self.directory)
|
|
|
|
def get_project(self, name: str) -> Project:
|
|
return Project.from_directory(self.directory.joinpath(name))
|
|
|
|
@property
|
|
def projects(self) -> Generator[Project, None, None]:
|
|
return (
|
|
self.get_project(project.name)
|
|
for project in self.config.projects
|
|
)
|
|
|
|
|
|
pass_instance = click.make_pass_decorator(Instance, ensure=True)
|