Add stat formatting with colorized diff indicators

This commit is contained in:
Chris Wanstrath 2026-02-23 21:28:23 -08:00
parent 33f820f124
commit be277b7623
2 changed files with 17 additions and 2 deletions

View File

@ -25,7 +25,7 @@ export async function action(branch: string) {
.replaceAll("{{BRANCH}}", escapeHtml(branch)) .replaceAll("{{BRANCH}}", escapeHtml(branch))
.replace("{{PROMPT_SECTION}}", () => session.prompt ? `<p class="prompt">${escapeHtml(session.prompt)}</p>` : "") .replace("{{PROMPT_SECTION}}", () => session.prompt ? `<p class="prompt">${escapeHtml(session.prompt)}</p>` : "")
.replace("{{LOG_SECTION}}", () => log ? `<div class="meta-section"><h3>Commits</h3><pre>${escapeHtml(log)}</pre></div>` : "") .replace("{{LOG_SECTION}}", () => log ? `<div class="meta-section"><h3>Commits</h3><pre>${escapeHtml(log)}</pre></div>` : "")
.replace("{{STAT_SECTION}}", () => stat ? `<div class="meta-section"><h3>Stats</h3><pre>${escapeHtml(stat)}</pre></div>` : "") .replace("{{STAT_SECTION}}", () => stat ? `<div class="meta-section"><h3>Stats</h3><pre>${formatStat(stat)}</pre></div>` : "")
.replace("{{DIFF_JSON}}", () => diffJson) .replace("{{DIFF_JSON}}", () => diffJson)
const tmpPath = `/tmp/sandlot-${branch}.html` const tmpPath = `/tmp/sandlot-${branch}.html`
@ -33,6 +33,21 @@ export async function action(branch: string) {
await $`open ${tmpPath}`.nothrow().quiet() await $`open ${tmpPath}`.nothrow().quiet()
} }
function formatStat(raw: string): string {
// strip leading space from lines to match the unindented first line
const trimmed = raw.split("\n").map(l => l.startsWith(" ") ? l.slice(1) : l).join("\n")
const escaped = escapeHtml(trimmed)
// colorize + and - in the bar portion (after the |)
return escaped.split("\n").map(line => {
const pipe = line.indexOf("|")
if (pipe === -1) return line
return line.slice(0, pipe + 1) +
line.slice(pipe + 1)
.replace(/\+/g, '<span style="color:#3fb950">+</span>')
.replace(/-/g, '<span style="color:#f85149">-</span>')
}).join("\n")
}
function escapeHtml(str: string): string { function escapeHtml(str: string): string {
return str return str
.replace(/&/g, "&amp;") .replace(/&/g, "&amp;")

View File

@ -198,7 +198,7 @@ export async function commitLog(range: string, cwd: string): Promise<string> {
/** Get a diff stat summary for a revision range. Returns empty string on failure. */ /** Get a diff stat summary for a revision range. Returns empty string on failure. */
export async function diffStat(range: string, cwd: string): Promise<string> { export async function diffStat(range: string, cwd: string): Promise<string> {
const result = await $`git diff --stat ${range}`.cwd(cwd).nothrow().quiet() const result = await $`git diff --stat --stat-width=68 ${range}`.cwd(cwd).nothrow().quiet()
if (result.exitCode !== 0) return "" if (result.exitCode !== 0) return ""
return result.text().trim() return result.text().trim()
} }