render: colourise diff details + widen card, no mid-line wrap
When details is a unified diff (the network-configs notify feeds `git diff HEAD~1`), colour each line like a pager: additions green, deletions red, hunk headers violet, file/meta headers dim. Non-diff details (auto-log output) still render as a plain muted block. Also widen the card 600->760px and switch the details <pre> from pre-wrap/word-break to white-space:pre + overflow-x:auto so diff lines scroll instead of wrapping into mush. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
+69
-4
@@ -168,6 +168,71 @@ def fetch_failing_log(
|
||||
return "\n".join(cleaned[-log_lines:]).strip()
|
||||
|
||||
|
||||
# --- diff rendering -------------------------------------------------------
|
||||
# When `details` is a unified diff (the network-configs notify feeds
|
||||
# `git diff HEAD~1`), colour each line the way a terminal pager would:
|
||||
# additions green, deletions red, hunk headers violet, file/meta headers dim.
|
||||
# Non-diff details (e.g. auto-log output) fall through to a single muted block.
|
||||
DIFF_ADD = OK_FG
|
||||
DIFF_DEL = ERROR_FG
|
||||
DIFF_HUNK = ACCENT_VIOLET
|
||||
DIFF_META = MUTED
|
||||
DIFF_CONTEXT = MUTED_STRONG
|
||||
|
||||
_HUNK_RE = re.compile(r"^@@ -\d+(?:,\d+)? \+\d+(?:,\d+)? @@")
|
||||
# Lines that start with +/- but are file headers, not content changes.
|
||||
_META_PREFIXES = (
|
||||
"diff --git ",
|
||||
"index ",
|
||||
"--- ",
|
||||
"+++ ",
|
||||
"new file mode ",
|
||||
"deleted file mode ",
|
||||
"old mode ",
|
||||
"new mode ",
|
||||
"rename ",
|
||||
"similarity index ",
|
||||
"copy ",
|
||||
"Binary files ",
|
||||
)
|
||||
|
||||
|
||||
def _looks_like_diff(text: str) -> bool:
|
||||
"""True if `text` reads as a unified diff (has a git header or a hunk)."""
|
||||
for ln in text.splitlines():
|
||||
if ln.startswith("diff --git ") or _HUNK_RE.match(ln):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def _diff_line_color(line: str) -> str:
|
||||
if _HUNK_RE.match(line):
|
||||
return DIFF_HUNK
|
||||
if line.startswith(_META_PREFIXES):
|
||||
return DIFF_META
|
||||
if line.startswith("+"):
|
||||
return DIFF_ADD
|
||||
if line.startswith("-"):
|
||||
return DIFF_DEL
|
||||
return DIFF_CONTEXT
|
||||
|
||||
|
||||
def colorize_diff_html(details: str) -> str:
|
||||
"""Return inner HTML for the details <pre>: one coloured span per line."""
|
||||
spans = [
|
||||
f'<span style="color:{_diff_line_color(line)};">{escape(line)}</span>'
|
||||
for line in details.split("\n")
|
||||
]
|
||||
return "\n".join(spans)
|
||||
|
||||
|
||||
def details_inner_html(details: str) -> str:
|
||||
"""Colour-highlight diffs; otherwise escape as a plain muted block."""
|
||||
if _looks_like_diff(details):
|
||||
return colorize_diff_html(details)
|
||||
return escape(details)
|
||||
|
||||
|
||||
def fact_rows(items: Iterable[tuple[str, str, str]]) -> tuple[str, str]:
|
||||
"""Build the HTML <table> rows and plain-text lines for the fact list.
|
||||
|
||||
@@ -222,8 +287,8 @@ def render(
|
||||
<pre style="margin:0;padding:14px 16px;background:{CANVAS};
|
||||
border:1px solid {BORDER};border-radius:8px;
|
||||
color:{MUTED_STRONG};font-family:{FONT_MONO};
|
||||
font-size:12px;line-height:1.55;white-space:pre-wrap;
|
||||
word-break:break-word;overflow-x:auto;">{escape(details)}</pre>
|
||||
font-size:12px;line-height:1.55;white-space:pre;
|
||||
overflow-x:auto;">{details_inner_html(details)}</pre>
|
||||
</td></tr>
|
||||
"""
|
||||
|
||||
@@ -240,8 +305,8 @@ def render(
|
||||
<table role="presentation" width="100%" cellpadding="0" cellspacing="0"
|
||||
border="0" style="background:{CANVAS};padding:32px 16px;">
|
||||
<tr><td align="center">
|
||||
<table role="presentation" width="600" cellpadding="0" cellspacing="0"
|
||||
border="0" style="max-width:600px;width:100%;background:{SURFACE};
|
||||
<table role="presentation" width="760" cellpadding="0" cellspacing="0"
|
||||
border="0" style="max-width:760px;width:100%;background:{SURFACE};
|
||||
border:1px solid {BORDER};border-radius:12px;
|
||||
overflow:hidden;">
|
||||
<tr><td style="padding:28px 32px 8px 32px;">
|
||||
|
||||
Reference in New Issue
Block a user