from __future__ import annotations from pathlib import Path from typing import Any import yaml from reuse_surface.registry import ROOT DEFAULT_SOURCES_PATH = ROOT / "registry" / "federation" / "sources.yaml" def registration_to_source(registration: dict[str, Any]) -> dict[str, Any]: source: dict[str, Any] = { "repo": registration["repo"], "url": registration["url"], "enabled": registration.get("enabled", True), "required": registration.get("required", False), "domain": registration.get("domain", "helix_forge"), } for optional in ( "description", "cache_ttl_seconds", "auth_env", "auth_header", ): if registration.get(optional) is not None: source[optional] = registration[optional] return source def sources_from_hub_payload( payload: dict[str, Any], *, enabled_only: bool = True, ) -> list[dict[str, Any]]: repos = payload.get("repos", []) sources: list[dict[str, Any]] = [] for registration in repos: if enabled_only and not registration.get("enabled", True): continue if not registration.get("url"): continue sources.append(registration_to_source(registration)) return sorted(sources, key=lambda item: item["repo"]) def merge_sources( hub_sources: list[dict[str, Any]], existing_sources: list[dict[str, Any]], ) -> list[dict[str, Any]]: hub_repos = {source["repo"] for source in hub_sources} merged = list(hub_sources) for source in existing_sources: if source.get("repo") in hub_repos: continue if "index" in source: merged.append(source) return sorted(merged, key=lambda item: item["repo"]) def build_manifest( hub_payload: dict[str, Any], existing: dict[str, Any] | None = None, *, merge: bool = False, ) -> dict[str, Any]: hub_sources = sources_from_hub_payload(hub_payload) if merge and existing: sources = merge_sources(hub_sources, existing.get("sources", [])) else: sources = hub_sources return { "version": existing.get("version", 1) if existing else 1, "domain": existing.get("domain", "helix_forge") if existing else "helix_forge", "collision_policy": existing.get("collision_policy", "warn") if existing else "warn", "sources": sources, } def load_sources_manifest(path: Path) -> dict[str, Any]: if not path.exists(): return { "version": 1, "domain": "helix_forge", "collision_policy": "warn", "sources": [], } return yaml.safe_load(path.read_text(encoding="utf-8")) def write_sources_manifest(manifest: dict[str, Any], path: Path = DEFAULT_SOURCES_PATH) -> Path: path.parent.mkdir(parents=True, exist_ok=True) path.write_text( yaml.safe_dump(manifest, sort_keys=False, allow_unicode=True), encoding="utf-8", ) return path