diff --git a/docs/assets/terminal-demo.gif b/docs/assets/terminal-demo.gif index fc752b0..be8ce11 100644 Binary files a/docs/assets/terminal-demo.gif and b/docs/assets/terminal-demo.gif differ diff --git a/scripts/integration.ts b/scripts/integration.ts index 9904949..ae3b9ca 100644 --- a/scripts/integration.ts +++ b/scripts/integration.ts @@ -19,6 +19,18 @@ function expectTimedSummary(output: string, context: string): void { if (!/\d+\.\d{2} ms/.test(output)) throw new Error(`${context}: missing two-decimal timing.`); } +function expectReportSpacing(output: string, context: string, hasIssues: boolean): void { + if (!output.startsWith('\n ') || output.startsWith('\n\n')) { + throw new Error(`${context}: expected exactly one leading blank line.`); + } + if (!output.endsWith('\n\n') || output.endsWith('\n\n\n')) { + throw new Error(`${context}: expected exactly one trailing blank line.`); + } + if (hasIssues && !output.includes(']\x1b[0m\n\n ')) { + throw new Error(`${context}: missing blank line between issues and summary.`); + } +} + try { const valid = run([], 'feat: add parser'); expectStatus(valid.status, 0, 'valid stdin'); @@ -29,6 +41,7 @@ try { throw new Error('Valid summary has incorrect counts.'); } expectTimedSummary(validOutput, 'valid summary'); + expectReportSpacing(validOutput, 'valid report', false); const invalid = run([], 'wat: some message'); expectStatus(invalid.status, 1, 'invalid stdin'); @@ -40,6 +53,7 @@ try { throw new Error('Error summary has incorrect singularization.'); } expectTimedSummary(invalidOutput, 'error summary'); + expectReportSpacing(invalidOutput, 'error report', true); const warning = run([], 'feat: add parser\nbody without blank'); expectStatus(warning.status, 0, 'warning-only stdin'); @@ -53,6 +67,7 @@ try { throw new Error('Warning summary has incorrect singularization.'); } expectTimedSummary(warningOutput, 'warning summary'); + expectReportSpacing(warningOutput, 'warning report', true); const messagePath = join(temp, 'COMMIT_EDITMSG'); writeFileSync(messagePath, 'fix(core): handle CRLF\r\n\r\nbody\r\n'); diff --git a/src/main.zig b/src/main.zig index 29d3750..7c2e98f 100644 --- a/src/main.zig +++ b/src/main.zig @@ -68,6 +68,7 @@ fn execute(init: std.process.Init, options: cli.Options) !void { var buffer: [4096]u8 = undefined; var writer = std.Io.File.stderr().writer(init.io, &buffer); + try writer.interface.writeByte('\n'); for (report.issues()) |issue| { const symbol = if (issue.severity == .err) "✖" else "⚠"; const symbol_color = if (issue.severity == .err) color.red else color.yellow; @@ -87,7 +88,7 @@ fn execute(init: std.process.Init, options: cli.Options) !void { const summary_color = if (report.errors > 0) color.red else if (report.warnings > 0) color.yellow else color.green; const error_suffix = if (report.errors == 1) "" else "s"; const warning_suffix = if (report.warnings == 1) "" else "s"; - try writer.interface.print(" {s}{s}{s} {s}{d} error{s}{s} · {s}{d} warning{s}{s} · {s}{d:.2} ms{s}\n", .{ + try writer.interface.print(" {s}{s}{s} {s}{d} error{s}{s} · {s}{d} warning{s}{s} · {s}{d:.2} ms{s}\n\n", .{ summary_color, summary_symbol, color.reset,