102 lines
2.6 KiB
Python
102 lines
2.6 KiB
Python
from collections.abc import Iterator
|
|
from dataclasses import dataclass
|
|
from pathlib import Path
|
|
from typing import Self, cast, final
|
|
|
|
from docker_compose.cfg.compose_paths import ServicePath, VolumePath
|
|
from docker_compose.cfg.org_yaml import OrgYaml
|
|
from docker_compose.util.Ts import TypeYamlCompatibleDict, TypeYamlCompatibleRes
|
|
from docker_compose.util.yaml_util import read_yaml, write_yaml
|
|
|
|
YAML_EXTS = frozenset((".yml", ".yaml"))
|
|
|
|
|
|
class ComposeFileTemplate(Path):
|
|
def write_dict(self, data: TypeYamlCompatibleDict) -> None:
|
|
write_yaml(data, self)
|
|
|
|
def write(self, data: str) -> None:
|
|
with self.open("wt") as f:
|
|
_ = f.write(data)
|
|
|
|
|
|
class OrgFile(Path):
|
|
@property
|
|
def as_dict(self) -> OrgYaml:
|
|
return cast(OrgYaml, cast(object, read_yaml(self)))
|
|
|
|
|
|
class YamlDir(Path):
|
|
@property
|
|
def yaml_files(self) -> Iterator[Path]:
|
|
if not self:
|
|
raise FileNotFoundError(self)
|
|
for service in self.iterdir():
|
|
if service.suffix not in YAML_EXTS:
|
|
continue
|
|
yield service
|
|
|
|
def __bool__(self) -> bool:
|
|
return self.exists()
|
|
|
|
|
|
class CfgDir(YamlDir):
|
|
@property
|
|
def cfg_file(self) -> OrgFile:
|
|
for file in self.yaml_files:
|
|
if file.stem != "cfg":
|
|
continue
|
|
return OrgFile(file)
|
|
raise FileNotFoundError(self.joinpath("cfg.y(a)ml"))
|
|
|
|
|
|
class ServiceDir(YamlDir):
|
|
@property
|
|
def files(self) -> Iterator[ServicePath]:
|
|
for file in self.yaml_files:
|
|
yield ServicePath(file)
|
|
|
|
|
|
class VolumesDir(YamlDir):
|
|
@property
|
|
def files(self) -> Iterator[VolumePath]:
|
|
try:
|
|
for file in self.yaml_files:
|
|
yield VolumePath(file)
|
|
except FileNotFoundError:
|
|
return
|
|
|
|
|
|
class VolumeData(Path):
|
|
def write(self, data: TypeYamlCompatibleRes) -> None:
|
|
write_yaml(data, self)
|
|
|
|
|
|
@final
|
|
@dataclass(frozen=True, slots=True)
|
|
class SrcPaths:
|
|
cfg_dir: CfgDir
|
|
org_file: OrgFile
|
|
env_file: Path
|
|
service_dir: ServiceDir
|
|
vol_dir: VolumesDir
|
|
compose_file: ComposeFileTemplate
|
|
volume_data: VolumeData
|
|
|
|
@classmethod
|
|
def from_path(cls, src: Path) -> Self:
|
|
cfg_dir = CfgDir(src)
|
|
return cls(
|
|
cfg_dir,
|
|
cfg_dir.cfg_file,
|
|
src.joinpath(".env"),
|
|
ServiceDir(src.joinpath("services")),
|
|
VolumesDir(src.joinpath("volumes")),
|
|
ComposeFileTemplate(src.joinpath("docker-compose.yml")),
|
|
VolumeData(src.joinpath("volume_paths.yml")),
|
|
)
|
|
|
|
@property
|
|
def app(self) -> str:
|
|
return self.cfg_dir.stem
|