diff --git a/src/universal-app/prerender.ts b/src/universal-app/prerender.ts index cca64e72d97..faee2fe8764 100644 --- a/src/universal-app/prerender.ts +++ b/src/universal-app/prerender.ts @@ -5,6 +5,7 @@ import {enableProdMode} from '@angular/core'; import {renderModuleFactory} from '@angular/platform-server'; import {join} from 'path'; import {readFileSync} from 'fs-extra'; +import {log} from 'gulp-util'; import {KitchenSinkServerModuleNgFactory} from './kitchen-sink/kitchen-sink.ngfactory'; enableProdMode(); @@ -14,7 +15,7 @@ const result = renderModuleFactory(KitchenSinkServerModuleNgFactory, { }); result - .then(html => console.log(html)) + .then(() => log('Prerender done.')) // If rendering the module factory fails, exit the process with an error code because otherwise // the CI task will not recognize the failure and will show as "success". The error message // will be printed automatically by the `renderModuleFactory` method. diff --git a/tools/gulp/tasks/universal.ts b/tools/gulp/tasks/universal.ts index bb01f2e82d0..aa14142abcc 100644 --- a/tools/gulp/tasks/universal.ts +++ b/tools/gulp/tasks/universal.ts @@ -25,7 +25,10 @@ const prerenderOutFile = join(outDir, 'prerender.js'); task('universal:test-prerender', ['universal:build'], execTask( // Runs node with the tsconfig-paths module to alias the @angular/material dependency. 'node', ['-r', 'tsconfig-paths/register', prerenderOutFile], { - env: {TS_NODE_PROJECT: tsconfigPrerenderPath} + env: {TS_NODE_PROJECT: tsconfigPrerenderPath}, + // Errors in lifecycle hooks will write to STDERR, but won't exit the process with an + // error code, however we still want to catch those cases in the CI. + failOnStderr: true } )); diff --git a/tools/gulp/util/task_helpers.ts b/tools/gulp/util/task_helpers.ts index e923e2364ac..10407981de2 100644 --- a/tools/gulp/util/task_helpers.ts +++ b/tools/gulp/util/task_helpers.ts @@ -49,6 +49,8 @@ export interface ExecTaskOptions { errMessage?: string; // Environment variables being passed to the child process. env?: any; + // Whether the task should fail if the process writes to STDERR. + failOnStderr?: boolean; } /** Create a task that executes a binary as if from the command line. */ @@ -56,24 +58,23 @@ export function execTask(binPath: string, args: string[], options: ExecTaskOptio return (done: (err?: string) => void) => { const env = Object.assign({}, process.env, options.env); const childProcess = child_process.spawn(binPath, args, {env}); + const stderrData: string[] = []; if (!options.silentStdout && !options.silent) { childProcess.stdout.on('data', (data: string) => process.stdout.write(data)); } - if (!options.silent) { - childProcess.stderr.on('data', (data: string) => process.stderr.write(data)); + if (!options.silent || options.failOnStderr) { + childProcess.stderr.on('data', (data: string) => { + options.failOnStderr ? stderrData.push(data) : process.stderr.write(data); + }); } childProcess.on('close', (code: number) => { - if (code != 0) { - if (options.errMessage === undefined) { - done('Process failed with code ' + code); - } else { - done(options.errMessage); - } + if (options.failOnStderr && stderrData.length) { + done(stderrData.join('\n')); } else { - done(); + code != 0 ? done(options.errMessage || `Process failed with code ${code}`) : done(); } }); };