refactor(build): simplify and modularize

simplify:
- use same html file for dart and JS
- build benchmarks automatically when doing `gulp build`
- centralize configuration

modularize:
- move all build tasks into separate node.js modules under
  `tools/build`.

changes:
- the `build` folder is now the `dist` folder

Closes #284
This commit is contained in:
Tobias Bosch 2014-12-05 16:26:30 -08:00
parent e32ddcc7eb
commit 8db77f2405
75 changed files with 710 additions and 848 deletions

6
.gitignore vendored
View File

@ -1,10 +1,8 @@
# Dont commit the following directories created by pub.
build/
benchpress-build/
/dist/
packages/
.buildlog
node_modules
packages
.pub
.DS_STORE
@ -21,4 +19,4 @@ pubspec.lock
.idea/
docs/bower_components/
/docs/bower_components/

View File

@ -25,13 +25,13 @@
### Build:
1. `gulp build` -> result is in `build` folder
1. `gulp build` -> result is in `dist` folder
* will also run `pub get` for the subfolders in `modules`
and run `dartanalyzer` for every file that matches
`<module>/src/<module>.dart`, e.g. `di/src/di.dart`
2. `gulp clean` -> cleans the `build` folder
2. `gulp clean` -> cleans the `dist` folder
### Tests:
@ -45,13 +45,6 @@ the transpiler is reloaded. With that it is possible to make changes
to the preprocessor and run the tests without exiting karma
(just touch a test file that you would like to run).
Restriction for Dart tests (for now):
* Due to a bug `karma-dart` plugin,
this will use the files in the `build` folder for resolving
`package:` dependencies (created e.g. for `import ... from 'di:di'`).
So you need to execute `gulp build` before this.
### Examples:
To see the examples, first build the project as described above.
@ -59,11 +52,11 @@ To see the examples, first build the project as described above.
#### Hello World Example
This example consists of three basic pieces - a component, a decorator and a service.
They are all constructed via injection. For more information see the comments in the
source `modules/examples/src/hello_world/app.js`.
source `modules/examples/src/hello_world/index.js`.
You can build this example as either JS or Dart app:
* (JS) `gulp serve` and open `localhost:8000/js/examples/lib/hello_world/` in Chrome.
* (Dart) `gulp examples/pub.serve` and open `localhost:8080` in Chrome(for dart2js) or dartium(for dart vm).
* (JS) `gulp serve.js.dev` and open `localhost:8000/examples/web/hello_world/` in Chrome.
* (Dart) `gulp serve/examples.dart` and open `localhost:8080` in Chrome(for dart2js) or dartium(for dart vm).
## Debug the transpiler

View File

@ -45,7 +45,7 @@ module.exports = new Package('angular', [jsdocPackage, nunjucksPackage])
// Configure file writing
.config(function(writeFilesProcessor) {
writeFilesProcessor.outputFolder = 'build/docs';
writeFilesProcessor.outputFolder = 'dist/docs';
})

View File

@ -1,6 +1,6 @@
var traceur = require('traceur/src/node/traceur.js');
var ParseTreeVisitor = System.get(System.map.traceur + '/src/syntax/ParseTreeVisitor').ParseTreeVisitor;
var file2modulename = require('../../../file2modulename');
var file2modulename = require('../../../tools/build/file2modulename');
/**
* Wrapper around traceur that can parse the contents of a file
*/

View File

@ -1,22 +1,23 @@
var benchpress = require('angular-benchpress/lib/cli');
var del = require('del');
var es = require('event-stream');
var file2moduleName = require('./file2modulename');
var fs = require('fs');
var glob = require('glob');
var gulp = require('gulp');
var $ = require('gulp-load-plugins')();
var merge = require('merge');
var mergeStreams = require('event-stream').merge;
var path = require('path');
var Q = require('q');
var readline = require('readline');
var gulpPlugins = require('gulp-load-plugins')();
var runSequence = require('run-sequence');
var spawn = require('child_process').spawn;
var through2 = require('through2');
var which = require('which');
var merge = require('merge');
var gulpTraceur = require('./tools/transpiler/gulp-traceur');
var js2es5Options = {
var clean = require('./tools/build/clean');
var deps = require('./tools/build/deps');
var transpile = require('./tools/build/transpile');
var html = require('./tools/build/html');
var benchpress = require('./tools/build/benchpress');
var pubspec = require('./tools/build/pubspec');
var dartanalyzer = require('./tools/build/dartanalyzer');
var jsserve = require('./tools/build/jsserve');
var pubserve = require('./tools/build/pubserve');
var DART_SDK = require('./tools/build/dartdetect')(gulp);
// -----------------------
// configuration
var _COMPILER_CONFIG_JS_DEFAULT = {
sourceMaps: true,
annotations: true, // parse annotations
types: true, // parse types
@ -25,388 +26,256 @@ var js2es5Options = {
modules: 'instantiate'
};
var js2es5OptionsProd = merge(true, js2es5Options, {
typeAssertions: false
});
var _HTLM_DEFAULT_SCRIPTS_JS = [
{src: '/deps/traceur-runtime.js', mimeType: 'text/javascript'},
{src: '/rtts_assert/lib/rtts_assert.js', mimeType: 'text/javascript'},
{src: '/deps/es6-module-loader-sans-promises.src.js', mimeType: 'text/javascript'},
{src: '/deps/system.src.js', mimeType: 'text/javascript'},
{src: '/deps/extension-register.js', mimeType: 'text/javascript'},
{src: '/deps/runtime_paths.js', mimeType: 'text/javascript'},
{
inline: 'System.import(\'$MODULENAME$\').then(function(m) { m.main(); }, console.log.bind(console))',
mimeType: 'text/javascript'
}
];
var js2es5OptionsDev = merge(true, js2es5Options, {
var CONFIG = {
commands: {
pub: process.platform === 'win32' ? 'pub.bat' : 'pub',
dartanalyzer: process.platform === "win32" ? "dartanalyzer.bat" : "dartanalyzer"
},
dest: {
js: {
all: 'dist/js',
dev: 'dist/js/dev',
prod: 'dist/js/prod'
},
dart: 'dist/dart'
},
srcFolderMapping: {
'default': 'lib',
// need a tmp folder as benchpress does not support
// inplace generation of the benchmarks...
'benchmark*/**': 'perf_tmp',
'example*/**': 'web'
},
deps: {
js: [
gulpTraceur.RUNTIME_PATH,
"node_modules/es6-module-loader/dist/es6-module-loader-sans-promises.src.js",
"node_modules/systemjs/dist/system.src.js",
"node_modules/systemjs/lib/extension-register.js",
"tools/build/runtime_paths.js",
"node_modules/angular/angular.js"
]
},
transpile: {
src: {
js: ['modules/**/*.js', 'modules/**/*.es6'],
dart: ['modules/**/*.js']
},
copy: {
js: ['modules/**/*.es5'],
dart: ['modules/**/*.dart']
},
options: {
js: {
dev: merge(true, _COMPILER_CONFIG_JS_DEFAULT, {
typeAssertionModule: 'rtts_assert/rtts_assert',
typeAssertions: true
});
var js2dartOptions = {
}),
prod: merge(true, _COMPILER_CONFIG_JS_DEFAULT, {
typeAssertions: false
})
},
dart: {
sourceMaps: true,
annotations: true, // parse annotations
types: true, // parse types
script: false, // parse as a module
memberVariables: true, // parse class fields
outputLanguage: 'dart'
};
var DART_SDK = false;
try {
which.sync('dart');
console.log('Dart SDK detected');
if (process.platform === 'win32') {
DART_SDK = {
PUB: 'pub.bat',
ANALYZER: 'dartanalyzer.bat'
};
} else {
DART_SDK = {
PUB: 'pub',
ANALYZER: 'dartanalyzer'
};
}
} catch (e) {
console.log('Dart SDK is not available, Dart tasks will be skipped.');
var gulpTaskFn = gulp.task.bind(gulp);
gulp.task = function (name, deps, fn) {
if (name.indexOf('.dart') === -1) {
return gulpTaskFn(name, deps, fn);
} else {
return gulpTaskFn(name, function() {
console.log('Dart SDK is not available. Skipping task: ' + name);
});
}
};
}
var gulpTraceur = require('./tools/transpiler/gulp-traceur');
// ---------
// traceur runtime
gulp.task('jsRuntime/build', function() {
var traceurRuntime = gulp.src([
gulpTraceur.RUNTIME_PATH,
"node_modules/es6-module-loader/dist/es6-module-loader-sans-promises.src.js",
"node_modules/systemjs/dist/system.src.js",
"node_modules/systemjs/lib/extension-register.js"
]).pipe(gulp.dest('build/js'));
return traceurRuntime;
});
// -----------------------
// modules
var sourceTypeConfigs = {
dart: {
transpileSrc: ['modules/**/*.js'],
// pub serve uses project_root/web for static serving.
htmlSrc: ['modules/*/src/**/*.html', 'modules/*/web/*.html'],
copySrc: ['modules/**/*.dart'],
outputDir: 'build/dart',
outputExt: 'dart',
mimeType: 'application/dart'
},
html: {
src: {
js: ['modules/*/src/**/*.html'],
dart: ['modules/*/src/**/*.html']
},
scriptsPerFolder: {
js: {
transpileSrc: ['modules/**/*.js', 'modules/**/*.es6'],
htmlSrc: ['modules/*/src/**/*.html'],
copySrc: ['modules/**/*.es5'],
outputDir: 'build/js',
outputExt: 'js'
default: _HTLM_DEFAULT_SCRIPTS_JS,
'benchmarks_external/**':
[{ src: '/deps/angular.js', mimeType: 'text/javascript' }].concat(_HTLM_DEFAULT_SCRIPTS_JS)
},
dart: {
default: [
{src: '$MODULENAME_WITHOUT_PATH$.dart', mimeType: 'application/dart'},
{src: 'packages/browser/dart.js', mimeType: 'text/javascript'}
]
}
}
},
benchpress: {
configFile: {
content: 'module.exports=function(){};\n',
name: 'bp.conf.js'
},
mainHtmls: '*/perf_tmp/**/main.html',
outputFolderName: 'web'
},
pubspec: {
src: 'modules/*/pubspec.yaml'
}
};
// ------------
// clean
gulp.task('modules/clean', function(cb) {
del('build', cb);
});
gulp.task('build/clean.js', clean(gulp, gulpPlugins, {
path: CONFIG.dest.js.all
}));
gulp.task('modules/build.dart/src', function() {
return createModuleTask(merge(sourceTypeConfigs.dart, {compilerOptions: js2dartOptions}));
});
gulp.task('build/clean.dart', clean(gulp, gulpPlugins, {
path: CONFIG.dest.dart
}));
gulp.task('modules/build.dart/pubspec', function() {
var outputDir = sourceTypeConfigs.dart.outputDir;
var files = [];
var changedStream = gulp.src('modules/*/pubspec.yaml')
.pipe($.changed(outputDir)) // Only forward files that changed.
.pipe(through2.obj(function(file, enc, done) {
files.push(path.resolve(process.cwd(), outputDir, file.relative));
this.push(file);
done();
}))
.pipe(gulp.dest(outputDir));
// 1. We need to wait for all pubspecs to be present before executing
// `pub get` as it checks the folders of the dependencies!
// 2. We execute `pub get` commands sequentially to avoid race condition with pub cache
var promise = streamToPromise(changedStream).then(function() {
for (var i = 0; i < files.length; i++) {
(function (file) {
promise = promise.then(function() {
return processToPromise(spawn(DART_SDK.PUB, ['get'], {
stdio: 'inherit',
cwd: path.dirname(file)
}));
});
})(files[i]);
}
});
// ------------
// deps
return promise;
gulp.task('build/deps.js.dev', deps(gulp, gulpPlugins, {
src: CONFIG.deps.js,
dest: CONFIG.dest.js.dev
}));
});
gulp.task('build/deps.js.prod', deps(gulp, gulpPlugins, {
src: CONFIG.deps.js,
dest: CONFIG.dest.js.prod
}));
function processToPromise(process) {
var defer = Q.defer();
process.on('close', function(code) {
if (code) {
defer.reject(code);
} else {
defer.resolve();
}
});
return defer.promise;
}
// ------------
// transpile
function streamToPromise(stream) {
var defer = Q.defer();
stream.on('end', defer.resolve);
stream.on('error', defer.reject);
return defer.promise;
}
gulp.task('build/transpile.js.dev', transpile(gulp, gulpPlugins, {
src: CONFIG.transpile.src.js,
copy: CONFIG.transpile.copy.js,
dest: CONFIG.dest.js.dev,
outputExt: 'js',
options: CONFIG.transpile.options.js.dev,
srcFolderMapping: CONFIG.srcFolderMapping
}));
gulp.task('modules/build.dart', ['modules/build.dart/src', 'modules/build.dart/pubspec']);
gulp.task('build/transpile.js.prod', transpile(gulp, gulpPlugins, {
src: CONFIG.transpile.src.js,
copy: CONFIG.transpile.copy.js,
dest: CONFIG.dest.js.prod,
outputExt: 'js',
options: CONFIG.transpile.options.js.prod,
srcFolderMapping: CONFIG.srcFolderMapping
}));
gulp.task('modules/build.dev.js', function() {
return createModuleTask(merge(true, sourceTypeConfigs.js, {compilerOptions: js2es5OptionsDev}));
});
gulp.task('build/transpile.dart', transpile(gulp, gulpPlugins, {
src: CONFIG.transpile.src.dart,
copy: CONFIG.transpile.copy.dart,
dest: CONFIG.dest.dart,
outputExt: 'dart',
options: CONFIG.transpile.options.dart,
srcFolderMapping: CONFIG.srcFolderMapping
}));
gulp.task('modules/build.prod.js', function() {
return createModuleTask(merge(true, sourceTypeConfigs.js, {compilerOptions: js2es5OptionsProd}));
});
// ------------
// html
function renameSrcToLib(file) {
file.dirname = file.dirname.replace(/\bsrc\b/, 'lib');
}
gulp.task('build/html.js.dev', html(gulp, gulpPlugins, {
src: CONFIG.html.src.js,
dest: CONFIG.dest.js.dev,
srcFolderMapping: CONFIG.srcFolderMapping,
scriptsPerFolder: CONFIG.html.scriptsPerFolder.js
}));
function renameEs5ToJs(file) {
if (file.extname == '.es5') {
file.extname = '.js';
}
}
gulp.task('build/html.js.prod', html(gulp, gulpPlugins, {
src: CONFIG.html.src.js,
dest: CONFIG.dest.js.prod,
srcFolderMapping: CONFIG.srcFolderMapping,
scriptsPerFolder: CONFIG.html.scriptsPerFolder.js
}));
function createModuleTask(sourceTypeConfig) {
var transpile = gulp.src(sourceTypeConfig.transpileSrc)
.pipe($.rename({extname: '.'+sourceTypeConfig.outputExt}))
.pipe($.rename(renameSrcToLib))
.pipe(gulpTraceur(sourceTypeConfig.compilerOptions, file2moduleName))
.pipe(gulp.dest(sourceTypeConfig.outputDir));
var copy = gulp.src(sourceTypeConfig.copySrc)
.pipe($.rename(renameSrcToLib))
.pipe($.rename(renameEs5ToJs))
.pipe(gulp.dest(sourceTypeConfig.outputDir));
// TODO: provide the list of files to the template
// automatically!
var html = gulp.src(sourceTypeConfig.htmlSrc)
.pipe($.rename(renameSrcToLib))
.pipe($.ejs({
type: sourceTypeConfig.outputExt
}))
.pipe(gulp.dest(sourceTypeConfig.outputDir));
gulp.task('build/html.dart', html(gulp, gulpPlugins, {
src: CONFIG.html.src.dart,
dest: CONFIG.dest.dart,
srcFolderMapping: CONFIG.srcFolderMapping,
scriptsPerFolder: CONFIG.html.scriptsPerFolder.dart
}));
return mergeStreams(transpile, copy, html);
}
// ------------
// benchpress
gulp.task('build/benchpress.js.dev', benchpress(gulp, gulpPlugins, {
mainHtmls: CONFIG.benchpress.mainHtmls,
configFile: CONFIG.benchpress.configFile,
buildDir: CONFIG.dest.js.dev,
outputFolderName: CONFIG.benchpress.outputFolderName
}));
gulp.task('build/benchpress.js.prod', benchpress(gulp, gulpPlugins, {
mainHtmls: CONFIG.benchpress.mainHtmls,
configFile: CONFIG.benchpress.configFile,
buildDir: CONFIG.dest.js.prod,
outputFolderName: CONFIG.benchpress.outputFolderName
}));
gulp.task('build/benchpress.dart', benchpress(gulp, gulpPlugins, {
mainHtmls: CONFIG.benchpress.mainHtmls,
configFile: CONFIG.benchpress.configFile,
buildDir: CONFIG.dest.dart,
outputFolderName: CONFIG.benchpress.outputFolderName
}));
// ------------
// pubspec
gulp.task('build/pubspec.dart', pubspec(gulp, gulpPlugins, {
src: CONFIG.pubspec.src,
dest: CONFIG.dest.dart,
command: DART_SDK.PUB
}));
// ------------
// pubspec
gulp.task('build/analyze.dart', dartanalyzer(gulp, gulpPlugins, {
dest: CONFIG.dest.dart,
command: DART_SDK.ANALYZER,
srcFolderMapping: CONFIG.srcFolderMapping
}));
// ------------------
// ANALYZE
// web servers
gulp.task('serve.js.dev', jsserve(gulp, gulpPlugins, {
path: CONFIG.dest.js.dev
}));
gulp.task('analyze/analyzer.dart', function(done) {
var pubSpecs = [].slice.call(glob.sync('build/dart/*/pubspec.yaml', {
cwd: __dirname
}));
var tempFile = '_analyzer.dart';
// analyze in parallel!
return Q.all(pubSpecs.map(function(pubSpecFile) {
var dir = path.dirname(pubSpecFile);
var srcFiles = [].slice.call(glob.sync('lib/**/*.dart', {
cwd: dir
}));
var testFiles = [].slice.call(glob.sync('test/**/*_spec.dart', {
cwd: dir
}));
var analyzeFile = ['library _analyzer;'];
srcFiles.concat(testFiles).forEach(function(fileName, index) {
if (fileName !== tempFile) {
analyzeFile.push('import "./'+fileName+'" as mod'+index+';');
}
});
fs.writeFileSync(path.join(dir, tempFile), analyzeFile.join('\n'));
var defer = Q.defer();
analyze(dir, defer.makeNodeResolver());
return defer.promise;
}));
gulp.task('serve.js.prod', jsserve(gulp, gulpPlugins, {
path: CONFIG.dest.js.prod
}));
function analyze(dirName, done) {
var stream = spawn(DART_SDK.ANALYZER, ['--fatal-warnings', tempFile], {
// inherit stdin and stderr, but filter stdout
stdio: [process.stdin, 'pipe', process.stderr],
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.stdout,
output: process.stdout,
terminal: false
});
var hintCount = 0;
rl.on('line', function(line) {
if (line.match(/Unused import/)) {
return;
}
if (line.match(/\[hint\]/)) {
hintCount++;
}
console.log(dirName + ':' + line);
});
stream.on('close', function(code) {
var error;
if (code !== 0) {
error = new Error('Dartanalyzer failed with exit code ' + code);
}
if (hintCount > 0) {
error = new Error('Dartanalyzer showed hints');
}
done(error);
});
}
});
gulp.task('serve/examples.dart', pubserve(gulp, gulpPlugins, {
command: DART_SDK.PUB,
path: CONFIG.dest.dart + '/examples'
}));
gulp.task('serve/benchmarks.dart', pubserve(gulp, gulpPlugins, {
command: DART_SDK.PUB,
path: CONFIG.dest.dart + '/benchmarks'
}));
// ------------------
// BENCHMARKS JS
gulp.task('benchmarks/internal.benchpress.js', function () {
benchpress.build({
benchmarksPath: 'build/js/benchmarks/lib',
buildPath: 'build/benchpress/js'
})
});
gulp.task('benchmarks/external.benchpress.js', function () {
benchpress.build({
benchmarksPath: 'build/js/benchmarks_external/lib',
buildPath: 'build/benchpress/js'
})
});
gulp.task('benchmarks/internal.js', function() {
runSequence(
['jsRuntime/build', 'modules/build.prod.js'],
'benchmarks/internal.benchpress.js'
);
});
gulp.task('benchmarks/external.js', function() {
runSequence(
['jsRuntime/build', 'modules/build.prod.js'],
'benchmarks/external.benchpress.js'
);
});
// ------------------
// BENCHMARKS DART
function benchmarkDart2Js(buildPath, done) {
mergeStreams(dart2jsStream(), bpConfStream())
.on('end', function() {
runBenchpress();
done();
});
function dart2jsStream() {
return gulp.src([
buildPath+"/lib/**/benchmark.dart"
]).pipe($.shell(['dart2js --package-root="'+buildPath+'/packages" -o "<%= file.path %>.js" <%= file.path %>']));
}
function bpConfStream() {
var bpConfContent = "module.exports = function(c) {c.set({scripts: [{src: 'benchmark.dart.js'}]});}";
var createBpConfJs = es.map(function(file, cb) {
var dir = path.dirname(file.path);
fs.writeFileSync(path.join(dir, "bp.conf.js"), bpConfContent);
cb();
});
return gulp.src([
buildPath+"/lib/**/benchmark.dart"
]).pipe(createBpConfJs);
}
function runBenchpress() {
benchpress.build({
benchmarksPath: buildPath+'/lib',
buildPath: 'build/benchpress/dart'
});
}
}
gulp.task('benchmarks/internal.dart', ['modules/build.dart'], function(done) {
benchmarkDart2Js('build/dart/benchmarks', done);
});
gulp.task('benchmarks/external.dart', ['modules/build.dart'], function(done) {
benchmarkDart2Js('build/dart/benchmarks_external', done);
});
gulp.task('benchmarks/build.dart', ['benchmarks/internal.dart', 'benchmarks/external.dart']);
// ------------------
// WEB SERVERS
gulp.task('serve', function() {
$.connect.server({
root: [__dirname+'/build'],
port: 8000,
livereload: false,
open: false,
middleware: function() {
return [function(req, resp, next){
if (req.url.match(/\.dart$/)) {
resp.setHeader("Content-Type", "application/dart");
}
next();
}];
}
})();
});
gulp.task('examples/pub.serve', function(done) {
spawn(DART_SDK.PUB, ['serve'], {cwd: 'build/dart/examples', stdio: 'inherit'})
.on('done', done);
});
// --------------
// general targets
gulp.task('clean', ['modules/clean']);
gulp.task('build', function(done) {
runSequence(
// parallel
['jsRuntime/build', 'modules/build.dart', 'modules/build.dev.js'],
// sequential
'analyze/analyzer.dart'
);
});
gulp.task('analyze', function(done) {
runSequence('analyze/analyzer.dart');
});
gulp.task('serve/benchmarks_external.dart', pubserve(gulp, gulpPlugins, {
command: DART_SDK.PUB,
path: CONFIG.dest.dart + '/benchmarks_external'
}));
// --------------
// doc generation
@ -435,12 +304,12 @@ gulp.task('docs/bower', function() {
gulp.task('docs/assets', ['docs/bower'], function() {
return gulp.src('docs/bower_components/**/*')
.pipe(gulp.dest('build/docs/lib'));
.pipe(gulp.dest('dist/docs/lib'));
});
gulp.task('docs/app', function() {
return gulp.src('docs/app/**/*')
.pipe(gulp.dest('build/docs'));
.pipe(gulp.dest('dist/docs'));
});
gulp.task('docs', ['docs/assets', 'docs/app', 'docs/dgeni']);
@ -456,8 +325,38 @@ gulp.task('docs/test', function () {
var webserver = require('gulp-webserver');
gulp.task('docs/serve', function() {
gulp.src('build/docs/')
gulp.src('dist/docs/')
.pipe(webserver({
fallback: 'index.html'
}));
});
// -----------------
// orchestrated targets
gulp.task('build.dart', function() {
return runSequence(
['build/transpile.dart', 'build/html.dart', 'build/pubspec.dart'],
'build/benchpress.dart',
'build/analyze.dart'
);
});
gulp.task('build.js.dev', function() {
return runSequence(
['build/deps.js.dev', 'build/transpile.js.dev', 'build/html.js.dev'],
'build/benchpress.js.dev'
);
});
gulp.task('build.js.prod', function() {
return runSequence(
['build/deps.js.prod', 'build/transpile.js.prod', 'build/html.js.prod'],
'build/benchpress.js.dev'
);
});
gulp.task('build.js', ['build.js.dev', 'build.js.prod']);
gulp.task('clean', ['build/clean.js', 'build/clean.dart']);
gulp.task('build', ['build.js', 'build.dart']);

View File

@ -1,6 +1,6 @@
// Karma configuration
// Generated on Thu Sep 25 2014 11:52:02 GMT-0700 (PDT)
var file2moduleName = require('./file2modulename');
var file2moduleName = require('./tools/build/file2modulename');
module.exports = function(config) {
config.set({

View File

@ -1,6 +1,6 @@
// Karma configuration
// Generated on Thu Sep 25 2014 11:52:02 GMT-0700 (PDT)
var file2moduleName = require('./file2modulename');
var file2moduleName = require('./tools/build/file2modulename');
module.exports = function(config) {
config.set({
@ -20,7 +20,7 @@ module.exports = function(config) {
'node_modules/systemjs/dist/system.src.js',
'node_modules/systemjs/lib/extension-register.js',
'file2modulename.js',
'tools/build/file2modulename.js',
'test-main.js'
],

View File

@ -12,3 +12,6 @@ dependencies:
path: ../core
change_detection:
path: ../change_detection
benchpress:
path: ../benchpress
browser: '>=0.10.0 <0.11.0'

View File

@ -1,8 +0,0 @@
library benchmark;
import './change_detection_benchmark.dart' as cdb;
import 'dart:js' as js;
main () {
cdb.run();
}

View File

@ -1,3 +0,0 @@
System.import('benchmarks/change_detection/change_detection_benchmark').then(function (bm) {
bm.run();
}, console.log.bind(console));

View File

@ -1,11 +0,0 @@
module.exports = function(config) {
config.set({
scripts: [
{src: '/js/traceur-runtime.js'},
{src: '/js/es6-module-loader-sans-promises.src.js'},
{src: '/js/extension-register.js'},
{src: 'register_system.js'},
{src: 'benchmark.js'}
]
});
};

View File

@ -3,7 +3,7 @@ import {Parser} from 'change_detection/parser/parser';
import {Lexer} from 'change_detection/parser/lexer';
import {reflector} from 'reflection/reflection';
import {isPresent} from 'facade/lang';
import {benchmark, benchmarkStep} from '../benchpress';
import {benchmark, benchmarkStep} from 'benchpress/benchpress';
import {
ChangeDetector,
@ -153,7 +153,7 @@ function setUpChangeDetection() {
return new ChangeDetector(parentRange);
}
export function run () {
export function main () {
setUpReflector();
benchmark(`Baseline`, function () {

View File

@ -0,0 +1 @@
$SCRIPTS$

View File

@ -0,0 +1 @@
export {main} from './change_detection_benchmark';

View File

@ -1,11 +0,0 @@
System.paths = {
'core/*': '/js/core/lib/*.js',
'change_detection/*': '/js/change_detection/lib/*.js',
'facade/*': '/js/facade/lib/*.js',
'di/*': '/js/di/lib/*.js',
'rtts_assert/*': '/js/rtts_assert/lib/*.js',
'test_lib/*': '/js/test_lib/lib/*.js',
'benchmarks/*': '/js/benchmarks/lib/*.js',
'reflection/*': '/js/reflection/lib/*.js'
};
register(System);

View File

@ -1,9 +0,0 @@
library compiler_benchmark;
import './selector_benchmark.dart' as sbm;
import './compiler_benchmark.dart' as cbm;
main () {
sbm.main();
cbm.main();
}

View File

@ -1,8 +0,0 @@
Promise.all([
System.import('benchmarks/compiler/selector_benchmark'),
System.import('benchmarks/compiler/compiler_benchmark')
]).then(function (benchmarks) {
benchmarks.forEach(function(bm) {
bm.main();
});
}, console.log.bind(console));

View File

@ -1,11 +0,0 @@
module.exports = function(config) {
config.set({
scripts: [
{src: '/js/traceur-runtime.js'},
{src: '/js/es6-module-loader-sans-promises.src.js'},
{src: '/js/extension-register.js'},
{src: 'register_system.js'},
{src: 'benchmark.js'}
]
});
};

View File

@ -1,7 +1,7 @@
import {benchmark, benchmarkStep} from '../benchpress';
import {benchmark, benchmarkStep} from 'benchpress/benchpress';
import {DOM, document} from 'facade/dom';
import {isBlank} from 'facade/lang';
import {isBlank, Type} from 'facade/lang';
import {MapWrapper} from 'facade/collection';
import {AnnotatedType} from 'core/compiler/annotated_type';
@ -111,7 +111,7 @@ export function main() {
benchmark(`instantiate 5*${COUNT} element with bindings`, function() {
var template = loadTemplate('templateWithBindings', COUNT);
var protoView = compiler.compileWithCache(null, annotatedComponent, template);
var rootRecordRange = new ProtoRecordRange().instantiate(null, new Object());
var rootRecordRange = new ProtoRecordRange().instantiate(null, null);
benchmarkStep('run', function() {
var view = protoView.instantiate(null, null, null);

View File

@ -1,3 +1,5 @@
$SCRIPTS$
<template id="templateNoBindings">
<div class="class0 class1 class2 class3 class4 " nodir0="" attr0="value0" nodir1="" attr1="value1" nodir2="" attr2="value2" nodir3="" attr3="value3" nodir4="" attr4="value4">
<div class="class0 class1 class2 class3 class4 " nodir0="" attr0="value0" nodir1="" attr1="value1" nodir2="" attr2="value2" nodir3="" attr3="value3" nodir4="" attr4="value4">

View File

@ -0,0 +1,7 @@
import * as sbm from './selector_benchmark';
import * as cbm from './compiler_benchmark';
export function main() {
sbm.main();
cbm.main();
}

View File

@ -1,11 +0,0 @@
System.paths = {
'core/*': '/js/core/lib/*.js',
'change_detection/*': '/js/change_detection/lib/*.js',
'facade/*': '/js/facade/lib/*.js',
'di/*': '/js/di/lib/*.js',
'rtts_assert/*': '/js/rtts_assert/lib/*.js',
'test_lib/*': '/js/test_lib/lib/*.js',
'benchmarks/*': '/js/benchmarks/lib/*.js',
'reflection/*': '/js/reflection/lib/*.js'
};
register(System);

View File

@ -1,4 +1,4 @@
import {benchmark, benchmarkStep} from '../benchpress';
import {benchmark, benchmarkStep} from 'benchpress/benchpress';
import {SelectorMatcher} from "core/compiler/selector";
import {CssSelector} from "core/compiler/selector";

View File

@ -1,11 +0,0 @@
library injector_get_benchmark;
import './injector_instantiate_benchmark.dart' as b;
import 'dart:js' as js;
main () {
js.context['benchmarkSteps'].add(new js.JsObject.jsify({
"name": "Injector.instantiate",
"fn": new js.JsFunction.withThis((_) => b.run())
}));
}

View File

@ -1,15 +0,0 @@
System.import('benchmarks/di/injector_get_benchmark').then(function (bm) {
window.benchmarkSteps.push({name: 'Injector.get (token)', fn: bm.run});
}, console.log.bind(console));
System.import('benchmarks/di/injector_get_by_key_benchmark').then(function (bm) {
window.benchmarkSteps.push({name: 'Injector.get (key)', fn: bm.run});
}, console.log.bind(console));
System.import('benchmarks/di/injector_get_child_benchmark').then(function (bm) {
window.benchmarkSteps.push({name: 'Injector.get (grand x 5 child)', fn: bm.run});
}, console.log.bind(console));
System.import('benchmarks/di/injector_instantiate_benchmark').then(function (bm) {
window.benchmarkSteps.push({name: 'Injector.instantiate', fn: bm.run});
}, console.log.bind(console));

View File

@ -1,11 +0,0 @@
module.exports = function(config) {
config.set({
scripts: [
{src: '/js/traceur-runtime.js'},
{src: '/js/es6-module-loader-sans-promises.src.js'},
{src: '/js/extension-register.js'},
{src: 'register_system.js'},
{src: 'benchmark.js'}
]
});
};

View File

@ -0,0 +1 @@
$SCRIPTS$

View File

@ -0,0 +1,24 @@
import * as injector_get_benchmark from './injector_get_benchmark';
import * as injector_get_by_key_benchmark from './injector_get_by_key_benchmark';
import * as injector_get_child_benchmark from './injector_get_child_benchmark';
import * as injector_instantiate_benchmark from './injector_instantiate_benchmark';
import {benchmark, benchmarkStep} from 'benchpress/benchpress';
export function main() {
benchmark(`Injector.get (token)`, function() {
benchmarkStep('run', injector_get_benchmark.run);
});
benchmark(`Injector.get (key)`, function() {
benchmarkStep('run', injector_get_by_key_benchmark.run);
});
benchmark(`Injector.get (grand x 5 child)`, function() {
benchmarkStep('run', injector_get_child_benchmark.run);
});
benchmark(`Injector.instantiate`, function() {
benchmarkStep('run', injector_instantiate_benchmark.run);
});
}

View File

@ -1,11 +0,0 @@
System.paths = {
'core/*': '/js/core/lib/*.js',
'change_detection/*': '/js/change_detection/lib/*.js',
'facade/*': '/js/facade/lib/*.js',
'di/*': '/js/di/lib/*.js',
'rtts_assert/*': '/js/rtts_assert/lib/*.js',
'test_lib/*': '/js/test_lib/lib/*.js',
'benchmarks/*': '/js/benchmarks/lib/*.js',
'reflection/*': '/js/reflection/lib/*.js'
};
register(System);

View File

@ -1,23 +0,0 @@
library element_injector_benchmark;
import './instantiate_benchmark.dart' as ib;
import './instantiate_benchmark_codegen.dart' as ibc;
import './instantiate_directive_benchmark.dart' as idb;
import 'dart:js' as js;
main () {
js.context['benchmarkSteps'].add(new js.JsObject.jsify({
"name": "ElementInjector.instantiate + instantiateDirectives",
"fn": new js.JsFunction.withThis((_) => ib.run())
}));
js.context['benchmarkSteps'].add(new js.JsObject.jsify({
"name": "ElementInjector.instantiateDirectives",
"fn": new js.JsFunction.withThis((_) => idb.run())
}));
js.context['benchmarkSteps'].add(new js.JsObject.jsify({
"name": "ElementInjector.instantiate + instantiateDirectives (codegen)",
"fn": new js.JsFunction.withThis((_) => ibc.run())
}));
}

View File

@ -1,11 +0,0 @@
System.import('benchmarks/element_injector/instantiate_benchmark').then(function (bm) {
window.benchmarkSteps.push({name: 'ElementInjector.instantiate + instantiateDirectives', fn: bm.run});
}, console.log.bind(console));
System.import('benchmarks/element_injector/instantiate_directive_benchmark').then(function (bm) {
window.benchmarkSteps.push({name: 'ElementInjector.instantiateDirectives', fn: bm.run});
}, console.log.bind(console));
System.import('benchmarks/element_injector/instantiate_benchmark_codegen').then(function (bm) {
window.benchmarkSteps.push({name: 'ElementInjector.instantiate + instantiateDirectives (codegen)', fn: bm.run});
}, console.log.bind(console));

View File

@ -1,11 +0,0 @@
module.exports = function(config) {
config.set({
scripts: [
{src: '/js/traceur-runtime.js'},
{src: '/js/es6-module-loader-sans-promises.src.js'},
{src: '/js/extension-register.js'},
{src: 'register_system.js'},
{src: 'benchmark.js'}
]
});
};

View File

@ -0,0 +1 @@
$SCRIPTS$

View File

@ -0,0 +1,19 @@
import * as instantiate_benchmark from './instantiate_benchmark';
import * as instantiate_directive_benchmark from './instantiate_directive_benchmark';
import * as instantiate_benchmark_codegen from './instantiate_benchmark_codegen';
import {benchmark, benchmarkStep} from 'benchpress/benchpress';
export function main() {
benchmark(`ElementInjector.instantiate + instantiateDirectives`, function() {
benchmarkStep('run', instantiate_benchmark.run);
});
benchmark(`ElementInjector.instantiateDirectives`, function() {
benchmarkStep('run', instantiate_directive_benchmark.run);
});
benchmark(`ElementInjector.instantiate + instantiateDirectives (codegen)`, function() {
benchmarkStep('run', instantiate_benchmark_codegen.run);
});
}

View File

@ -1,11 +0,0 @@
System.paths = {
'core/*': '/js/core/lib/*.js',
'change_detection/*': '/js/change_detection/lib/*.js',
'facade/*': '/js/facade/lib/*.js',
'di/*': '/js/di/lib/*.js',
'rtts_assert/*': '/js/rtts_assert/lib/*.js',
'test_lib/*': '/js/test_lib/lib/*.js',
'benchmarks/*': '/js/benchmarks/lib/*.js',
'reflection/*': '/js/reflection/lib/*.js'
};
register(System);

View File

@ -3,3 +3,5 @@ environment:
sdk: '>=1.4.0'
dependencies:
angular: ">=1.0.0 <2.0.0"
benchpress:
path: ../benchpress

View File

@ -1,63 +0,0 @@
library benchmarks.benchpress;
import 'dart:js' as js;
import 'dart:html';
import 'dart:async';
// TODO: move the functionality of this module into benchpress and replace this
// file with a Dart wrapper!
var _benchmarkNames = [];
_benchmarkId(index) {
return "benchmark${index}";
}
_useBenchmark(index) {
var search = window.location.search;
if (search.length > 0) {
search = search.substring(1);
}
if (search.length > 0) {
return search == _benchmarkId(index);
} else {
return true;
}
}
_onLoad(callback) {
var isReady = document.readyState == 'complete';
if (isReady) {
Timer.run(callback);
} else {
window.addEventListener('load', (event) => callback(), false);
}
}
_createBenchmarkMenu() {
var div = document.createElement('div');
div.innerHtml += '<h1>Benchmarks:</h1><a class="btn btn-default" href="?">All</a>';
for (var i=0; i<_benchmarkNames.length; i++) {
var activeClass = _useBenchmark(i) ? 'active' : '';
div.innerHtml += '<a class="btn btn-default ${activeClass}" href="?${_benchmarkId(i)}">${_benchmarkNames[i]}</a>';
}
document.body.insertBefore(div, document.body.childNodes[0]);
}
benchmark(name, stepsCreationCallback) {
_benchmarkNames.add(name);
if (_benchmarkNames.length == 2) {
_onLoad(_createBenchmarkMenu);
}
if (_useBenchmark(_benchmarkNames.length-1)) {
stepsCreationCallback();
}
}
benchmarkStep(name, callback) {
var benchmarkName = _benchmarkNames[_benchmarkNames.length-1];
js.context['benchmarkSteps'].add(new js.JsObject.jsify({
"name": benchmarkName + '#' + name,
"fn": new js.JsFunction.withThis((_) => callback())
}));
}

View File

@ -1,55 +0,0 @@
// TODO: move the functionality of this module into benchpress itself!
var benchmarkNames = [];
function benchmarkId(index) {
return 'benchmark' + index;
}
function useBenchmark(index) {
var search = window.location.search;
if (search.length > 0) {
search = search.substring(1);
}
if (search.length > 0) {
return search == benchmarkId(index);
} else {
return true;
}
}
function onLoad(callback) {
var isReady = document.readyState === 'complete';
if (isReady) {
window.setTimeout(callback);
} else {
window.addEventListener('load', callback, false);
}
}
function createBenchmarkMenu() {
var div = document.createElement('div');
div.innerHTML += '<h1>Benchmarks:</h1><a class="btn btn-default" href="?">All</a>';
for (var i=0; i<benchmarkNames.length; i++) {
var activeClass = useBenchmark(i) ? 'active' : '';
div.innerHTML += ('<a class="btn btn-default '+activeClass+'" href="?'+benchmarkId(i)+'">'+benchmarkNames[i]+'</a>');
}
document.body.insertBefore(div, document.body.childNodes[0]);
}
export function benchmark(name, stepsCreationCallback) {
benchmarkNames.push(name);
if (benchmarkNames.length === 2) {
onLoad(createBenchmarkMenu);
}
if (useBenchmark(benchmarkNames.length-1)) {
stepsCreationCallback();
}
}
export function benchmarkStep(name, callback) {
var benchmarkName = benchmarkNames[benchmarkNames.length-1];
window.benchmarkSteps.push({
name: benchmarkName + '#' + name, fn: callback
});
}

View File

@ -1,7 +0,0 @@
Promise.all([
System.import('benchmarks_external/compiler/compiler_benchmark_ng13')
]).then(function (benchmarks) {
benchmarks.forEach(function(bm) {
bm.main();
});
}, console.log.bind(console));

View File

@ -1,12 +0,0 @@
module.exports = function(config) {
config.set({
scripts: [
{src: '/js/traceur-runtime.js'},
{src: '/js/es6-module-loader-sans-promises.src.js'},
{src: '/js/extension-register.js'},
{src: 'register_system.js'},
{src: 'https://ajax.googleapis.com/ajax/libs/angularjs/1.3.2/angular.js'},
{src: 'benchmark.js'}
]
});
};

View File

@ -1,6 +1,6 @@
import 'package:angular/angular.dart';
import 'package:angular/application_factory_static.dart';
import '../benchpress.dart';
import 'package:benchpress/benchpress.dart';
import 'dart:html';
var COUNT = 30;

View File

@ -1,4 +1,4 @@
import {benchmark, benchmarkStep} from '../benchpress';
import {benchmark, benchmarkStep} from 'benchpress/benchpress';
var COUNT = 30;
var $compile;

View File

@ -0,0 +1 @@
export {main} from './compiler_benchmark_ng13';

View File

@ -1,3 +1,5 @@
$SCRIPTS$
<template id="templateNoBindings">
<div class="class0 class1 class2 class3 class4 " nodir0="" attr0="value0" nodir1="" attr1="value1" nodir2="" attr2="value2" nodir3="" attr3="value3" nodir4="" attr4="value4">
<div class="class0 class1 class2 class3 class4 " nodir0="" attr0="value0" nodir1="" attr1="value1" nodir2="" attr2="value2" nodir3="" attr3="value3" nodir4="" attr4="value4">

View File

@ -1,11 +0,0 @@
System.paths = {
'core/*': '/js/core/lib/*.js',
'change_detection/*': '/js/change_detection/lib/*.js',
'facade/*': '/js/facade/lib/*.js',
'di/*': '/js/di/lib/*.js',
'rtts_assert/*': '/js/rtts_assert/lib/*.js',
'test_lib/*': '/js/test_lib/lib/*.js',
'benchmarks_external/*': '/js/benchmarks_external/lib/*.js',
'reflection/*': '/js/reflection/lib/*.js'
};
register(System);

View File

@ -0,0 +1,4 @@
name: benchpress
environment:
sdk: '>=1.4.0'
dependencies:

View File

@ -1,23 +1,11 @@
<!doctype html>
<html>
<title>Hello Angular 2.0 (JS)</title>
<title>Hello Angular 2.0 (Reflection)</title>
<body>
<hello-app>
Loading...
</hello-app>
<script src="../../../traceur-runtime.js"></script>
<script src="../../../rtts_assert/lib/rtts_assert.js"></script>
<script src="../../../es6-module-loader-sans-promises.src.js"></script>
<script src="../../../system.src.js"></script>
<script src="../../../extension-register.js"></script>
<script src="main.js"></script>
$SCRIPTS$
</body>
</html>
<!-- to run do:
1) gulp build
2) gulp serve
3) open localhost:8000/js/examples/lib/hello_world/ in chrome.
TODO(rado): merge with Darts's index.html in ../../web/
-->

View File

@ -0,0 +1,11 @@
<!doctype html>
<html>
<title>Hello Angular 2.0 (Static)</title>
<body>
<hello-app>
Loading...
</hello-app>
$SCRIPTS$
</body>
</html>

View File

@ -1,4 +1,4 @@
import * as app from './app';
import * as app from './index';
import {Component, Decorator, TemplateConfig, NgElement} from 'core/core';
import {Parser} from 'change_detection/parser/parser';

View File

@ -1,23 +0,0 @@
register(System);
System.baseURL = '../../../';
// So that we can import packages like `core/foo`, instead of `core/lib/foo`.
System.paths = {
'core/*': './core/lib/*.js',
'change_detection/*': './change_detection/lib/*.js',
'facade/*': './facade/lib/*.js',
'di/*': './di/lib/*.js',
'reflection/*': './reflection/lib/*.js',
'rtts_assert/*': './rtts_assert/lib/*.js',
'examples/*': './examples/lib/*.js'
};
// TODO(rado): templatize and make reusable for all examples
System.import('examples/hello_world/app').then(function(m) {
m.main();
}, function(e) {
console.error(e.stack || e);
});

View File

@ -1,20 +0,0 @@
<!doctype html>
<html>
<head>
<title>Hello Angular 2.0 (Dart)</title>
<script type="application/dart" src="main.dart"></script>
<script src="packages/browser/dart.js"></script>
</head>
<body>
<hello-app>
Loading...
</hello-app>
</body>
</html>
<!-- to run do:
1) gulp build
2) gulp examples/pub.serve
3) open localhost:8080 in dartium or chrome.
TODO(rado): merge with JS's index.html in ../src/hello_world/
-->

View File

@ -1,20 +0,0 @@
<!doctype html>
<html>
<head>
<title>Hello Angular 2.0 (Dart Static)</title>
<script type="application/dart" src="main_static.dart"></script>
<script src="packages/browser/dart.js"></script>
</head>
<body>
<hello-app>
Loading...
</hello-app>
</body>
</html>
<!-- to run do:
1) gulp build
2) gulp examples/pub.serve
3) open localhost:8080/index_static.html in dartium or chrome.
TODO(rado): merge with JS's index.html in ../src/hello_world/
-->

View File

@ -1,11 +0,0 @@
import 'package:examples/hello_world/app.dart' as HelloWorldApp;
import 'package:reflection/reflection_capabilities.dart';
import 'package:reflection/reflection.dart';
// TODO(rado): templatize and make reusable for all examples.
main() {
// enable mirrors and reflection.
// see static_app.js for an example of a static app.
reflector.reflectionCapabilities = new ReflectionCapabilities();
HelloWorldApp.main();
}

View File

@ -1,4 +0,0 @@
import 'packages/examples/hello_world/static_app.dart' as HelloWorldApp;
// TODO(rado): templatize and make reusable for all examples.
main() => HelloWorldApp.main();

View File

@ -1,12 +0,0 @@
/**
* This is a special facade used to bootstrap JS automatically.
* (In contrast to door wheere the user needs to explicitly call into angular.)
* This file is appened to AngularJS and needs to be written in ES5.
*/
(function(window, document) {
document.addEventListener('DOMContentLoaded', bootstrap, false);
function bootstrap() {
// TODO(misko): load application factory from the module system.
applicationFactory().run();
}
})(window, document);

View File

@ -40,6 +40,8 @@
"gulp-rename": "^1.2.0",
"gulp-shell": "^0.2.10",
"gulp-webserver": "^0.8.7",
"angular": "1.3.5",
"minimatch": "^2.0.1",
"lodash": "^2.4.1"
}
}

View File

@ -2,18 +2,6 @@ name: angular
environment:
sdk: '>=1.4.0'
dependencies:
examples:
path: build/dart/examples
test_lib:
path: build/dart/test_lib
facade:
path: build/dart/facade
core:
path: build/dart/core
di:
path: build/dart/di
change_detection:
path: build/dart/change_detection
dev_dependencies:
guinness: ">=0.1.16 <0.2.0"

View File

@ -8,10 +8,6 @@ SCRIPT_DIR=$(dirname $0)
cd $SCRIPT_DIR/../..
source ./scripts/env.sh
# For some reason, this task fails on Travis when run as a part of the `gulp build`.
# It runs `pub get` which fails to read the `pubspec.yml` (created earlier by the task).
./node_modules/.bin/gulp modules/build.dart/pubspec
./node_modules/.bin/gulp build
pub install

39
tools/build/benchpress.js Normal file
View File

@ -0,0 +1,39 @@
var util = require('./util');
var path = require('path');
var benchpress = require('angular-benchpress/lib/cli');
var through2 = require('through2');
var Q = require('q');
var path = require('path');
module.exports = function(gulp, plugins, config) {
return function() {
var benchmarkParentFolders = {};
var createBpConfStream = util.streamToPromise(
gulp.src(path.join(config.buildDir, config.mainHtmls))
.pipe(through2.obj(function(file, enc, done) {
file.path = path.join(path.dirname(file.path), config.configFile.name);
file.contents = new Buffer(config.configFile.content);
this.push(file);
benchmarkParentFolders[getParentFolder(file.path)] = true;
done();
}))
.pipe(gulp.dest(config.buildDir)));
return createBpConfStream.then(function() {
return Promise.all(Object.keys(benchmarkParentFolders).map(function(benchmarkParentPath) {
var defer = Q.defer();
benchpress.build({
benchmarksPath: benchmarkParentPath,
buildPath: path.join(benchmarkParentPath, path.join('../', config.outputFolderName))
}, defer.makeNodeResolver());
return defer.promise;
}));
});
};
};
function getParentFolder(file) {
var parts = path.dirname(file).split(path.sep);
parts.pop();
return parts.join(path.sep);
}

8
tools/build/clean.js Normal file
View File

@ -0,0 +1,8 @@
var del = require('del');
module.exports = function(gulp, plugins, config) {
return function(done) {
del(config.path, done);
};
};

View File

@ -0,0 +1,70 @@
var Q = require('q');
var readline = require('readline');
var spawn = require('child_process').spawn;
var path = require('path');
var glob = require('glob');
var fs = require('fs');
var util = require('./util');
module.exports = function(gulp, plugins, config) {
return function() {
var dartModuleFolders = [].slice.call(glob.sync(config.dest + '/*'));
var tempFile = '_analyzer.dart';
// analyze in parallel!
return Q.all(dartModuleFolders.map(function(dir) {
var srcFiles = [].slice.call(glob.sync(util.filterByFile(config.srcFolderMapping, dir) + '/**/*.dart', {
cwd: dir
}));
var testFiles = [].slice.call(glob.sync('test/**/*_spec.dart', {
cwd: dir
}));
var analyzeFile = ['library _analyzer;'];
srcFiles.concat(testFiles).forEach(function(fileName, index) {
if (fileName !== tempFile) {
analyzeFile.push('import "./'+fileName+'" as mod'+index+';');
}
});
fs.writeFileSync(path.join(dir, tempFile), analyzeFile.join('\n'));
var defer = Q.defer();
analyze(dir, defer.makeNodeResolver());
return defer.promise;
}));
function analyze(dirName, done) {
var stream = spawn(config.command, ['--fatal-warnings', tempFile], {
// inherit stdin and stderr, but filter stdout
stdio: [process.stdin, 'pipe', process.stderr],
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.stdout,
output: process.stdout,
terminal: false
});
var hintCount = 0;
rl.on('line', function(line) {
if (line.match(/Unused import/)) {
return;
}
if (line.match(/\[hint\]/)) {
hintCount++;
}
console.log(dirName + ':' + line);
});
stream.on('close', function(code) {
var error;
if (code !== 0) {
error = new Error('Dartanalyzer failed with exit code ' + code);
}
if (hintCount > 0) {
error = new Error('Dartanalyzer showed hints');
}
done(error);
});
}
};
};

33
tools/build/dartdetect.js Normal file
View File

@ -0,0 +1,33 @@
var which = require('which');
module.exports = function(gulp) {
var DART_SDK = false;
try {
which.sync('dart');
console.log('Dart SDK detected');
if (process.platform === 'win32') {
DART_SDK = {
PUB: 'pub.bat',
ANALYZER: 'dartanalyzer.bat'
};
} else {
DART_SDK = {
PUB: 'pub',
ANALYZER: 'dartanalyzer'
};
}
} catch (e) {
console.log('Dart SDK is not available, Dart tasks will be skipped.');
var gulpTaskFn = gulp.task.bind(gulp);
gulp.task = function (name, deps, fn) {
if (name.indexOf('.dart') === -1) {
return gulpTaskFn(name, deps, fn);
} else {
return gulpTaskFn(name, function() {
console.log('Dart SDK is not available. Skipping task: ' + name);
});
}
};
}
return DART_SDK;
}

8
tools/build/deps.js Normal file
View File

@ -0,0 +1,8 @@
var path = require('path');
module.exports = function(gulp, plugins, config) {
return function() {
return gulp.src(config.src)
.pipe(gulp.dest(path.join(config.dest, 'deps')));
};
};

View File

@ -5,6 +5,8 @@ function file2moduleName(filePath) {
.replace(/.*\/tools\//, '')
// module name should not include `src`, `test`, `lib`
.replace(/\/src\//, '/')
.replace(/\/web\//, '/')
.replace(/\/perf_tmp\//, '/')
.replace(/\/lib\//, '/')
// module name should not have a suffix
.replace(/\.\w*$/, '');

32
tools/build/html.js Normal file
View File

@ -0,0 +1,32 @@
var util = require('./util');
var file2moduleName = require('./file2modulename');
var through2 = require('through2');
var path = require('path');
module.exports = function(gulp, plugins, config) {
return function() {
return gulp.src(config.src)
.pipe(util.renameSrcFolder(plugins, config.srcFolderMapping))
.pipe(through2.obj(function(file, enc, done) {
var fileName = file.relative;
var moduleName = file2moduleName(fileName);
var moduleNameWithoutPath = path.basename(moduleName);
var scripts = util.filterByFile(config.scriptsPerFolder, fileName).map(function(script) {
var scriptTag;
if (script.src) {
scriptTag = '<script src="'+script.src+'" type="'+script.mimeType+'"></script>';
} else {
scriptTag = '<script type="'+script.mimeType+'">'+script.inline+'</script>';
}
return scriptTag
.replace('$MODULENAME_WITHOUT_PATH$', moduleNameWithoutPath)
.replace('$MODULENAME$', moduleName)
}).join('\n');
file.contents = new Buffer(file.contents.toString().replace('$SCRIPTS$', scripts));
this.push(file);
done();
}))
.pipe(gulp.dest(config.dest));
};
};

10
tools/build/jsserve.js Normal file
View File

@ -0,0 +1,10 @@
module.exports = function(gulp, plugins, config) {
return function() {
plugins.connect.server({
root: [__dirname+'/../../'+config.path],
port: 8000,
livereload: false,
open: false
})();
};
};

11
tools/build/pubserve.js Normal file
View File

@ -0,0 +1,11 @@
var util = require('./util');
var spawn = require('child_process').spawn;
module.exports = function(gulp, plugins, config, module) {
return function() {
return util.streamToPromise(spawn(config.command, ['serve'], {
cwd: config.path, stdio: 'inherit'
}));
};
};

37
tools/build/pubspec.js Normal file
View File

@ -0,0 +1,37 @@
var util = require('./util');
var Q = require('q');
var spawn = require('child_process').spawn;
var through2 = require('through2');
var path = require('path');
module.exports = function(gulp, plugins, config) {
return function() {
var files = [];
var pubSpecCopy = util.streamToPromise(gulp.src(config.src)
.pipe(plugins.changed(config.dest)) // Only forward files that changed.
.pipe(through2.obj(function(file, enc, done) {
files.push(path.resolve(process.cwd(), config.dest, file.relative));
this.push(file);
done();
}))
.pipe(gulp.dest(config.dest)));
// We need to wait for all pubspecs to be present before executing
// `pub get` as it checks the folders of the dependencies!
// We need to execute pubspec serially as otherwise we can get into trouble
// with the pub cache...
return pubSpecCopy.then(nextFile);
function nextFile() {
if (!files.length) {
return;
}
var file = files.shift();
return util.processToPromise(spawn(config.command, ['get'], {
stdio: 'inherit',
cwd: path.dirname(file)
})).then(nextFile);
}
};
};

View File

@ -0,0 +1,14 @@
System.paths = {
'core/*': '/core/lib/*.js',
'change_detection/*': '/change_detection/lib/*.js',
'facade/*': '/facade/lib/*.js',
'di/*': '/di/lib/*.js',
'rtts_assert/*': '/rtts_assert/lib/*.js',
'test_lib/*': '/test_lib/lib/*.js',
'reflection/*': '/reflection/lib/*.js',
'benchpress/*': '/benchpress/lib/*.js',
'examples/*': '/examples/web/*.js',
'benchmarks/*': '/benchmarks/web/*.js',
'benchmarks_external/*': '/benchmarks_external/web/*.js',
};
register(System);

24
tools/build/transpile.js Normal file
View File

@ -0,0 +1,24 @@
var util = require('./util');
var gulpTraceur = require('../transpiler/gulp-traceur');
var file2moduleName = require('./file2modulename');
var mergeStreams = require('event-stream').merge;
module.exports = function(gulp, plugins, config) {
return function() {
var transpile = gulp.src(config.src)
.pipe(plugins.rename({extname: '.'+config.outputExt}))
.pipe(util.renameSrcFolder(plugins, config.srcFolderMapping))
.pipe(gulpTraceur(
config.options,
file2moduleName)
)
.pipe(gulp.dest(config.dest));
var copy = gulp.src(config.copy)
.pipe(plugins.rename({extname: '.'+config.outputExt}))
.pipe(util.renameSrcFolder(plugins, config.srcFolderMapping))
.pipe(gulp.dest(config.dest));
return mergeStreams(transpile, copy);
};
};

45
tools/build/util.js Normal file
View File

@ -0,0 +1,45 @@
var Q = require('q');
var minimatch = require('minimatch');
module.exports = {
processToPromise: processToPromise,
streamToPromise: streamToPromise,
renameSrcFolder: renameSrcFolder,
filterByFile: filterByFile
};
function filterByFile(valuesWithPatterns, fileName) {
var match = null;
for (var pattern in valuesWithPatterns) {
if (pattern !== 'default' && minimatch(fileName, pattern)) {
match = valuesWithPatterns[pattern];
}
}
return match || valuesWithPatterns['default'];
}
function processToPromise(process) {
var defer = Q.defer();
process.on('close', function(code) {
if (code) {
defer.reject(code);
} else {
defer.resolve();
}
});
return defer.promise;
}
function streamToPromise(stream) {
var defer = Q.defer();
stream.on('end', defer.resolve);
stream.on('error', defer.reject);
return defer.promise;
}
function renameSrcFolder(plugins, srcFolderMapping) {
return plugins.rename(function(file) {
var srcOutputFolder = filterByFile(srcFolderMapping, file.dirname);
file.dirname = file.dirname.replace(/\bsrc\b/, srcOutputFolder);
});
}