Skip to content

Commit 2ca91c0

Browse files
committed
fix(utils): ensure multiline logs during spinner are indented properly
1 parent a180797 commit 2ca91c0

File tree

3 files changed

+67
-12
lines changed

3 files changed

+67
-12
lines changed

packages/utils/src/lib/formatting.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,3 +120,14 @@ export function truncateDescription(text: string): string {
120120
export function truncateIssueMessage(text: string): string {
121121
return truncateText(text, MAX_ISSUE_MESSAGE_LENGTH);
122122
}
123+
124+
export function transformLines(
125+
text: string,
126+
fn: (line: string) => string,
127+
): string {
128+
return text.split(/\r?\n/).map(fn).join('\n');
129+
}
130+
131+
export function indentLines(text: string, identation: number): string {
132+
return transformLines(text, line => `${' '.repeat(identation)}${line}`);
133+
}

packages/utils/src/lib/formatting.unit.test.ts

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
1+
import ansis from 'ansis';
12
import { describe, expect, it } from 'vitest';
23
import {
34
formatBytes,
45
formatDate,
56
formatDuration,
7+
indentLines,
68
pluralize,
79
pluralizeToken,
810
roundDecimals,
911
slugify,
12+
transformLines,
1013
truncateText,
1114
} from './formatting.js';
1215

@@ -181,3 +184,48 @@ describe('truncateText', () => {
181184
);
182185
});
183186
});
187+
188+
describe('transformLines', () => {
189+
it('should apply custom transformation to each line', () => {
190+
let count = 0;
191+
expect(
192+
transformLines(
193+
`export function greet(name = 'World') {\n console.log('Hello, ' + name + '!');\n}\n`,
194+
line => `${ansis.gray(`${++count} | `)}${line}`,
195+
),
196+
).toBe(
197+
`
198+
${ansis.gray('1 | ')}export function greet(name = 'World') {
199+
${ansis.gray('2 | ')} console.log('Hello, ' + name + '!');
200+
${ansis.gray('3 | ')}}
201+
${ansis.gray('4 | ')}`.trimStart(),
202+
);
203+
});
204+
205+
it('should support CRLF line endings', () => {
206+
expect(
207+
transformLines(
208+
'ESLint v9.16.0\r\n\r\nAll files pass linting.\r\n',
209+
line => `> ${line}`,
210+
),
211+
).toBe(
212+
`
213+
> ESLint v9.16.0
214+
>
215+
> All files pass linting.
216+
> `.trimStart(),
217+
);
218+
});
219+
});
220+
221+
describe('indentLines', () => {
222+
it('should indent each line by given number of spaces', () => {
223+
expect(indentLines('ESLint v9.16.0\n\nAll files pass linting.\n', 2)).toBe(
224+
`
225+
ESLint v9.16.0
226+
227+
All files pass linting.
228+
`.slice(1), // ignore first line break
229+
);
230+
});
231+
});

packages/utils/src/lib/logger.ts

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import os from 'node:os';
33
import ora, { type Ora } from 'ora';
44
import { dateToUnixTimestamp } from './dates.js';
55
import { isEnvVarEnabled } from './env.js';
6-
import { formatDuration } from './formatting.js';
6+
import { formatDuration, indentLines, transformLines } from './formatting.js';
77
import { settlePromise } from './promises.js';
88

99
type GroupColor = Extract<AnsiColors, 'cyan' | 'magenta'>;
@@ -261,7 +261,7 @@ export class Logger {
261261

262262
this.#activeSpinner = undefined;
263263
this.#activeSpinnerLogs.forEach(message => {
264-
this.#log(` ${message}`);
264+
this.#log(indentLines(message, 2));
265265
});
266266
this.#activeSpinnerLogs = [];
267267
process.removeListener('SIGINT', this.#sigintListener);
@@ -276,7 +276,7 @@ export class Logger {
276276
if (this.#activeSpinner.isSpinning) {
277277
this.#activeSpinnerLogs.push(this.#format(message, color));
278278
} else {
279-
console.log(this.#format(` ${message}`, color));
279+
console.log(this.#format(indentLines(message, 2), color));
280280
}
281281
} else {
282282
console.log(this.#format(message, color));
@@ -288,15 +288,11 @@ export class Logger {
288288
if (!this.#groupColor || this.#activeSpinner?.isSpinning) {
289289
return this.#colorize(message, color);
290290
}
291-
return message
292-
.split(/\r?\n/)
293-
.map(line =>
294-
[
295-
this.#colorize('│', this.#groupColor),
296-
this.#colorize(line, color),
297-
].join(' '),
298-
)
299-
.join('\n');
291+
return transformLines(
292+
message,
293+
line =>
294+
`${this.#colorize('│', this.#groupColor)} ${this.#colorize(line, color)}`,
295+
);
300296
}
301297

302298
#colorize(text: string, color: AnsiColors | undefined): string {

0 commit comments

Comments
 (0)