generated from coulomb/repo-seed
57 lines
1.6 KiB
Python
57 lines
1.6 KiB
Python
from __future__ import annotations
|
|
|
|
from pathlib import Path
|
|
from typing import Any
|
|
|
|
import yaml
|
|
|
|
from .model import Declaration
|
|
|
|
DECLARATION_DIRS = ("services", "capabilities", "interfaces", "dependencies", "bindings")
|
|
|
|
|
|
def repo_root() -> Path:
|
|
return Path(__file__).resolve().parents[1]
|
|
|
|
|
|
def declaration_files(path: Path) -> list[Path]:
|
|
path = path.resolve()
|
|
if path.is_file():
|
|
return [path]
|
|
|
|
fabric = path if path.name == "fabric" else path / "fabric"
|
|
files: list[Path] = []
|
|
for directory in DECLARATION_DIRS:
|
|
root = fabric / directory
|
|
if root.is_dir():
|
|
files.extend(sorted(root.glob("*.yaml")))
|
|
files.extend(sorted(root.glob("*.yml")))
|
|
return files
|
|
|
|
|
|
def load_yaml(path: Path) -> Any:
|
|
return yaml.safe_load(path.read_text(encoding="utf-8"))
|
|
|
|
|
|
def load_declarations(paths: list[Path]) -> tuple[list[Declaration], list[tuple[Path, str]]]:
|
|
declarations: list[Declaration] = []
|
|
errors: list[tuple[Path, str]] = []
|
|
seen_files: set[Path] = set()
|
|
|
|
for raw in paths:
|
|
for path in declaration_files(raw):
|
|
if path in seen_files:
|
|
continue
|
|
seen_files.add(path)
|
|
try:
|
|
data = load_yaml(path)
|
|
except Exception as exc:
|
|
errors.append((path, str(exc)))
|
|
continue
|
|
if not isinstance(data, dict):
|
|
errors.append((path, "declaration must be a YAML mapping"))
|
|
continue
|
|
declarations.append(Declaration(path=path, data=data))
|
|
|
|
return declarations, errors
|