Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 20 additions & 2 deletions packages/cli/src/repowise/cli/state_persistence.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from __future__ import annotations

import logging
from pathlib import Path
from typing import Any

Expand All @@ -22,16 +23,33 @@ def build_kg_state(kg: Any) -> dict[str, Any]:
}


def save_knowledge_graph_json(repo_path: Path, kg: Any) -> None:
def save_knowledge_graph_json(repo_path: Path, kg: Any, *, portable: bool = False) -> None:
"""Write ``.repowise/knowledge-graph.json`` for a KG result.

No-op when the result can't serialize itself (``to_dict`` missing), so
callers only need to guard against a ``None`` knowledge graph.

When ``portable`` is set, write the self-contained, self-validated artifact
(curated layers + tour + entry points + summaries + a ``meta``/``validation``
block) instead of the bare ``to_dict`` output. Hard invariant violations are
logged but the artifact is still emitted, with the failures recorded under
``meta.validation`` so a consumer can see them ("repaired, not rejected").
"""
if not hasattr(kg, "to_dict"):
return
import json

if portable:
from repowise.core.analysis.kg_curation import build_portable_kg

data, validation = build_portable_kg(kg)
if not validation.ok:
logging.getLogger(__name__).warning(
"portable KG failed invariants: %s", "; ".join(validation.errors)
)
else:
data = kg.to_dict()

kg_json_path = repo_path / ".repowise" / "knowledge-graph.json"
kg_json_path.parent.mkdir(parents=True, exist_ok=True)
kg_json_path.write_text(json.dumps(kg.to_dict(), indent=2), encoding="utf-8")
kg_json_path.write_text(json.dumps(data, indent=2), encoding="utf-8")
Loading
Loading