97-documentation/ns_report_publisher/distribution.py

from __future__ import annotations

import datetime as dt
from pathlib import Path
from typing import Any

from .platform_builder import build_platform, register_report
from .publisher import write_html_report
from .repository_provider import RepositoryDescriptor, resolve_repository


def _quality_check(descriptor: RepositoryDescriptor, result: dict[str, Any], runtime_root: Path, *, allow_unresolved_artifact_references: bool = False, require_platform: bool = True) -> dict[str, Any]:
    output_root = Path(result["outputRoot"])
    errors: list[str] = []
    index_path = output_root / "report-index.json"
    if not index_path.is_file():
        errors.append("report-index.json fehlt")
    pages = result.get("pages", [])
    if not pages:
        errors.append("Report enthält keine Seiten")
    for page in pages:
        if not (output_root / page).is_file():
            errors.append(f"Seite fehlt: {page}")
    unresolved = result.get("unresolvedArtifactReferences", [])
    if unresolved and not allow_unresolved_artifact_references:
        errors.extend(f"Ungelöste Referenz: {item}" for item in unresolved)
    reports_root = runtime_root.resolve() / "web" / "reports"
    if require_platform:
        if not (reports_root / "index.html").is_file():
            errors.append("Plattformnavigation fehlt")
        if not (reports_root / "platform-index.json").is_file():
            errors.append("platform-index.json fehlt")
    return {"ok": not errors, "errors": errors, "unresolvedArtifactReferences": unresolved,
            "checkedAt": dt.datetime.now().isoformat(timespec="seconds")}


def distribute_repository(repository_type: str, repository_root: Path, runtime_root: Path, target_runtime: str = "test", *, allow_unresolved_artifact_references: bool = False, rebuild_platform: bool = True) -> dict[str, Any]:
    descriptor = resolve_repository(repository_type, repository_root)
    result = write_html_report(
        descriptor.documentation_source,
        runtime_root=runtime_root,
        target_runtime=target_runtime,
        output_name=descriptor.output_path,
    )
    pages = result.get("pages", [])
    entry = {
        "repositoryId": descriptor.repository_id,
        "repositoryType": descriptor.repository_type,
        "displayName": descriptor.display_name,
        "reportRoot": descriptor.output_path,
        "entryPage": pages[0] if pages else "",
        "sourceRoot": str(descriptor.documentation_source),
        "generatedAt": result.get("generatedAt"),
    }
    register_report(runtime_root, entry)
    # A complete rebuild registers several reports.  Rebuilding the same
    # landing page after every registration repeats report-index reads and
    # dashboard discovery; callers can defer it until the final registration.
    platform = build_platform(runtime_root, target_runtime=target_runtime) if rebuild_platform else None
    quality = _quality_check(
        descriptor, result, runtime_root,
        allow_unresolved_artifact_references=allow_unresolved_artifact_references,
        require_platform=rebuild_platform,
    )
    if not quality["ok"]:
        raise RuntimeError("Documentation Quality Checks fehlgeschlagen: " + "; ".join(quality["errors"]))
    return {"descriptor": descriptor, "report": result, "platform": platform, "quality": quality}