diff --git a/kiwi_scp/instance.py b/kiwi_scp/instance.py new file mode 100644 index 0000000..41facbe --- /dev/null +++ b/kiwi_scp/instance.py @@ -0,0 +1,72 @@ +import functools +import re +from pathlib import Path +from typing import Iterable, List, Dict, Any + +import attr +import 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 = yaml.safe_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_instance(self.directory) + + @property + def projects(self) -> Iterable[Project]: + return [] diff --git a/tests/test_project.py b/tests/test_project.py new file mode 100644 index 0000000..eccff01 --- /dev/null +++ b/tests/test_project.py @@ -0,0 +1,32 @@ +from pathlib import Path + +from kiwi_scp.instance import Project + + +def test_example(): + p = Project.from_directory(Path("example/hello-world.project")) + + assert p.directory == Path("example/hello-world.project") + assert len(p.services) == 5 + + s = p.services[0] + assert s.name == "greeter" + assert len(s.configs) == 0 + + s = p.services[1] + assert s.name == "web" + assert len(s.configs) == 0 + + s = p.services[2] + assert s.name == "db" + assert len(s.configs) == 0 + + s = p.services[3] + assert s.name == "adminer" + assert len(s.configs) == 0 + + s = p.services[4] + assert s.name == "another-web" + assert len(s.configs) == 1 + assert s.configs[0] == Path("html/index.html") +