From 6926f7ac00d45780877e314927bbec8a58f0023c Mon Sep 17 00:00:00 2001 From: safishamsi Date: Tue, 11 Aug 2026 15:19:54 +0100 Subject: [PATCH] fix(export): make graph.html title marker-truncation take precedence (#2598 follow-up) The #2600 title helper preferred a cwd-relative label, which still leaks host/user path segments when the graph is built from a directory above the project. Keep from the graphify-out / GRAPHIFY_OUT marker onward first (portable in every case); fall back to cwd-relative only for a fully custom output path with no marker. Co-Authored-By: Claude Opus 4.8 (1M context) --- graphify/exporters/html.py | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/graphify/exporters/html.py b/graphify/exporters/html.py index 8d600c4f..372dd397 100644 --- a/graphify/exporters/html.py +++ b/graphify/exporters/html.py @@ -327,10 +327,10 @@ def _html_document_title(output_path: str) -> str: """Return a portable label for the graph.html . Tracked artifacts must not embed the generator host absolute path - (regression of #433; reported again as #2598 on Windows). Prefer a - path relative to the process cwd; otherwise keep from the configured - output-dir bare name (``graphify-out`` / ``GRAPHIFY_OUT`` basename) - onward; finally fall back to the filename only. + (regression of #433; reported again as #2598 on Windows). Keep from the + configured output-dir bare name (``graphify-out`` / ``GRAPHIFY_OUT`` + basename) onward — portable in every case; otherwise fall back to a + cwd-relative label, and finally the filename only. """ from graphify.paths import GRAPHIFY_OUT_NAME @@ -340,6 +340,20 @@ def _html_document_title(output_path: str) -> str: raw = raw[2:] # "/Users/..." style after drive strip p = Path(raw) + parts = list(Path(raw).parts) + # Path("C:/Users/..") on POSIX may keep "C:" as first part — strip it. + if parts and len(parts[0]) == 2 and parts[0][1] == ":" and parts[0][0].isalpha(): + parts = parts[1:] + # Prefer keeping from the output-dir marker onward: portable in every + # case, whereas a cwd-relative path still leaks host/user segments when + # the graph is built from a directory ABOVE the project (#2598 follow-up). + marker = GRAPHIFY_OUT_NAME + for i, part in enumerate(parts): + if part == marker or part.startswith("graphify-out"): + return "/".join(parts[i:]) + + # No standard out-dir marker (fully custom output path): fall back to a + # cwd-relative label when the target is under cwd, else the bare filename. try: resolved = p if p.is_absolute() else (Path.cwd() / p) rel = resolved.resolve().relative_to(Path.cwd().resolve()) @@ -349,14 +363,6 @@ def _html_document_title(output_path: str) -> str: except (ValueError, OSError, RuntimeError): pass - parts = list(Path(raw).parts) - # Path("C:/Users/..") on POSIX may keep "C:" as first part — strip it. - if parts and len(parts[0]) == 2 and parts[0][1] == ":" and parts[0][0].isalpha(): - parts = parts[1:] - marker = GRAPHIFY_OUT_NAME - for i, part in enumerate(parts): - if part == marker or part.startswith("graphify-out"): - return "/".join(parts[i:]) name = p.name return name if name else "graph.html"