from __future__ import annotations from pathlib import Path from typing import Dict, List, Optional import yaml class NavSpec: """Parsed representation of docforge.nav.yml.""" def __init__( self, home: Optional[str], groups: Dict[str, List[str]], ) -> None: self.home = home self.groups = groups @classmethod def load(cls, path: Path) -> "NavSpec": if not path.exists(): raise FileNotFoundError(path) data = yaml.safe_load(path.read_text(encoding="utf-8")) if not isinstance(data, dict): raise ValueError("Nav spec must be a mapping") home = data.get("home") groups = data.get("groups", {}) if home is not None and not isinstance(home, str): raise ValueError("home must be a string") if not isinstance(groups, dict): raise ValueError("groups must be a mapping") for key, value in groups.items(): if not isinstance(key, str): raise ValueError("group names must be strings") if not isinstance(value, list) or not all( isinstance(v, str) for v in value ): raise ValueError(f"group '{key}' must be a list of strings") return cls(home=home, groups=groups) def all_patterns(self) -> List[str]: patterns: List[str] = [] if self.home: patterns.append(self.home) for items in self.groups.values(): patterns.extend(items) return patterns