72 lines
1.7 KiB
Python
72 lines
1.7 KiB
Python
from __future__ import annotations
|
|
|
|
from pathlib import Path
|
|
from typing import Dict, Iterable, List
|
|
|
|
import glob
|
|
|
|
from docforge.nav.spec import NavSpec
|
|
|
|
|
|
class ResolvedNav:
|
|
def __init__(
|
|
self,
|
|
home: str | None,
|
|
groups: Dict[str, List[Path]],
|
|
docs_root: Path | None = None,
|
|
) -> None:
|
|
self.home = home
|
|
self.groups = groups
|
|
self._docs_root = docs_root
|
|
|
|
def all_files(self) -> Iterable[Path]:
|
|
if self.home:
|
|
if self._docs_root is None:
|
|
raise RuntimeError("docs_root is required to resolve home path")
|
|
yield self._docs_root / self.home
|
|
for paths in self.groups.values():
|
|
for p in paths:
|
|
yield p
|
|
|
|
|
|
def resolve_nav(
|
|
spec: NavSpec,
|
|
docs_root: Path,
|
|
) -> ResolvedNav:
|
|
if not docs_root.exists():
|
|
raise FileNotFoundError(docs_root)
|
|
|
|
def resolve_pattern(pattern: str) -> List[Path]:
|
|
full = docs_root / pattern
|
|
matches = sorted(
|
|
Path(p) for p in glob.glob(str(full), recursive=True)
|
|
)
|
|
|
|
if not matches:
|
|
raise FileNotFoundError(pattern)
|
|
|
|
return matches
|
|
|
|
# Resolve home
|
|
home: str | None = None
|
|
if spec.home:
|
|
home_path = docs_root / spec.home
|
|
if not home_path.exists():
|
|
raise FileNotFoundError(spec.home)
|
|
home = spec.home
|
|
|
|
# Resolve groups
|
|
resolved_groups: Dict[str, List[Path]] = {}
|
|
|
|
for group, patterns in spec.groups.items():
|
|
files: List[Path] = []
|
|
for pattern in patterns:
|
|
files.extend(resolve_pattern(pattern))
|
|
resolved_groups[group] = files
|
|
|
|
return ResolvedNav(
|
|
home=home,
|
|
groups=resolved_groups,
|
|
docs_root=docs_root,
|
|
)
|