Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 16 additions & 4 deletions packages/reporters/cli/src/CLIReporter.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ const THROTTLE_DELAY = 100;
const seenWarnings = new Set();
const seenPhases = new Set();
const seenPhasesGen = new Set();
const phaseStartTimes = {};

let phaseStartTimes = {};
let pendingIncrementalBuild = false;

let statusThrottle = throttle((message: string) => {
updateSpinner(message);
Expand Down Expand Up @@ -76,6 +78,13 @@ export async function _report(
break;
}

if (pendingIncrementalBuild) {
pendingIncrementalBuild = false;
phaseStartTimes = {};
seenPhasesGen.clear();
seenPhases.clear();
}

if (!seenPhasesGen.has(event.phase)) {
phaseStartTimes[event.phase] = Date.now();
seenPhasesGen.add(event.phase);
Expand Down Expand Up @@ -127,9 +136,12 @@ export async function _report(
options.projectRoot,
options.detailedReport?.assetsPerBundle,
);
if (process.env.PARCEL_SHOW_PHASE_TIMES) {
phaseReport(phaseStartTimes);
}
} else {
pendingIncrementalBuild = true;
}

if (process.env.PARCEL_SHOW_PHASE_TIMES) {
phaseReport(phaseStartTimes);
}
break;
case 'buildFailure':
Expand Down
49 changes: 49 additions & 0 deletions packages/reporters/cli/test/CLIReporter.test.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
// @flow strict-local

import assert from 'assert';
import sinon from 'sinon';
import {PassThrough} from 'stream';
import {_report} from '../src/CLIReporter';
import {_setStdio} from '../src/render';
import {inputFS, outputFS} from '@parcel/test-utils';
import {NodePackageManager} from '@parcel/package-manager';
import stripAnsi from 'strip-ansi';
import * as bundleReport from '../src/bundleReport';
import * as render from '../src/render';

const EMPTY_OPTIONS = {
cacheDir: '.parcel-cache',
Expand Down Expand Up @@ -179,4 +182,50 @@ describe('CLIReporter', () => {
await _report({type: 'buildProgress', phase: 'bundling'}, EMPTY_OPTIONS);
assert.equal(stdoutOutput, 'Bundling...\n');
});

it('writes phase timings to stdout when PARCEL_SHOW_PHASE_TIMES is set', async () => {
let oldPhaseTimings = process.env['PARCEL_SHOW_PHASE_TIMES'];
const bundleReportStub = sinon.stub(bundleReport, 'default');
const persistSpinnerStub = sinon.stub(render, 'persistSpinner');

after(() => {
bundleReportStub.restore();
persistSpinnerStub.restore();
process.env['PARCEL_SHOW_PHASE_TIMES'] = oldPhaseTimings;
});

// emit a buildSuccess event to reset the timings and seen phases
// from the previous test
process.env['PARCEL_SHOW_PHASE_TIMES'] = undefined;
// $FlowFixMe[incompatible-call]
await _report({type: 'buildSuccess'}, EMPTY_OPTIONS);

process.env['PARCEL_SHOW_PHASE_TIMES'] = 'true';
await _report(
{type: 'buildProgress', phase: 'transforming', filePath: 'foo.js'},
EMPTY_OPTIONS,
);
await _report({type: 'buildProgress', phase: 'bundling'}, EMPTY_OPTIONS);
// $FlowFixMe[incompatible-call]
await _report({type: 'buildProgress', phase: 'packaging'}, EMPTY_OPTIONS);
// $FlowFixMe[incompatible-call]
await _report({type: 'buildSuccess'}, EMPTY_OPTIONS);
const expected =
/Building...\nBundling...\nPackaging & Optimizing...\nTransforming finished in [0-9]ms\nBundling finished in [0-9]ms\nPackaging & Optimizing finished in [0-9]ms/;

assert.equal(expected.test(stdoutOutput), true);

stdoutOutput = '';

await _report(
{type: 'buildProgress', phase: 'transforming', filePath: 'foo.js'},
EMPTY_OPTIONS,
);
await _report({type: 'buildProgress', phase: 'bundling'}, EMPTY_OPTIONS);
// $FlowFixMe[incompatible-call]
await _report({type: 'buildProgress', phase: 'packaging'}, EMPTY_OPTIONS);
// $FlowFixMe[incompatible-call]
await _report({type: 'buildSuccess'}, EMPTY_OPTIONS);
assert.equal(expected.test(stdoutOutput), true);
});
});