from abc import ABCMeta from dataclasses import dataclass from pathlib import Path from typing import Self, final from docker_compose.compose.service_yaml_read import ( ServiceYamlRead, ) from docker_compose.compose.service_yaml_write import ( ServiceYamlWrite, ServiceYamlWriteData, ) from docker_compose.compose.val_obj import Record from docker_compose.Ts import T_Primitive @final @dataclass(frozen=True, slots=True) class Service(metaclass=ABCMeta): command: tuple[str, ...] | None container_name: str entrypoint: tuple[str, ...] | None environment: dict[str, T_Primitive] | None image: str labels: frozenset[str] | None logging: dict[str, str] | None networks: frozenset[str] | None restart: str security_opt: frozenset[str] user: str | None volumes: frozenset[str] | None @classmethod def from_path(cls, path: Path) -> Self: return cls.from_dict(ServiceYamlRead.from_path(path)) @classmethod def from_dict(cls, data: ServiceYamlRead): command = data.data.get("command") entrypoint = data.data.get("entrypoint") volumes = data.data.get("volumes") nets = data.data.get("networks") return cls( None if not command else tuple(command), Record.get_replace_name("org_name"), tuple(entrypoint) if entrypoint else None, data.data.get("environment"), data.data["image"], data.labels, data.data.get("logging"), frozenset(nets) if nets else None, "unless-stopped", data.sec_opts, data.data.get("user"), frozenset(volumes) if volumes else None, ) @property def as_dict(self) -> ServiceYamlWrite: data = ServiceYamlWriteData( container_name=self.container_name, image=self.image, restart=self.restart, security_opt=sorted(self.security_opt), ) if self.command is not None: data["command"] = list(self.command) if self.entrypoint is not None: data["entrypoint"] = list(self.entrypoint) if self.environment is not None: data["environment"] = self.environment if self.labels is not None: data["labels"] = sorted(self.labels) if self.logging is not None: data["logging"] = self.logging if self.user is not None: data["user"] = self.user if self.volumes is not None: data["volumes"] = sorted(self.volumes) return ServiceYamlWrite(data)