From 51e6f33d32d7da348bcb3d762b2e82412d707a44 Mon Sep 17 00:00:00 2001 From: Alex Eagle Date: Mon, 20 Jul 2015 15:54:30 -0700 Subject: [PATCH] chore(build): Make PRs 15m faster. Don't precompile Dart2JS for pull requests, instead serve the dart sources with pub serve. We were already testing with Dartium so all we lose is some test coverage of defects exposed only by the Dart2JS transpiler. This still runs the dart transformer. Fixes #3030 --- DEVELOPER.md | 4 +-- gulpfile.js | 35 ++++++++++++++++--- .../src/compiler/compiler_benchmark.dart | 10 +++--- npm-shrinkwrap.clean.json | 6 ++++ npm-shrinkwrap.json | 24 +++++++++---- package.json | 2 ++ scripts/ci/test_e2e_dart.sh | 13 +++++-- scripts/ci/test_perf.sh | 13 +++++-- scripts/ci/test_server_dart.sh | 13 +++++-- tools/build/jsserve.js | 33 ++++++++++++++--- tools/build/pubserve.js | 7 ++-- 11 files changed, 128 insertions(+), 32 deletions(-) diff --git a/DEVELOPER.md b/DEVELOPER.md index 8f45b8a97c..d911cd45e2 100644 --- a/DEVELOPER.md +++ b/DEVELOPER.md @@ -187,7 +187,7 @@ rights to built them in your operating system. ### E2E tests 1. `$(npm bin)/gulp build.js.cjs` (builds benchpress and tests into `dist/js/cjs` folder). -2. `$(npm bin)/gulp serve.js.prod serve.js.dart2js` (runs a local webserver). +2. `$(npm bin)/gulp serve.js.prod serve.dart` (runs a local webserver). 3. `$(npm bin)/protractor protractor-js.conf.js`: JS e2e tests. 4. `$(npm bin)/protractor protractor-dart2js.conf.js`: dart2js e2e tests. @@ -197,7 +197,7 @@ Angular specific command line options when running protractor: ### Performance tests 1. `$(npm bin)/gulp build.js.cjs` (builds benchpress and tests into `dist/js/cjs` folder) -2. `$(npm bin)/gulp serve.js.prod serve.js.dart2js` (runs a local webserver) +2. `$(npm bin)/gulp serve.js.prod serve.dart` (runs a local webserver) 3. `$(npm bin)/protractor protractor-js.conf.js --benchmark`: JS performance tests 4. `$(npm bin)/protractor protractor-dart2js.conf.js --benchmark`: dart2js performance tests diff --git a/gulpfile.js b/gulpfile.js index bbb60ef957..dde8fa90c0 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -150,7 +150,7 @@ var BENCHPRESS_BUNDLE_CONFIG = { 'rx' ], dest: CONFIG.dest.benchpress_bundle -} +}; // ------------ // clean @@ -245,6 +245,7 @@ gulp.task('build/analyze.dart', dartanalyzer(gulp, gulpPlugins, { // ------------ // pubbuild +// WARNING: this task is very slow (~15m as of July 2015) gulp.task('build/pubbuild.dart', pubbuild(gulp, gulpPlugins, { src: CONFIG.dest.dart, @@ -330,6 +331,17 @@ function jsServeDartJs() { })(); } +function proxyServeDart() { + return jsserve(gulp, gulpPlugins, { + port: 8002, + proxies: [ + {route: '/examples', url: 'http://localhost:8004'}, + {route: '/benchmarks_external', url: 'http://localhost:8008'}, + {route: '/benchmarks', url: 'http://localhost:8006'} + ] + })(); +} + // ------------------ // web servers gulp.task('serve.js.dev', ['build.js.dev'], function(neverDone) { @@ -351,19 +363,33 @@ gulp.task('serve.e2e.prod', ['build.js.prod', 'build.js.cjs', 'build.css.materia gulp.task('serve.js.dart2js', jsServeDartJs); +gulp.task('!proxyServeDart', proxyServeDart); + +gulp.task('serve.dart', function(done) { + runSequence([ + '!proxyServeDart', + 'serve/examples.dart', + 'serve/benchmarks.dart', + 'serve/benchmarks_external.dart' + ], done); +}); + gulp.task('serve/examples.dart', pubserve(gulp, gulpPlugins, { command: DART_SDK.PUB, - path: CONFIG.dest.dart + '/examples' + path: CONFIG.dest.dart + '/examples', + port: 8004 })); gulp.task('serve/benchmarks.dart', pubserve(gulp, gulpPlugins, { command: DART_SDK.PUB, - path: CONFIG.dest.dart + '/benchmarks' + path: CONFIG.dest.dart + '/benchmarks', + port: 8006 })); gulp.task('serve/benchmarks_external.dart', pubserve(gulp, gulpPlugins, { command: DART_SDK.PUB, - path: CONFIG.dest.dart + '/benchmarks_external' + path: CONFIG.dest.dart + '/benchmarks_external', + port: 8008 })); // -------------- @@ -751,7 +777,6 @@ gulp.task('build.dart', function(done) { 'build/packages.dart', 'build/pubspec.dart', 'build/analyze.dart', - 'build/pubbuild.dart', 'build.dart.material.css', sequenceComplete(done) ); diff --git a/modules/benchmarks_external/src/compiler/compiler_benchmark.dart b/modules/benchmarks_external/src/compiler/compiler_benchmark.dart index 5fd61ba6cf..fb887d81d3 100644 --- a/modules/benchmarks_external/src/compiler/compiler_benchmark.dart +++ b/modules/benchmarks_external/src/compiler/compiler_benchmark.dart @@ -56,33 +56,33 @@ createTemplate(String html) { return div; } -@Directive(selector: '[dir0]', map: const {'attr0': '=>prop'}) +@Decorator(selector: '[dir0]', map: const {'attr0': '=>prop'}) class Dir0 { Object prop; } -@Directive(selector: '[dir1]', map: const {'attr1': '=>prop'}) +@Decorator(selector: '[dir1]', map: const {'attr1': '=>prop'}) class Dir1 { Object prop; constructor(Dir0 dir0) {} } -@Directive(selector: '[dir2]', map: const {'attr2': '=>prop'}) +@Decorator(selector: '[dir2]', map: const {'attr2': '=>prop'}) class Dir2 { Object prop; constructor(Dir1 dir1) {} } -@Directive(selector: '[dir3]', map: const {'attr3': '=>prop'}) +@Decorator(selector: '[dir3]', map: const {'attr3': '=>prop'}) class Dir3 { Object prop; constructor(Dir2 dir2) {} } -@Directive(selector: '[dir4]', map: const {'attr4': '=>prop'}) +@Decorator(selector: '[dir4]', map: const {'attr4': '=>prop'}) class Dir4 { Object prop; diff --git a/npm-shrinkwrap.clean.json b/npm-shrinkwrap.clean.json index f5eca4bd30..b628d168dc 100644 --- a/npm-shrinkwrap.clean.json +++ b/npm-shrinkwrap.clean.json @@ -9382,6 +9382,9 @@ "node-uuid": { "version": "1.4.3" }, + "on-headers": { + "version": "1.0.0" + }, "parse5": { "version": "1.3.2" }, @@ -9533,6 +9536,9 @@ } } }, + "proxy-middleware": { + "version": "0.13.0" + }, "q": { "version": "1.3.0" }, diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index 8afbb77b84..252ae2fc6c 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -3355,7 +3355,7 @@ }, "clang-format": { "version": "1.0.28", - "from": "clang-format@1.0.28", + "from": "https://registry.npmjs.org/clang-format/-/clang-format-1.0.28.tgz", "resolved": "https://registry.npmjs.org/clang-format/-/clang-format-1.0.28.tgz", "dependencies": { "resolve": { @@ -14506,6 +14506,11 @@ "from": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.3.tgz", "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.3.tgz" }, + "on-headers": { + "version": "1.0.0", + "from": "on-headers@*", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.0.tgz" + }, "parse5": { "version": "1.3.2", "from": "https://registry.npmjs.org/parse5/-/parse5-1.3.2.tgz", @@ -14743,6 +14748,11 @@ } } }, + "proxy-middleware": { + "version": "0.13.0", + "from": "proxy-middleware@*", + "resolved": "https://registry.npmjs.org/proxy-middleware/-/proxy-middleware-0.13.0.tgz" + }, "q": { "version": "1.3.0", "from": "https://registry.npmjs.org/q/-/q-1.3.0.tgz", @@ -15390,29 +15400,29 @@ "dependencies": { "source-map": { "version": "0.4.4", - "from": "source-map@>=0.4.2 <0.5.0", + "from": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", "dependencies": { "amdefine": { "version": "1.0.0", - "from": "amdefine@>=0.0.4", + "from": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.0.tgz", "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.0.tgz" } } }, "source-map-support": { "version": "0.3.2", - "from": "source-map-support@>=0.3.1 <0.4.0", + "from": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.3.2.tgz", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.3.2.tgz", "dependencies": { "source-map": { "version": "0.1.32", - "from": "source-map@0.1.32", + "from": "https://registry.npmjs.org/source-map/-/source-map-0.1.32.tgz", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.32.tgz", "dependencies": { "amdefine": { "version": "1.0.0", - "from": "amdefine@>=0.0.4", + "from": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.0.tgz", "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.0.tgz" } } @@ -15421,7 +15431,7 @@ }, "typescript": { "version": "1.5.3", - "from": "microsoft/TypeScript#release-1.5", + "from": "git://github.com/microsoft/TypeScript.git#a24aa6f57d281bafd3535f0f4c3f492364a8b4d6", "resolved": "git://github.com/microsoft/TypeScript.git#a24aa6f57d281bafd3535f0f4c3f492364a8b4d6" } } diff --git a/package.json b/package.json index b39035ebd1..39bb6e793e 100644 --- a/package.json +++ b/package.json @@ -103,8 +103,10 @@ "mock-fs": "^2.5.0", "node-html-encoder": "0.0.2", "node-uuid": "1.4.x", + "on-headers": "^1.0.0", "parse5": "1.3.2", "protractor": "2.1.0", + "proxy-middleware": "^0.13.0", "q": "^1.0.1", "react": "^0.13.2", "rewire": "^2.3.3", diff --git a/scripts/ci/test_e2e_dart.sh b/scripts/ci/test_e2e_dart.sh index 009575d1ba..ec9726a44f 100755 --- a/scripts/ci/test_e2e_dart.sh +++ b/scripts/ci/test_e2e_dart.sh @@ -12,8 +12,17 @@ function killServer () { kill $serverPid } -./node_modules/.bin/gulp serve.js.dart2js& -serverPid=$! +# Serving pre-compiled dart JS takes an extra 15m. +# So we do this only for post-commit testing. +# Pull requests test with Dartium and pub serve +if [ "${TRAVIS_PULL_REQUEST}" = "false" ]; then + ./node_modules/.bin/gulp build/pubbuild.dart + ./node_modules/.bin/gulp serve.js.dart2js& + serverPid=$! +else + ./node_modules/.bin/gulp serve.dart& + serverPid=$! +fi ./node_modules/.bin/gulp build.css.material& diff --git a/scripts/ci/test_perf.sh b/scripts/ci/test_perf.sh index 5f3c99a060..6906f29fff 100755 --- a/scripts/ci/test_perf.sh +++ b/scripts/ci/test_perf.sh @@ -13,8 +13,17 @@ function killServer () { kill $serverPid } -./node_modules/.bin/gulp serve.js.prod serve.js.dart2js& -serverPid=$! +# Serving pre-compiled dart JS takes an extra 15m. +# So we do this only for post-commit testing. +# Pull requests test with Dartium and pub serve +if [ "${TRAVIS_PULL_REQUEST}" = "false" ]; then + ./node_modules/.bin/gulp build/pubbuild.dart + ./node_modules/.bin/gulp serve.js.prod serve.js.dart2js& + serverPid=$! +else + ./node_modules/.bin/gulp serve.js.prod serve.dart& + serverPid=$! +fi trap killServer EXIT diff --git a/scripts/ci/test_server_dart.sh b/scripts/ci/test_server_dart.sh index 6bb7e2e028..90c6c6046f 100755 --- a/scripts/ci/test_server_dart.sh +++ b/scripts/ci/test_server_dart.sh @@ -11,8 +11,17 @@ cd $SCRIPT_DIR/../.. webdriverServerPid=$! ps -ef | grep webdriver-manager -./node_modules/.bin/gulp serve.js.dart2js& -serverPid=$! +# Serving pre-compiled dart JS takes an extra 15m. +# So we do this only for post-commit testing. +# Pull requests test with Dartium and pub serve +if [ "${TRAVIS_PULL_REQUEST}" = "false" ]; then + ./node_modules/.bin/gulp build/pubbuild.dart + ./node_modules/.bin/gulp serve.js.dart2js& + serverPid=$! +else + ./node_modules/.bin/gulp serve.dart& + serverPid=$! +fi function killAllServers () { kill $serverPid diff --git a/tools/build/jsserve.js b/tools/build/jsserve.js index e00fa23dc9..d2e01e3fde 100644 --- a/tools/build/jsserve.js +++ b/tools/build/jsserve.js @@ -1,15 +1,40 @@ +var onHeaders = require('on-headers'); +var proxy = require('proxy-middleware'); +var url = require('url'); + module.exports = function(gulp, plugins, config) { return function() { plugins.connect.server({ - root: [__dirname+'/../../'+config.path], + root: [__dirname + '/../../' + config.path], port: config.port, livereload: false, open: false, middleware: function(connect, opt) { - return [ - connect.favicon() - ] + config.proxies = config.proxies || []; + var middlewares = + config.proxies.map(function(entry) { return makeProxy(entry.route, entry.url); }); + middlewares.push(connect.favicon()); + // pub serve can't give the right content-type header for jsonp requests + // so we must turn off Chromium strict MIME type checking + // see https://github.com/angular/angular/issues/3030#issuecomment-123453168 + middlewares.unshift(stripHeader('x-content-type-options')); + return middlewares; } })(); }; }; + +function makeProxy(route, urlParam) { + var options = url.parse(urlParam); + options.route = route; + return proxy(options); +} + +function stripHeader(toStrip) { + return function(req, res, next) { + onHeaders(res, function onHeaders() { + res.removeHeader(toStrip); + }); + next(); + }; +} diff --git a/tools/build/pubserve.js b/tools/build/pubserve.js index 69857885d3..461a932be0 100644 --- a/tools/build/pubserve.js +++ b/tools/build/pubserve.js @@ -3,11 +3,12 @@ var spawn = require('child_process').spawn; module.exports = function(gulp, plugins, config, module) { return function() { + config.port = config.port || 8080; var pubMode = config.mode || 'debug'; - var pubArgs = ['serve', '--mode', pubMode]; + var pubArgs = ['serve', '--mode', pubMode, '--port', config.port]; return util.streamToPromise(spawn(config.command, pubArgs, { - cwd: config.path, stdio: 'inherit' + // pub serve is very spammy, and --verbosity flag doesn't fix it + cwd: config.path, stdio: 'ignore' })); }; }; -