From e74a58d0efd7088d842e2792cc95fbf55df286ef Mon Sep 17 00:00:00 2001 From: neverland Date: Mon, 3 Aug 2026 17:32:11 +0800 Subject: [PATCH] fix(fmt): report partial writes on errors --- packages/rstack/src/fmt/cli.ts | 15 ++++++++------- packages/rstack/tests/cli/fmt/index.test.ts | 13 +++++++++++++ 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/packages/rstack/src/fmt/cli.ts b/packages/rstack/src/fmt/cli.ts index 32a5ded..d16c6b6 100644 --- a/packages/rstack/src/fmt/cli.ts +++ b/packages/rstack/src/fmt/cli.ts @@ -122,10 +122,12 @@ const logFmtResult = ( matchedFileCount: number, durationSeconds: number, ): void => { + let writtenCount = 0; let differentCount = 0; for (const file of result.files) { if (file.status === 'written') { + writtenCount++; continue; } @@ -139,18 +141,17 @@ const logFmtResult = ( } if (mode === 'write') { - if (result.exitCode !== 0) { + if (writtenCount === 0 && result.exitCode !== 0) { return; } - const writtenCount = result.files.length; const matchedFiles = formatFileCount(matchedFileCount); const time = prettyTime(durationSeconds); - if (writtenCount > 0) { - logger.success(`Formatted ${formatCount(writtenCount)} of ${matchedFiles} in ${time}.`); - } else { - logger.success(`Checked ${matchedFiles} in ${time}. No changes needed.`); - } + const message = + writtenCount > 0 + ? `Formatted ${formatCount(writtenCount)} of ${matchedFiles} in ${time}.` + : `Checked ${matchedFiles} in ${time}. No changes needed.`; + logger[result.exitCode === 0 ? 'success' : 'info'](message); return; } diff --git a/packages/rstack/tests/cli/fmt/index.test.ts b/packages/rstack/tests/cli/fmt/index.test.ts index d7bd34a..f409693 100644 --- a/packages/rstack/tests/cli/fmt/index.test.ts +++ b/packages/rstack/tests/cli/fmt/index.test.ts @@ -370,6 +370,19 @@ test('returns exit code 2 for formatting errors', () => { expect(result.stderr).toContain('error index.ts: SyntaxError:'); }); +test('reports partial writes when formatting fails', () => { + writeProjectFile('valid.ts', 'const value=true'); + writeProjectFile('invalid.ts', 'const invalid = ;'); + + const result = runFmt(['valid.ts', 'invalid.ts']); + + expect(result.status).toBe(2); + expect(normalizeDuration(result.stdout)).toBe('info Formatted 1 of 2 files in .\n'); + expect(result.stderr).toContain('error invalid.ts: SyntaxError:'); + expect(readProjectFile('valid.ts')).toBe('const value = true;\n'); + expect(readProjectFile('invalid.ts')).toBe('const invalid = ;'); +}); + test('reports when no files match', () => { const writeResult = runFmt(['missing/**/*.ts']);