mirror of
https://github.com/safishamsi/graphify.git
synced 2026-08-26 16:26:42 +00:00
fix(report): use a portable basename in the GRAPH_REPORT header (#2682)
This commit is contained in:
committed by
safishamsi
parent
5d8d6113db
commit
b3ca490408
+26
-1
@@ -2,9 +2,34 @@
|
||||
from __future__ import annotations
|
||||
import re
|
||||
from datetime import date
|
||||
from pathlib import Path
|
||||
import networkx as nx
|
||||
|
||||
|
||||
def _portable_root_label(root: str) -> str:
|
||||
"""Portable label for the report header — the project directory basename.
|
||||
|
||||
GRAPH_REPORT.md is a tracked artifact in practice, so its header must not
|
||||
bake the generator host's absolute path into the file: the same graph would
|
||||
otherwise produce different bytes on different machines and leak the build
|
||||
machine's directory layout into git history (#2628, same class as #2598).
|
||||
|
||||
Taking the basename strips any leading absolute path without touching the
|
||||
filesystem, and makes `graphify update .`, `graphify update ./proj`, and
|
||||
`graphify update /abs/path/proj` all label the header `proj`. Only the
|
||||
degenerate `.`/``/`..` cases need a cwd resolve to recover the real name;
|
||||
if even that fails, fall back to the raw value.
|
||||
"""
|
||||
raw = str(root).replace("\\", "/")
|
||||
name = Path(raw).name
|
||||
if name in ("", ".", ".."):
|
||||
try:
|
||||
name = Path(raw).resolve().name
|
||||
except (OSError, RuntimeError):
|
||||
name = ""
|
||||
return name or raw
|
||||
|
||||
|
||||
def _safe_community_name(label: str) -> str:
|
||||
"""Mirrors export.safe_name so community hub filenames and report wikilinks always agree."""
|
||||
cleaned = re.sub(r'[\\/*?:"<>|#^[\]]', "", label.replace("\r\n", " ").replace("\r", " ").replace("\n", " ")).strip()
|
||||
@@ -101,7 +126,7 @@ def generate(
|
||||
inf_avg = round(sum(inf_scores) / len(inf_scores), 2) if inf_scores else None
|
||||
|
||||
lines = [
|
||||
f"# Graph Report - {root} ({today})",
|
||||
f"# Graph Report - {_portable_root_label(root)} ({today})",
|
||||
"",
|
||||
"## Corpus Check",
|
||||
]
|
||||
|
||||
@@ -63,6 +63,30 @@ def test_report_shows_raw_cohesion_scores():
|
||||
assert "⚠" not in report
|
||||
|
||||
|
||||
def test_report_header_does_not_embed_host_absolute_path():
|
||||
"""#2628 / #2598: the header must not bake the generator host absolute path
|
||||
into GRAPH_REPORT.md — it labels with the project directory basename so the
|
||||
same graph produces the same bytes on any machine."""
|
||||
G, communities, cohesion, labels, gods, surprises, detection, tokens = make_inputs()
|
||||
report = generate(G, communities, cohesion, labels, gods, surprises, detection,
|
||||
tokens, "/Users/mike/dev/apps/secretproj")
|
||||
header = report.splitlines()[0]
|
||||
assert "/Users/mike" not in header
|
||||
assert "secretproj" in header
|
||||
|
||||
|
||||
def test_portable_root_label():
|
||||
from graphify.report import _portable_root_label
|
||||
# Absolute paths collapse to the basename on both POSIX and Windows.
|
||||
assert _portable_root_label("/Users/mike/dev/apps/proj") == "proj"
|
||||
assert _portable_root_label(r"C:\Users\mike\dev\proj") == "proj"
|
||||
# A trailing slash still yields the directory name, not an empty label.
|
||||
assert _portable_root_label("/Users/mike/dev/proj/") == "proj"
|
||||
# Relative names pass through unchanged.
|
||||
assert _portable_root_label("./project") == "project"
|
||||
assert _portable_root_label("project") == "project"
|
||||
|
||||
|
||||
# --- work-memory lessons section ----------------------------------------------
|
||||
|
||||
def test_report_work_memory_section_present_with_overlay_and_dead_ends():
|
||||
|
||||
Reference in New Issue
Block a user