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