337 lines
9.2 KiB
JavaScript
337 lines
9.2 KiB
JavaScript
var benchpress = require('angular-benchpress/lib/cli');
|
|
var clean = require('gulp-rimraf');
|
|
var connect = require('gulp-connect');
|
|
var ejs = require('gulp-ejs');
|
|
var es = require('event-stream');
|
|
var file2moduleName = require('./file2modulename');
|
|
var fs = require('fs');
|
|
var glob = require('glob');
|
|
var gulp = require('gulp');
|
|
var merge = require('merge');
|
|
var mergeStreams = require('event-stream').merge;
|
|
var path = require('path');
|
|
var Q = require('q');
|
|
var readline = require('readline');
|
|
var rename = require('gulp-rename');
|
|
var runSequence = require('run-sequence');
|
|
var shell = require('gulp-shell');
|
|
var spawn = require('child_process').spawn;
|
|
var through2 = require('through2');
|
|
var watch = require('gulp-watch');
|
|
var changed = require('gulp-changed');
|
|
|
|
var js2es5Options = {
|
|
sourceMaps: true,
|
|
annotations: true, // parse annotations
|
|
types: true, // parse types
|
|
script: false, // parse as a module
|
|
memberVariables: true, // parse class fields
|
|
modules: 'instantiate'
|
|
};
|
|
|
|
var js2es5OptionsProd = merge(true, js2es5Options, {
|
|
typeAssertions: false
|
|
});
|
|
|
|
var js2es5OptionsDev = merge(true, js2es5Options, {
|
|
typeAssertionModule: 'rtts_assert/rtts_assert',
|
|
typeAssertions: true
|
|
});
|
|
|
|
var js2dartOptions = {
|
|
sourceMaps: true,
|
|
annotations: true, // parse annotations
|
|
types: true, // parse types
|
|
script: false, // parse as a module
|
|
memberVariables: true, // parse class fields
|
|
outputLanguage: 'dart'
|
|
};
|
|
|
|
var PUB_CMD = process.platform === 'win32' ? 'pub.bat' : 'pub';
|
|
|
|
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'],
|
|
htmlSrc: ['modules/*/src/**/*.html'],
|
|
copySrc: ['modules/**/*.dart'],
|
|
outputDir: 'build/dart',
|
|
outputExt: 'dart',
|
|
mimeType: 'application/dart'
|
|
},
|
|
js: {
|
|
transpileSrc: ['modules/**/*.js', 'modules/**/*.es6'],
|
|
htmlSrc: ['modules/*/src/**/*.html'],
|
|
copySrc: ['modules/**/*.es5'],
|
|
outputDir: 'build/js',
|
|
outputExt: 'js'
|
|
}
|
|
};
|
|
|
|
|
|
gulp.task('modules/clean', function() {
|
|
return gulp.src('build', {read: false})
|
|
.pipe(clean());
|
|
});
|
|
|
|
gulp.task('modules/build.dart/src', function() {
|
|
return createModuleTask(merge(sourceTypeConfigs.dart, {compilerOptions: js2dartOptions}));
|
|
});
|
|
|
|
gulp.task('modules/build.dart/pubspec', function(done) {
|
|
var outputDir = sourceTypeConfigs.dart.outputDir;
|
|
return gulp.src('modules/*/pubspec.yaml')
|
|
.pipe(changed(outputDir)) // Only forward files that changed.
|
|
.pipe(gulpDestWithForward(outputDir))
|
|
.pipe(through2.obj(function(file, enc, done) {
|
|
// After a `pubspec.yml` is copied, we run `pub install`.
|
|
spawn(PUB_CMD, ['get'], {
|
|
stdio: [process.stdin, process.stdout, process.stderr],
|
|
cwd: path.dirname(file.path)
|
|
}).on('close', done);
|
|
}));
|
|
});
|
|
|
|
gulp.task('modules/build.dart', ['modules/build.dart/src', 'modules/build.dart/pubspec']);
|
|
|
|
gulp.task('modules/build.dev.js', function() {
|
|
return createModuleTask(merge(true, sourceTypeConfigs.js, {compilerOptions: js2es5OptionsDev}));
|
|
});
|
|
|
|
gulp.task('modules/build.prod.js', function() {
|
|
return createModuleTask(merge(true, sourceTypeConfigs.js, {compilerOptions: js2es5OptionsProd}));
|
|
});
|
|
|
|
function renameSrcToLib(file) {
|
|
file.dirname = file.dirname.replace(/\bsrc\b/, 'lib');
|
|
}
|
|
|
|
function renameEs5ToJs(file) {
|
|
if (file.extname == '.es5') {
|
|
file.extname = '.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));
|
|
|
|
return mergeStreams(transpile, copy, html);
|
|
}
|
|
|
|
|
|
// Act as `gulp.dest()` but does forward the files to the next stream.
|
|
// I believe this is how `gulp.dest` should work.
|
|
function gulpDestWithForward(destDir) {
|
|
var stream = gulp.dest(destDir);
|
|
var originalTransform = stream._transform;
|
|
|
|
stream._transform = function(file, enc, done) {
|
|
return originalTransform.call(this, file, enc, function() {
|
|
stream.push(file);
|
|
done();
|
|
});
|
|
};
|
|
|
|
return stream;
|
|
}
|
|
|
|
// ------------------
|
|
// ANALYZE
|
|
|
|
gulp.task('analyze/dartanalyzer', 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;
|
|
}));
|
|
|
|
function analyze(dirName, done) {
|
|
var dartanalyzerCmd = (process.platform === "win32" ? "dartanalyzer.bat" : "dartanalyzer");
|
|
var stream = spawn(dartanalyzerCmd, ['--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 .*_analyzer\.dart/)) {
|
|
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);
|
|
});
|
|
}
|
|
});
|
|
|
|
|
|
|
|
// ------------------
|
|
// BENCHMARKS JS
|
|
|
|
gulp.task('benchmarks/build.benchpress.js', function () {
|
|
benchpress.build({
|
|
benchmarksPath: 'build/js/benchmarks/lib',
|
|
buildPath: 'build/benchpress/js'
|
|
})
|
|
});
|
|
|
|
gulp.task('benchmarks/build.js', function() {
|
|
runSequence(
|
|
['jsRuntime/build', 'modules/build.prod.js'],
|
|
'benchmarks/build.benchpress.js'
|
|
);
|
|
});
|
|
|
|
|
|
// ------------------
|
|
// BENCHMARKS DART
|
|
|
|
gulp.task('benchmarks/build.dart2js.dart', function () {
|
|
return gulp.src([
|
|
"build/dart/benchmarks/lib/**/benchmark.dart"
|
|
]).pipe(shell(['dart2js --package-root="build/dart/benchmarks/packages" -o "<%= file.path %>.js" <%= file.path %>']));
|
|
});
|
|
|
|
gulp.task('benchmarks/create-bpconf.dart', function () {
|
|
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([
|
|
"build/dart/benchmarks/lib/**/benchmark.dart"
|
|
]).pipe(createBpConfJs);
|
|
});
|
|
|
|
gulp.task('benchmarks/build.benchpress.dart', function () {
|
|
benchpress.build({
|
|
benchmarksPath: 'build/dart/benchmarks/lib',
|
|
buildPath: 'build/benchpress/dart'
|
|
})
|
|
});
|
|
|
|
gulp.task('benchmarks/build.dart', function() {
|
|
runSequence(
|
|
'modules/build.dart',
|
|
'benchmarks/build.dart2js.dart',
|
|
'benchmarks/create-bpconf.dart',
|
|
'benchmarks/build.benchpress.dart'
|
|
);
|
|
});
|
|
|
|
|
|
|
|
// ------------------
|
|
// WEB SERVER
|
|
|
|
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();
|
|
}];
|
|
}
|
|
})();
|
|
});
|
|
|
|
|
|
|
|
// --------------
|
|
// 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/dartanalyzer'
|
|
);
|
|
});
|
|
|
|
gulp.task('analyze', function(done) {
|
|
runSequence('analyze/dartanalyzer');
|
|
});
|