Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Print phase times on development builds #9417

Merged
merged 10 commits into from
Dec 7, 2023
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);
});
});