Skip to content

Commit 116275c

Browse files
authored
Fix: stop all active spinners on reporter.close() (#4150)
**Summary** We were not stopping any activities in the reporter and were relying on `process.exit()` to kill them earlier. This patch fixes that and ensures all activities are stopped when the reporter is closed. **Test plan** Adds a new snapshots test that fails without the fix. Manual: just try to install a non-existent package and see `yarn` getting stuck due to an ongoing reporter activity. After the fix, it shuts down properly.
1 parent 22ff4f2 commit 116275c

File tree

3 files changed

+42
-1
lines changed

3 files changed

+42
-1
lines changed

__tests__/reporters/__snapshots__/console-reporter.js.snap

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,3 +145,10 @@ exports[`Spinner 2`] = `"⠁ ⠂ foo"`;
145145
exports[`Spinner 3`] = `"⠁ ⠂ foo⠄ bar"`;
146146
147147
exports[`Spinner 4`] = `"⠁ ⠂ foo⠄ bar"`;
148+
149+
exports[`close 1`] = `
150+
Object {
151+
"stderr": "░░ 0/2█░ 1/2⠁ ",
152+
"stdout": "",
153+
}
154+
`;

__tests__/reporters/console-reporter.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,3 +244,23 @@ test('Spinner', () => {
244244
spinner.stop();
245245
expect(data).toMatchSnapshot();
246246
});
247+
248+
test('close', async () => {
249+
jest.useFakeTimers();
250+
expect(
251+
await getConsoleBuff(r => {
252+
r.noProgress = false; // we need this to override is-ci when running tests on ci
253+
const tick = r.progress(2);
254+
tick();
255+
jest.runAllTimers();
256+
tick();
257+
258+
const activity = r.activity();
259+
activity.tick('foo');
260+
261+
r.close();
262+
// .close() should stop all timers and activities
263+
jest.runAllTimers();
264+
}),
265+
).toMatchSnapshot();
266+
});

src/reporters/console/console-reporter.js

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/* @flow */
22

33
import type {
4+
ReporterSetSpinner,
45
ReporterSpinnerSet,
56
Package,
67
Trees,
@@ -37,12 +38,14 @@ export default class ConsoleReporter extends BaseReporter {
3738
super(opts);
3839

3940
this._lastCategorySize = 0;
41+
this._spinners = new Set();
4042
this.format = (chalk: any);
4143
this.isSilent = !!opts.isSilent;
4244
}
4345

4446
_lastCategorySize: number;
4547
_progressBar: ?Progress;
48+
_spinners: Set<Spinner>;
4649

4750
_prependEmoji(msg: string, emoji: ?string): string {
4851
if (this.emoji && emoji && this.isTTY) {
@@ -65,6 +68,10 @@ export default class ConsoleReporter extends BaseReporter {
6568
}
6669

6770
close() {
71+
for (const spinner of this._spinners) {
72+
spinner.stop();
73+
}
74+
this._spinners.clear();
6875
this.stopProgress();
6976
super.close();
7077
}
@@ -245,14 +252,16 @@ export default class ConsoleReporter extends BaseReporter {
245252
return super.activitySet(total, workers);
246253
}
247254
248-
const spinners = [];
255+
const spinners: Array<ReporterSetSpinner> = [];
256+
const reporterSpinners = this._spinners;
249257
250258
for (let i = 1; i < workers; i++) {
251259
this.log('');
252260
}
253261
254262
for (let i = 0; i < workers; i++) {
255263
const spinner = new Spinner(this.stderr, i);
264+
reporterSpinners.add(spinner);
256265
spinner.start();
257266
258267
let prefix: ?string = null;
@@ -287,6 +296,7 @@ export default class ConsoleReporter extends BaseReporter {
287296
288297
end() {
289298
spinner.stop();
299+
reporterSpinners.delete(spinner);
290300
},
291301
});
292302
}
@@ -309,17 +319,21 @@ export default class ConsoleReporter extends BaseReporter {
309319
end() {},
310320
};
311321
}
322+
const reporterSpinners = this._spinners;
312323
313324
const spinner = new Spinner(this.stderr);
314325
spinner.start();
315326
327+
reporterSpinners.add(spinner);
328+
316329
return {
317330
tick(name: string) {
318331
spinner.setText(name);
319332
},
320333
321334
end() {
322335
spinner.stop();
336+
reporterSpinners.delete(spinner);
323337
},
324338
};
325339
}

0 commit comments

Comments
 (0)