From a8c3b9d67c39a0b12f61a602bb876a36d219efed Mon Sep 17 00:00:00 2001 From: Igor Minar Date: Thu, 26 Nov 2015 23:45:40 -0800 Subject: [PATCH] build(gulp): lazy-require modules in order to improve startup time Closes #5498 --- gulpfile.js | 182 +++++++++++++++++++++++--------- tools/build/dartanalyzer.js | 201 ++++++++++++++++++------------------ tools/build/dartapidocs.js | 58 +++++------ 3 files changed, 258 insertions(+), 183 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index c6df38a43d..301e5543b0 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -1,51 +1,30 @@ 'use strict'; -var autoprefixer = require('gulp-autoprefixer'); -var clangFormat = require('clang-format'); var del = require('del'); -var exec = require('child_process').exec; -var fork = require('child_process').fork; var gulp = require('gulp'); -var gulpFormat = require('gulp-clang-format'); var gulpPlugins = require('gulp-load-plugins')(); -var sass = require('gulp-sass'); -var shell = require('gulp-shell'); -var spawn = require('child_process').spawn; -var runSequence = require('run-sequence'); -var madge = require('madge'); var merge = require('merge'); var merge2 = require('merge2'); +var minimist = require('minimist'); +var os = require('os'); var path = require('path'); -var q = require('q'); +var runSequence = require('run-sequence'); +var shell = require('gulp-shell'); + var licenseWrap = require('./tools/build/licensewrap'); var analytics = require('./tools/analytics/analytics'); - -var watch = require('./tools/build/watch'); - var pubget = require('./tools/build/pubget'); -var proto = require('./tools/build/proto'); var linknodemodules = require('./tools/build/linknodemodules'); var pubbuild = require('./tools/build/pubbuild'); -var dartanalyzer = require('./tools/build/dartanalyzer'); -var dartapidocs = require('./tools/build/dartapidocs'); var jsserve = require('./tools/build/jsserve'); var pubserve = require('./tools/build/pubserve'); -var karma = require('karma'); -var minimist = require('minimist'); var runServerDartTests = require('./tools/build/run_server_dart_tests'); -var sourcemaps = require('gulp-sourcemaps'); -var tsc = require('gulp-typescript'); var util = require('./tools/build/util'); -var bundler = require('./tools/build/bundle'); -var rename = require('gulp-rename'); -var replace = require('gulp-replace'); -var insert = require('gulp-insert'); var buildRouter = require('./modules/angular1_router/build'); -var uglify = require('gulp-uglify'); var shouldLog = require('./tools/build/logging'); var dartSdk = require('./tools/build/dart'); var browserProvidersConf = require('./browser-providers.conf.js'); -var os = require('os'); + require('./tools/check-environment')( {requiredNpmVersion: '>=2.14.7', requiredNodeVersion: '>=4.2.1'}); @@ -119,7 +98,9 @@ function sequenceComplete(done) { var treatTestErrorsAsFatal = true; function runJasmineTests(globs, done) { + var fork = require('child_process').fork; var args = ['--'].concat(globs); + fork('./tools/cjs-jasmine', args, {stdio: 'inherit'}) .on('close', function jasmineCloseHandler(exitCode) { if (exitCode && treatTestErrorsAsFatal) { @@ -220,6 +201,8 @@ gulp.task('build/pubspec.dart', // // See #2437 for more info. gulp.task('!build/remove-pub-symlinks', function(done) { + var exec = require('child_process').exec; + if (process.platform == 'win32') { done(); return; @@ -238,16 +221,29 @@ gulp.task('!build/remove-pub-symlinks', function(done) { // ------------ // dartanalyzer -gulp.task('build/analyze.dart', - dartanalyzer(gulp, gulpPlugins, {dest: CONFIG.dest.dart, command: DART_SDK.ANALYZER})); -gulp.task('build/analyze.ddc.dart', - dartanalyzer(gulp, gulpPlugins, - {dest: CONFIG.dest.dart, command: DART_SDK.ANALYZER, use_ddc: true})); +gulp.task('build/analyze.dart', () => { + var dartanalyzer = require('./tools/build/dartanalyzer'); + + return dartanalyzer(gulp, gulpPlugins, {dest: CONFIG.dest.dart, command: DART_SDK.ANALYZER}); +}); + + +gulp.task('build/analyze.ddc.dart', () => { + var dartanalyzer = require('./tools/build/dartanalyzer'); + + return dartanalyzer(gulp, gulpPlugins, + {dest: CONFIG.dest.dart, command: DART_SDK.ANALYZER, use_ddc: true}); +}); + + +gulp.task('build/check.apidocs.dart', () => { + var dartapidocs = require('./tools/build/dartapidocs'); + + return dartapidocs(gulp, gulpPlugins, + {dest: CONFIG.dest.dart, output: os.tmpdir(), command: DART_SDK.DARTDOCGEN}); +}); -gulp.task('build/check.apidocs.dart', - dartapidocs(gulp, gulpPlugins, - {dest: CONFIG.dest.dart, output: os.tmpdir(), command: DART_SDK.DARTDOCGEN})); // ------------ // pubbuild @@ -262,6 +258,9 @@ gulp.task( // formatting function doCheckFormat() { + var clangFormat = require('clang-format'); + var gulpFormat = require('gulp-clang-format'); + return gulp.src(['modules/**/*.ts', 'tools/**/*.ts', '!**/typings/**/*.d.ts', 'gulpfile.js']) .pipe(gulpFormat.checkFormat('file', clangFormat)); } @@ -305,6 +304,8 @@ gulp.task('lint', ['build.tools'], function() { // ------------ // check circular dependencies in Node.js context gulp.task('build/checkCircularDependencies', function(done) { + var madge = require('madge'); + var dependencyObject = madge(CONFIG.dest.js.dev.es5, { format: 'cjs', paths: [CONFIG.dest.js.dev.es5], @@ -345,6 +346,8 @@ function proxyServeDart() { // ------------------ // web servers gulp.task('serve.js.dev', ['build.js'], function(neverDone) { + var watch = require('./tools/build/watch'); + watch('modules/**', {ignoreInitial: true}, '!broccoli.js.dev'); jsServeDev(); }); @@ -353,12 +356,16 @@ gulp.task('serve.js.prod', jsServeProd); gulp.task('serve.e2e.dev', ['build.js.dev', 'build.js.cjs', 'build.css.material'], function(neverDone) { + var watch = require('./tools/build/watch'); + watch('modules/**', {ignoreInitial: true}, ['!broccoli.js.dev', '!build.js.cjs']); jsServeDev(); }); gulp.task('serve.e2e.prod', ['build.js.prod', 'build.js.cjs', 'build.css.material'], function(neverDone) { + var watch = require('./tools/build/watch'); + watch('modules/**', {ignoreInitial: true}, ['!broccoli.js.prod', '!build.js.cjs']); jsServeProd(); }); @@ -392,6 +399,8 @@ gulp.task( {command: DART_SDK.PUB, path: CONFIG.dest.dart + '/benchmarks_external', port: 8008})); gulp.task('serve.e2e.dart', ['build.js.cjs'], function(neverDone) { + var watch = require('./tools/build/watch'); + // Note: we are not using build.dart as the dart analyzer takes too long... watch('modules/**', {ignoreInitial: true}, ['!build/tree.dart', '!build.js.cjs']); runSequence('build/packages.dart', 'build/pubspec.dart', 'build.dart.material.css', 'serve.dart'); @@ -402,6 +411,8 @@ gulp.task('serve.e2e.dart', ['build.js.cjs'], function(neverDone) { // CI tests suites function runKarma(configFile, done) { + var exec = require('child_process').exec; + var cmd = process.platform === 'win32' ? 'node_modules\\.bin\\karma run ' : 'node node_modules/.bin/karma run '; cmd += configFile; @@ -473,14 +484,18 @@ function getBrowsersFromCLI(provider, isDart) { }; } -gulp.task('test.unit.js', ['build.js.dev'], function(done) { +gulp.task('test.unit.js', ['build.js.dev'], function(neverDone) { + var watch = require('./tools/build/watch'); + printModulesWarning(); runSequence('!test.unit.js/karma-server', function() { watch('modules/**', {ignoreInitial: true}, ['!broccoli.js.dev', '!test.unit.js/karma-run']); }); }); -gulp.task('watch.js.dev', ['build.js.dev'], function(done) { +gulp.task('watch.js.dev', ['build.js.dev'], function(neverDone) { + var watch = require('./tools/build/watch'); + printModulesWarning(); watch('modules/**', ['!broccoli.js.dev']); }); @@ -507,6 +522,8 @@ gulp.task('test.unit.js.browserstack', ['build.js.dev'], function(done) { }); function launchKarmaWithExternalBrowsers(reporters, browsers, done) { + var karma = require('karma'); + new karma.Server( { configFile: __dirname + '/karma-js.conf.js', @@ -524,6 +541,8 @@ function launchKarmaWithExternalBrowsers(reporters, browsers, done) { } gulp.task('!test.unit.js/karma-server', function(done) { + var karma = require('karma'); + var watchStarted = false; var server = new karma.Server({configFile: __dirname + '/karma-js.conf.js'}); server.on('run_complete', function() { @@ -542,19 +561,25 @@ gulp.task('!test.unit.js/karma-run', function(done) { runKarma('karma-js.conf.js', done); }); -gulp.task('test.unit.router', function(done) { +gulp.task('test.unit.router', function(neverDone) { + var watch = require('./tools/build/watch'); + runSequence('!test.unit.router/karma-server', function() { watch('modules/**', ['buildRouter.dev', '!test.unit.router/karma-run']); }); }); gulp.task('!test.unit.router/karma-server', function() { + var karma = require('karma'); + new karma.Server({configFile: __dirname + '/modules/angular1_router/karma-router.conf.js'}) .start(); }); gulp.task('!test.unit.router/karma-run', function(done) { + var karma = require('karma'); + karma.runner.run({configFile: __dirname + '/modules/angular1_router/karma-router.conf.js'}, function(exitCode) { // ignore exitCode, we don't want to fail the build in the interactive (non-ci) @@ -571,6 +596,8 @@ gulp.task('test.unit.dart', function(done) { runSequence('build/tree.dart', 'build/pure-packages.dart', '!build/pubget.angular2.dart', '!build/change_detect.dart', '!build/remove-pub-symlinks', 'build.dart.material.css', '!test.unit.dart/karma-server', '!test.unit.dart/karma-run', function(error) { + var watch = require('./tools/build/watch'); + // if initial build failed (likely due to build or formatting step) then exit // otherwise karma server doesn't start and we can't continue running properly if (error) { @@ -611,6 +638,8 @@ gulp.task('watch.dart.dev', function(done) { runSequence('build/tree.dart', 'build/pure-packages.dart', '!build/pubget.angular2.dart', '!build/change_detect.dart', '!build/remove-pub-symlinks', 'build.dart.material.css', function(error) { + var watch = require('./tools/build/watch'); + // if initial build failed (likely due to build or formatting step) then exit // otherwise karma server doesn't start and we can't continue running properly if (error) { @@ -630,11 +659,15 @@ gulp.task('!test.unit.dart/karma-run', function(done) { gulp.task('!test.unit.dart/karma-server', function() { + var karma = require('karma'); + new karma.Server({configFile: __dirname + '/karma-dart.conf.js', reporters: 'dots'}).start(); }); gulp.task('test.unit.router/ci', function(done) { + var karma = require('karma'); + var browserConf = getBrowsersFromCLI(); new karma.Server( { @@ -648,6 +681,8 @@ gulp.task('test.unit.router/ci', function(done) { }); gulp.task('test.unit.js/ci', function(done) { + var karma = require('karma'); + var browserConf = getBrowsersFromCLI(); new karma.Server( { @@ -670,6 +705,8 @@ gulp.task('test.unit.js.browserstack/ci', function(done) { }); gulp.task('test.unit.dart/ci', function(done) { + var karma = require('karma'); + var browserConf = getBrowsersFromCLI(null, true); new karma.Server( { @@ -689,6 +726,8 @@ gulp.task('test.unit.cjs/ci', function(done) { gulp.task('test.unit.cjs', ['build/clean.js', 'build.tools'], function(neverDone) { + var watch = require('./tools/build/watch'); + printModulesWarning(); treatTestErrorsAsFatal = false; watch('modules/**', ['!build.js.cjs', 'test.unit.cjs/ci']); @@ -696,7 +735,9 @@ gulp.task('test.unit.cjs', ['build/clean.js', 'build.tools'], function(neverDone // Use this target to continuously run dartvm unit-tests (such as transformer // tests) while coding. Note: these tests do not use Karma. -gulp.task('test.unit.dartvm', function(done) { +gulp.task('test.unit.dartvm', function(neverDone) { + var watch = require('./tools/build/watch'); + runSequence( 'build/tree.dart', 'build/pure-packages.dart', '!build/pubget.angular2.dart', '!build/change_detect.dart', '!test.unit.dartvm/run', function(error) { @@ -723,13 +764,11 @@ gulp.task('test.unit.tools/ci', function(done) { }); -gulp.task('test.unit.tools', ['build/clean.tools'], function(done) { - +gulp.task('test.unit.tools', ['build/clean.tools'], function(neverDone) { + var watch = require('./tools/build/watch'); treatTestErrorsAsFatal = false; - var buildAndTest = ['!build.tools', 'test.unit.tools/ci']; - - watch(['tools/**', '!tools/**/test-fixtures/**'], buildAndTest); + watch(['tools/**', '!tools/**/test-fixtures/**'], ['!build.tools', 'test.unit.tools/ci']); }); @@ -781,6 +820,8 @@ gulp.task('!pre.test.typings.copyTypingsSpec', function() { }); gulp.task('test.typings', ['!pre.test.typings.layoutNodeModule', '!pre.test.typings.copyTypingsSpec'], function() { + var tsc = require('gulp-typescript'); + return gulp.src([tmpdir + '/**']) .pipe(tsc({ target: 'ES5', @@ -801,9 +842,7 @@ gulp.task('test.typings', // // This task is expected to be run after build/tree.dart gulp.task('build/pure-packages.dart', function() { - var through2 = require('through2'); var yaml = require('js-yaml'); - var originalPrefix = '../../dist/dart/'; return gulp.src([ 'modules_dart/transform/**/*', @@ -835,6 +874,9 @@ gulp.task('build.tools', ['build/clean.tools'], // private task to build tools gulp.task('!build.tools', function() { + var sourcemaps = require('gulp-sourcemaps'); + var tsc = require('gulp-typescript'); + var stream = gulp.src(['tools/**/*.ts']) .pipe(sourcemaps.init()) .pipe(tsc({ @@ -925,12 +967,13 @@ var bundleConfig = { // production build gulp.task('!bundle.js.prod', ['build.js.prod'], function() { + var bundler = require('./tools/build/bundle'); var bundlerConfig = {sourceMaps: true}; return bundler.bundle(bundleConfig, 'angular2/angular2', './dist/build/angular2.js', bundlerConfig) .then(function() { - return q.all([ + return Promise.all([ bundler.bundle(bundleConfig, 'angular2/http - angular2/angular2', './dist/build/http.js', bundlerConfig), bundler.bundle(bundleConfig, 'angular2/router - angular2/angular2', @@ -941,12 +984,13 @@ gulp.task('!bundle.js.prod', ['build.js.prod'], function() { // minified production build gulp.task('!bundle.js.min', ['build.js.prod'], function() { + var bundler = require('./tools/build/bundle'); var bundlerConfig = {sourceMaps: true, minify: true}; return bundler.bundle(bundleConfig, 'angular2/angular2', './dist/build/angular2.min.js', bundlerConfig) .then(function() { - return q.all([ + return Promise.all([ bundler.bundle(bundleConfig, 'angular2/http - angular2/angular2', './dist/build/http.min.js', bundlerConfig), bundler.bundle(bundleConfig, 'angular2/router - angular2/angular2', @@ -957,6 +1001,7 @@ gulp.task('!bundle.js.min', ['build.js.prod'], function() { // development build gulp.task('!bundle.js.dev', ['build.js.dev'], function() { + var bundler = require('./tools/build/bundle'); var bundlerConfig = {sourceMaps: true}; var devBundleConfig = merge(true, bundleConfig); @@ -965,7 +1010,7 @@ gulp.task('!bundle.js.dev', ['build.js.dev'], function() { return bundler.bundle(devBundleConfig, 'angular2/angular2', './dist/build/angular2.dev.js', bundlerConfig) .then(function() { - return q.all([ + return Promise.all([ bundler.bundle(devBundleConfig, 'angular2/http - angular2/angular2', './dist/build/http.dev.js', bundlerConfig), bundler.bundle(bundleConfig, 'angular2/router - angular2/angular2', @@ -976,8 +1021,11 @@ gulp.task('!bundle.js.dev', ['build.js.dev'], function() { // WebWorker build gulp.task("!bundle.web_worker.js.dev", ["build.js.dev"], function() { + var bundler = require('./tools/build/bundle'); var devBundleConfig = merge(true, bundleConfig); + devBundleConfig.paths = merge(true, devBundleConfig.paths, {"*": "dist/js/dev/es5/*.js"}); + return bundler.bundle(devBundleConfig, 'angular2/web_worker/ui', './dist/build/web_worker/ui.dev.js', {sourceMaps: true}) .then(function() { @@ -987,8 +1035,11 @@ gulp.task("!bundle.web_worker.js.dev", ["build.js.dev"], function() { }); gulp.task('!bundle.testing', ['build.js.dev'], function() { + var bundler = require('./tools/build/bundle'); + var devBundleConfig = merge(true, bundleConfig); devBundleConfig.paths = merge(true, devBundleConfig.paths, {"*": "dist/js/dev/es5/*.js"}); + return bundler.bundle(devBundleConfig, 'angular2/testing - angular2/angular2', './dist/js/bundle/testing.js', {sourceMaps: true}); }); @@ -999,14 +1050,18 @@ gulp.task('!bundle.testing', ['build.js.dev'], function() { // use System loader polyfills (like system.js and es6 loader). // see: https://github.com/systemjs/builder (SFX bundles). gulp.task('!bundle.js.sfx.dev', ['build.js.dev'], function() { + var bundler = require('./tools/build/bundle'); + var devBundleConfig = merge(true, bundleConfig); devBundleConfig.paths = merge(true, devBundleConfig.paths, {'*': 'dist/js/dev/es5/*.js'}); + return bundler.bundle(devBundleConfig, 'angular2/angular2_sfx', './dist/build/angular2.sfx.dev.js', {sourceMaps: true}, /* self-executing */ true); }); gulp.task('!bundles.js.umd', ['build.js.dev'], function() { + var q = require('q'); var webpack = q.denodeify(require('webpack')); function resolveOptions(devOrProd) { @@ -1046,6 +1101,9 @@ gulp.task('!bundles.js.umd', ['build.js.dev'], function() { }); gulp.task('bundles.js.umd.min', ['!bundles.js.umd', '!bundle.external.deps'], function() { + var rename = require('gulp-rename'); + var uglify = require('gulp-uglify'); + // minify production bundles return gulp.src([ 'dist/js/bundle/external-dependencies.js', @@ -1058,6 +1116,8 @@ gulp.task('bundles.js.umd.min', ['!bundles.js.umd', '!bundle.external.deps'], fu }); gulp.task('!bundle.js.prod.deps', ['!bundle.js.prod'], function() { + var bundler = require('./tools/build/bundle'); + return merge2(addDevDependencies('angular2.js'), bundler.modify(['dist/build/http.js'], 'http.js'), bundler.modify(['dist/build/router.js'], 'router.js')) @@ -1065,6 +1125,9 @@ gulp.task('!bundle.js.prod.deps', ['!bundle.js.prod'], function() { }); gulp.task('!bundle.js.min.deps', ['!bundle.js.min'], function() { + var bundler = require('./tools/build/bundle'); + var uglify = require('gulp-uglify'); + return merge2(addDevDependencies('angular2.min.js'), bundler.modify(['dist/build/http.min.js'], 'http.min.js'), bundler.modify(['dist/build/router.min.js'], 'router.min.js')) @@ -1095,12 +1158,17 @@ function insertRXLicense(source) { } function addDevDependencies(outputFile) { + var bundler = require('./tools/build/bundle'); + var insert = require('gulp-insert'); + return bundler.modify(JS_DEV_DEPS.concat(['dist/build/' + outputFile]), outputFile) .pipe(insert.transform(insertRXLicense)) .pipe(gulp.dest('dist/js/bundle')); } gulp.task('!bundle.js.dev.deps', ['!bundle.js.dev'], function() { + var bundler = require('./tools/build/bundle'); + return merge2(addDevDependencies('angular2.dev.js'), bundler.modify(['dist/build/http.dev.js'], 'http.dev.js'), bundler.modify(['dist/build/router.dev.js'], 'router.dev.js')) @@ -1108,6 +1176,8 @@ gulp.task('!bundle.js.dev.deps', ['!bundle.js.dev'], function() { }); gulp.task('!bundle.js.sfx.dev.deps', ['!bundle.js.sfx.dev'], function() { + var bundler = require('./tools/build/bundle'); + return bundler.modify(JS_DEV_DEPS.concat(['dist/build/angular2.sfx.dev.js']), 'angular2.sfx.dev.js') .pipe(gulp.dest('dist/js/bundle')); @@ -1157,10 +1227,14 @@ gulp.task('build', ['build.js', 'build.dart']); // ------------ // transform codegen gulp.task('lint_protos.dart', function(done) { + var proto = require('./tools/build/proto'); + return proto.lint({dir: 'modules_dart/transform/lib/src/transform/common/model/'}, done); }); gulp.task('gen_protos.dart', function(done) { + var proto = require('./tools/build/proto'); + return proto.generate( { dir: 'modules_dart/transform/lib/src/transform/common/model/', @@ -1177,6 +1251,8 @@ gulp.task('build.change_detect.dart', function(done) { gulp.task('!build/change_detect.dart', function(done) { var fs = require('fs'); + var spawn = require('child_process').spawn; + var changeDetectDir = path.join(CONFIG.dest.dart, 'angular2/test/core/change_detection/'); var srcDir = path.join(changeDetectDir, 'generator'); var destDir = path.join(changeDetectDir, 'generated'); @@ -1198,6 +1274,9 @@ gulp.task('!build/change_detect.dart', function(done) { // ------------ // angular material testing rules gulp.task('build.css.material', function() { + var autoprefixer = require('gulp-autoprefixer'); + var sass = require('gulp-sass'); + return gulp.src('modules/*/src/**/*.scss') .pipe(sass()) .pipe(autoprefixer()) @@ -1216,6 +1295,9 @@ gulp.task('build.dart2js.material', function(done) { }); gulp.task('build.dart.material.css', function() { + var autoprefixer = require('gulp-autoprefixer'); + var sass = require('gulp-sass'); + return gulp.src('dist/dart/angular2_material/src/**/*.scss') .pipe(sass()) .pipe(autoprefixer()) @@ -1229,6 +1311,8 @@ gulp.task('build.dart.material', ['build/packages.dart'], function(done) { gulp.task('cleanup.builder', function() { return angularBuilder.cleanup(); }); gulp.task('benchpress.bundle', ['build/clean.benchpress.bundle', 'build.js.cjs'], function(cb) { + var bundler = require('./tools/build/bundle'); + bundler.benchpressBundle(BENCHPRESS_BUNDLE_CONFIG.entries, BENCHPRESS_BUNDLE_CONFIG.packageJson, BENCHPRESS_BUNDLE_CONFIG.includes, BENCHPRESS_BUNDLE_CONFIG.excludes, BENCHPRESS_BUNDLE_CONFIG.ignore, BENCHPRESS_BUNDLE_CONFIG.dest, cb); diff --git a/tools/build/dartanalyzer.js b/tools/build/dartanalyzer.js index 9384330d84..b2e7746cdd 100644 --- a/tools/build/dartanalyzer.js +++ b/tools/build/dartanalyzer.js @@ -9,114 +9,111 @@ var util = require('./util'); var yaml = require('js-yaml'); module.exports = function(gulp, plugins, config) { - return function() { - var travisFoldEnd = travisFoldStart(`dartanalyzer-${config.use_ddc ? 'ddc' : ''}-${config.dest}`); - var tempFile = '_analyzer.dart'; + var travisFoldEnd = travisFoldStart(`dartanalyzer-${config.use_ddc ? 'ddc' : ''}-${config.dest}`); + var tempFile = '_analyzer.dart'; - return util.forEachSubDirSequential(config.dest, function(dir) { - var pubspecContents = fs.readFileSync(path.join(dir, 'pubspec.yaml')); - var pubspec = yaml.safeLoad(pubspecContents); - var packageName = pubspec.name; + return util.forEachSubDirSequential(config.dest, function(dir) { + var pubspecContents = fs.readFileSync(path.join(dir, 'pubspec.yaml')); + var pubspec = yaml.safeLoad(pubspecContents); + var packageName = pubspec.name; - var libFiles = [].slice.call(glob.sync('lib/**/*.dart', {cwd: dir})); - var webFiles = [].slice.call(glob.sync('web/**/*.dart', {cwd: dir})); - var testFiles = [].slice.call(glob.sync('test/**/*_spec.dart', {cwd: dir})); + var libFiles = [].slice.call(glob.sync('lib/**/*.dart', {cwd: dir})); + var webFiles = [].slice.call(glob.sync('web/**/*.dart', {cwd: dir})); + var testFiles = [].slice.call(glob.sync('test/**/*_spec.dart', {cwd: dir})); - var analyzeFile = ['library _analyzer;']; - libFiles.concat(testFiles).concat(webFiles).forEach(function(fileName, index) { - if (fileName !== tempFile && fileName.indexOf("/packages/") === -1) { - if (fileName.indexOf('lib') == 0) { - fileName = 'package:' + packageName + '/' + path.relative('lib', fileName).replace(/\\/g, '/'); - } - analyzeFile.push('import "' + fileName + '" as mod' + index + ';'); - } - }); - fs.writeFileSync(path.join(dir, tempFile), analyzeFile.join('\n')); - var defer = Q.defer(); - if (config.use_ddc) { - analyze(dir, defer.makeNodeResolver(), true); - } else { - analyze(dir, defer.makeNodeResolver()); - } - return defer.promise; - }).then(travisFoldEnd); + var analyzeFile = ['library _analyzer;']; + libFiles.concat(testFiles).concat(webFiles).forEach(function(fileName, index) { + if (fileName !== tempFile && fileName.indexOf("/packages/") === -1) { + if (fileName.indexOf('lib') == 0) { + fileName = 'package:' + packageName + '/' + + path.relative('lib', fileName).replace(/\\/g, '/'); + } + analyzeFile.push('import "' + fileName + '" as mod' + index + ';'); + } + }); + fs.writeFileSync(path.join(dir, tempFile), analyzeFile.join('\n')); + var defer = Q.defer(); + if (config.use_ddc) { + analyze(dir, defer.makeNodeResolver(), true); + } else { + analyze(dir, defer.makeNodeResolver()); + } + return defer.promise; + }).then(travisFoldEnd); - function analyze(dirName, done, useDdc) { - // TODO remove --package-warnings once dartanalyzer handles transitive libraries - var flags = ['--fatal-warnings', '--package-warnings', '--format=machine']; + function analyze(dirName, done, useDdc) { + // TODO remove --package-warnings once dartanalyzer handles transitive libraries + var flags = ['--fatal-warnings', '--package-warnings', '--format=machine']; - if (useDdc) { - console.log('Using DDC analyzer to analyze', dirName); - flags.push('--strong'); - } - - var args = flags.concat(tempFile); - - var stream = spawn(config.command, args, { - // inherit stdin and stderr, but filter stdout - stdio: [process.stdin, process.stdout, 'pipe'], - cwd: dirName - }); - // Filter out unused imports from our generated file. - // We don't reexports from the generated file - // as this could lead to name clashes when two files - // export the same thing. - var rl = readline.createInterface( - {input: stream.stderr, output: process.stdout, terminal: false}); - var hintCount = 0; - var errorCount = 0; - var warningCount = 0; - rl.on('line', function(line) { - if (line == "find: > bin [: No such file or directory") { - //Skip bad output from Dart SDK .bat files on Windows - return; - } - var parsedLine = _AnalyzerOutputLine.parse(line); - if (!parsedLine) { - errorCount++; - console.log('Unexpected output: ' + line); - return; - } - // TODO remove once dartanalyzer handles transitive libraries - // skip errors in third-party packages - if (parsedLine.sourcePath.indexOf(dirName) == -1) { - return; - } - if (parsedLine.shouldIgnore()) { - return; - } - - if (parsedLine.isHint) { - hintCount++; - } else if (parsedLine.isWarning) { - warningCount++; - } else { - errorCount++; - } - console.log(dirName + ':' + parsedLine); - }); - stream.on('close', function() { - var error; - var report = []; - if (errorCount > 0) { - report.push(errorCount + ' error(s)'); - } - if (warningCount > 0) { - report.push(warningCount + ' warning(s)'); - } - if (hintCount > 0) { - report.push(hintCount + ' hint(s)'); - } - if (report.length > 0) { - error = 'Dartanalyzer showed ' + report.join(', '); - } - done(error); - }); - stream.on('error', function(error) { - done(error); - }); + if (useDdc) { + console.log('Using DDC analyzer to analyze', dirName); + flags.push('--strong'); } - }; + + var args = flags.concat(tempFile); + + var stream = spawn(config.command, args, { + // inherit stdin and stderr, but filter stdout + stdio: [process.stdin, process.stdout, 'pipe'], + cwd: dirName + }); + // Filter out unused imports from our generated file. + // We don't reexports from the generated file + // as this could lead to name clashes when two files + // export the same thing. + var rl = + readline.createInterface({input: stream.stderr, output: process.stdout, terminal: false}); + var hintCount = 0; + var errorCount = 0; + var warningCount = 0; + rl.on('line', function(line) { + if (line == "find: > bin [: No such file or directory") { + // Skip bad output from Dart SDK .bat files on Windows + return; + } + var parsedLine = _AnalyzerOutputLine.parse(line); + if (!parsedLine) { + errorCount++; + console.log('Unexpected output: ' + line); + return; + } + // TODO remove once dartanalyzer handles transitive libraries + // skip errors in third-party packages + if (parsedLine.sourcePath.indexOf(dirName) == -1) { + return; + } + if (parsedLine.shouldIgnore()) { + return; + } + + if (parsedLine.isHint) { + hintCount++; + } else if (parsedLine.isWarning) { + warningCount++; + } else { + errorCount++; + } + console.log(dirName + ':' + parsedLine); + }); + stream.on('close', function() { + var error; + var report = []; + if (errorCount > 0) { + report.push(errorCount + ' error(s)'); + } + if (warningCount > 0) { + report.push(warningCount + ' warning(s)'); + } + if (hintCount > 0) { + report.push(hintCount + ' hint(s)'); + } + if (report.length > 0) { + error = 'Dartanalyzer showed ' + report.join(', '); + } + done(error); + }); + stream.on('error', function(error) { done(error); }); + } }; // See https://github.com/dart-lang/analyzer_cli/blob/master/lib/src/error_formatter.dart diff --git a/tools/build/dartapidocs.js b/tools/build/dartapidocs.js index 29961c8fda..247dc81d7a 100644 --- a/tools/build/dartapidocs.js +++ b/tools/build/dartapidocs.js @@ -5,41 +5,35 @@ var util = require('./util'); module.exports = function(gulp, plugins, config) { config.output = config.output || 'doc/api'; - return function() { - return util.forEachSubDirSequential(config.dest, function(dir) { - var defer = Q.defer(); - var done = defer.makeNodeResolver(); + return util.forEachSubDirSequential(config.dest, function(dir) { + var defer = Q.defer(); + var done = defer.makeNodeResolver(); - var supportedModules = [ - 'dist/dart/angular2', - // TODO: blocked by https://github.com/angular/angular/issues/3518 - // 'dist/dart/angular2_material', - 'dist/dart/benchpress' - ]; + var supportedModules = [ + 'dist/dart/angular2', + // TODO: blocked by https://github.com/angular/angular/issues/3518 + // 'dist/dart/angular2_material', + 'dist/dart/benchpress' + ]; - if (supportedModules.indexOf(dir) === -1) { - done(); - } else { - console.log('INFO: running dartdoc for ', dir); + if (supportedModules.indexOf(dir) === -1) { + done(); + } else { + console.log('INFO: running dartdoc for ', dir); - var stream = spawn(config.command, ['--input=.', '--output=' + config.output], { - stdio: [process.stdin, process.stdout, process.stderr], - cwd: dir - }); + var stream = spawn(config.command, ['--input=.', '--output=' + config.output], + {stdio: [process.stdin, process.stdout, process.stderr], cwd: dir}); - stream.on('exit', function(code) { - if (code !== 0) { - done('ERROR: dartdoc exited with non-zero status ' + code); - } else { - done(); - } - }); + stream.on('exit', function(code) { + if (code !== 0) { + done('ERROR: dartdoc exited with non-zero status ' + code); + } else { + done(); + } + }); - stream.on('error', function(e) { - done('ERROR: dartdoc reported error: ' + e); - }); - } - return defer.promise; - }); - }; + stream.on('error', function(e) { done('ERROR: dartdoc reported error: ' + e); }); + } + return defer.promise; + }); };