packager: cleanup build status reporting

Reviewed By: cpojer

Differential Revision: D4521560

fbshipit-source-id: 8943e179192522da5145e4f14f0b648d3548cc36
This commit is contained in:
Jean Lauliac 2017-02-09 04:17:35 -08:00 committed by Facebook Github Bot
parent 78ae767123
commit 7b301aa3a4
3 changed files with 89 additions and 93 deletions

View File

@ -544,6 +544,35 @@ class Server {
return JSON.stringify(Object.assign({}, options, { onProgress: null })); return JSON.stringify(Object.assign({}, options, { onProgress: null }));
} }
/**
* Ensure we properly report the promise of a build that's happening,
* including failed builds. We use that separately for when we update a bundle
* and for when we build for scratch.
*/
_reportBundlePromise(
options: {entryFile: string},
bundlePromise: Promise<Bundle>,
): Promise<Bundle> {
this._reporter.update({
entryFilePath: options.entryFile,
type: 'bundle_build_started',
});
return bundlePromise.then(bundle => {
this._reporter.update({
entryFilePath: options.entryFile,
type: 'bundle_build_done',
});
return bundle;
}, error => {
this._reporter.update({
entryFilePath: options.entryFile,
error,
type: 'bundle_build_failed',
});
return Promise.reject(error);
});
}
_useCachedOrUpdateOrCreateBundle(options: { _useCachedOrUpdateOrCreateBundle(options: {
entryFile: string, entryFile: string,
platform?: string, platform?: string,
@ -567,11 +596,6 @@ class Server {
action_name: 'Updating existing bundle', action_name: 'Updating existing bundle',
outdated_modules: outdated.size, outdated_modules: outdated.size,
})); }));
this._reporter.update({
type: 'bundle_update_existing',
entryFilePath: options.entryFile,
outdatedModuleCount: outdated.size,
});
debug('Attempt to update existing bundle'); debug('Attempt to update existing bundle');
@ -644,7 +668,7 @@ class Server {
debug('Failed to update existing bundle, rebuilding...', e.stack || e.message); debug('Failed to update existing bundle, rebuilding...', e.stack || e.message);
return bundleFromScratch(); return bundleFromScratch();
}); });
return bundlePromise; return this._reportBundlePromise(options, bundlePromise);
} else { } else {
debug('Using cached bundle'); debug('Using cached bundle');
return bundle; return bundle;
@ -652,7 +676,7 @@ class Server {
}); });
} }
return bundleFromScratch(); return this._reportBundlePromise(options, bundleFromScratch());
} }
processRequest( processRequest(
@ -691,10 +715,6 @@ class Server {
} }
const options = this._getOptionsFromUrl(req.url); const options = this._getOptionsFromUrl(req.url);
this._reporter.update({
type: 'bundle_requested',
entryFilePath: options.entryFile,
});
const requestingBundleLogEntry = const requestingBundleLogEntry =
log(createActionStartEntry({ log(createActionStartEntry({
action_name: 'Requesting bundle', action_name: 'Requesting bundle',
@ -724,10 +744,6 @@ class Server {
const building = this._useCachedOrUpdateOrCreateBundle(options); const building = this._useCachedOrUpdateOrCreateBundle(options);
building.then( building.then(
p => { p => {
this._reporter.update({
type: 'bundle_built',
entryFilePath: options.entryFile,
});
if (requestType === 'bundle') { if (requestType === 'bundle') {
debug('Generating source code'); debug('Generating source code');
const bundleSource = p.getSource({ const bundleSource = p.getSource({

View File

@ -27,7 +27,6 @@ type BundleProgress = {
transformedFileCount: number, transformedFileCount: number,
totalFileCount: number, totalFileCount: number,
ratio: number, ratio: number,
outdatedModuleCount: number,
}; };
const DARK_BLOCK_CHAR = '\u2593'; const DARK_BLOCK_CHAR = '\u2593';
@ -48,6 +47,8 @@ export type TerminalReportableEvent = ReportableEvent | {
totalFileCount: number, totalFileCount: number,
}; };
type BuildPhase = 'in_progress' | 'done' | 'failed';
/** /**
* We try to print useful information to the terminal for interactive builds. * We try to print useful information to the terminal for interactive builds.
* This implements the `Reporter` interface from the './reporting' module. * This implements the `Reporter` interface from the './reporting' module.
@ -77,49 +78,26 @@ class TerminalReporter {
} }
/** /**
* Return a message looking like this: * Construct a message that represents the progress of a
* single bundle build, for example:
* *
* Transforming files |#### | 34.2% (324/945)... * Bunding `foo.js` |#### | 34.2% (324/945)
*
*/
_getFileTransformMessage(
{totalFileCount, transformedFileCount, ratio, outdatedModuleCount}: BundleProgress,
build: 'in_progress' | 'done',
): string {
if (outdatedModuleCount > 0) {
const plural = outdatedModuleCount > 1;
return `Updating ${outdatedModuleCount} ` +
`module${plural ? 's' : ''} in place` +
(build === 'done' ? ', done' : '...');
}
if (totalFileCount === 0) {
return build === 'done'
? 'No module changed.'
: 'Analysing...';
}
return util.format(
'Transforming modules %s%s% (%s/%s)%s',
build === 'done' ? '' : getProgressBar(ratio, 30) + ' ',
(100 * ratio).toFixed(1),
transformedFileCount,
totalFileCount,
build === 'done' ? ', done.' : '...',
);
}
/**
* Construct a message that represent the progress of a single bundle build.
*/ */
_getBundleStatusMessage( _getBundleStatusMessage(
entryFilePath: string, entryFilePath: string,
progress: BundleProgress, {totalFileCount, transformedFileCount, ratio}: BundleProgress,
build: 'in_progress' | 'done', phase: BuildPhase,
): string { ): string {
const localPath = path.relative('.', entryFilePath); const localPath = path.relative('.', entryFilePath);
return [ return util.format(
`Bundling \`${localPath}\``, 'Bundling `%s` %s%s% (%s/%s)%s',
' ' + this._getFileTransformMessage(progress, build), localPath,
].join('\n'); phase === 'in_progress' ? getProgressBar(ratio, 16) + ' ' : '',
(100 * ratio).toFixed(1),
transformedFileCount,
totalFileCount,
phase === 'done' ? ', done.' : (phase === 'failed' ? ', failed.' : ''),
);
} }
_logCacheDisabled(reason: GlobalCacheDisabledReason): void { _logCacheDisabled(reason: GlobalCacheDisabledReason): void {
@ -134,19 +112,38 @@ class TerminalReporter {
} }
} }
_logBundleBuildDone(entryFilePath: string) {
const progress = this._activeBundles.get(entryFilePath);
if (progress != null) {
const msg = this._getBundleStatusMessage(entryFilePath, {
...progress,
ratio: 1,
transformedFileCount: progress.totalFileCount,
}, 'done');
terminal.log(msg);
}
}
_logBundleBuildFailed(entryFilePath: string, error: Error) {
reporting.logError(terminal, 'bundling: %s', error.stack);
const progress = this._activeBundles.get(entryFilePath);
if (progress != null) {
const msg = this._getBundleStatusMessage(entryFilePath, progress, 'failed');
terminal.log(msg);
}
}
/** /**
* This function is only concerned with logging and should not do state * This function is only concerned with logging and should not do state
* or terminal status updates. * or terminal status updates.
*/ */
_log(event: TerminalReportableEvent): void { _log(event: TerminalReportableEvent): void {
switch (event.type) { switch (event.type) {
case 'bundle_built': case 'bundle_build_done':
const progress = this._activeBundles.get(event.entryFilePath); this._logBundleBuildDone(event.entryFilePath);
if (progress != null) { break;
terminal.log( case 'bundle_build_failed':
this._getBundleStatusMessage(event.entryFilePath, progress, 'done'), this._logBundleBuildFailed(event.entryFilePath, event.error);
);
}
break; break;
case 'dep_graph_loaded': case 'dep_graph_loaded':
terminal.log(`${DEP_GRAPH_MESSAGE}, done.`); terminal.log(`${DEP_GRAPH_MESSAGE}, done.`);
@ -187,35 +184,24 @@ class TerminalReporter {
ratio, ratio,
transformedFileCount, transformedFileCount,
totalFileCount, totalFileCount,
outdatedModuleCount: 0,
}); });
} }
_updateBundleOutdatedModuleCount(
{entryFilePath, outdatedModuleCount}: {
entryFilePath: string,
outdatedModuleCount: number,
},
) {
const currentProgress = this._activeBundles.get(entryFilePath);
if (currentProgress == null) {
return;
}
currentProgress.outdatedModuleCount = outdatedModuleCount;
}
/** /**
* This function is exclusively concerned with updating the internal state. * This function is exclusively concerned with updating the internal state.
* No logging or status updates should be done at this point. * No logging or status updates should be done at this point.
*/ */
_updateState(event: TerminalReportableEvent): void { _updateState(event: TerminalReportableEvent): void {
switch (event.type) { switch (event.type) {
case 'bundle_requested': case 'bundle_build_done':
case 'bundle_build_failed':
this._activeBundles.delete(event.entryFilePath);
break;
case 'bundle_build_started':
this._activeBundles.set(event.entryFilePath, { this._activeBundles.set(event.entryFilePath, {
transformedFileCount: 0, transformedFileCount: 0,
totalFileCount: 0, totalFileCount: 1,
ratio: 0, ratio: 0,
outdatedModuleCount: 0,
}); });
break; break;
case 'bundle_transform_progressed': case 'bundle_transform_progressed':
@ -229,12 +215,6 @@ class TerminalReporter {
case 'bundle_transform_progressed_throttled': case 'bundle_transform_progressed_throttled':
this._updateBundleProgress(event); this._updateBundleProgress(event);
break; break;
case 'bundle_update_existing':
this._updateBundleOutdatedModuleCount(event);
break;
case 'bundle_built':
this._activeBundles.delete(event.entryFilePath);
break;
case 'dep_graph_loading': case 'dep_graph_loading':
this._dependencyGraphHasLoaded = false; this._dependencyGraphHasLoaded = false;
break; break;

View File

@ -23,24 +23,24 @@ export type GlobalCacheDisabledReason = 'too_many_errors' | 'too_many_misses';
* report to the tool user. * report to the tool user.
*/ */
export type ReportableEvent = { export type ReportableEvent = {
entryFilePath: string,
type: 'bundle_build_done',
} | {
entryFilePath: string,
error: Error,
type: 'bundle_build_failed',
} | {
entryFilePath: string,
type: 'bundle_build_started',
} | {
type: 'dep_graph_loading', type: 'dep_graph_loading',
} | { } | {
type: 'dep_graph_loaded', type: 'dep_graph_loaded',
} | {
type: 'bundle_requested',
entryFilePath: string,
} | { } | {
type: 'bundle_transform_progressed', type: 'bundle_transform_progressed',
entryFilePath: string, entryFilePath: string,
transformedFileCount: number, transformedFileCount: number,
totalFileCount: number, totalFileCount: number,
} | {
entryFilePath: string,
outdatedModuleCount: number,
type: 'bundle_update_existing',
} | {
type: 'bundle_built',
entryFilePath: string,
} | { } | {
type: 'global_cache_error', type: 'global_cache_error',
error: Error, error: Error,