feat(build): Use broccoli for ts2dart transpilation.

This commit is contained in:
Martin Probst 2015-04-10 14:30:35 -07:00
parent 7b790a3369
commit a3decad4c2
7 changed files with 121 additions and 10 deletions

43
Brocfile-dart.js Normal file
View File

@ -0,0 +1,43 @@
// Brocfile to transpile sources from TypeScript to Dart using ts2dart.
var Funnel = require('broccoli-funnel');
var stew = require('broccoli-stew');
var ts2dart = require('./dist/broccoli/broccoli-ts2dart');
var path = require('path');
// Transpile everything in 'modules'...
var modulesTree = new Funnel('modules', {
include: ['**/*.js', '**/*.ts', '**/*.dart'], // .dart file available means don't translate.
exclude: ['rtts_assert/**/*'], // ... except for the rtts_asserts (don't apply to Dart).
destDir: '/', // Remove the 'modules' prefix.
});
// Transpile to dart.
var dartTree = ts2dart.transpile(modulesTree);
// Move around files to match Dart's layout expectations.
dartTree = stew.rename(dartTree, function(relativePath) {
// If a file matches the `pattern`, insert the given `insertion` as the second path part.
var replacements = [
{pattern: /^benchmarks\/test\//, insertion: ''},
{pattern: /^benchmarks\//, insertion: 'web'},
{pattern: /^benchmarks_external\/test\//, insertion: ''},
{pattern: /^benchmarks_external\//, insertion: 'web'},
{pattern: /^example.?\//, insertion: 'web/'},
{pattern: /^example.?\/test\//, insertion: ''},
{pattern: /^[^\/]*\/test\//, insertion: ''},
{pattern: /^./, insertion: 'lib'}, // catch all.
];
for (var i = 0; i < replacements.length; i++) {
var repl = replacements[i];
if (relativePath.match(repl.pattern)) {
var parts = relativePath.split('/');
parts.splice(1, 0, repl.insertion);
return path.join.apply(path, parts);
}
}
throw new Error('Failed to match any path', relativePath);
});
// Move the tree under the 'dart' folder.
module.exports = stew.mv(dartTree, 'dart');

View File

@ -29,7 +29,6 @@ var runServerDartTests = require('./tools/build/run_server_dart_tests');
var sourcemaps = require('gulp-sourcemaps'); var sourcemaps = require('gulp-sourcemaps');
var transformCJSTests = require('./tools/build/transformCJSTests'); var transformCJSTests = require('./tools/build/transformCJSTests');
var tsc = require('gulp-typescript'); var tsc = require('gulp-typescript');
var ts2dart = require('gulp-ts2dart');
var util = require('./tools/build/util'); var util = require('./tools/build/util');
var bundler = require('./tools/build/bundle'); var bundler = require('./tools/build/bundle');
var replace = require('gulp-replace'); var replace = require('gulp-replace');
@ -373,11 +372,8 @@ gulp.task('build/transformCJSTests', function() {
.pipe(gulp.dest(CONFIG.dest.js.cjs + '/angular2/test/')); .pipe(gulp.dest(CONFIG.dest.js.cjs + '/angular2/test/'));
}); });
gulp.task('build/transpile.dart', function() { gulp.task('build/transpile.dart', ['build.broccoli.tools'], function() {
return gulp.src(CONFIG.transpile.src.dart) return broccoliBuild(require('./Brocfile-dart.js'), 'dart');
.pipe(ts2dart.transpile())
.pipe(util.insertSrcFolder(gulpPlugins, CONFIG.srcFolderInsertion.dart))
.pipe(gulp.dest(CONFIG.dest.dart));
}); });
// ------------ // ------------
@ -720,7 +716,8 @@ gulp.task('test.transpiler.unittest', function() {
// Builds all Dart packages, but does not compile them // Builds all Dart packages, but does not compile them
gulp.task('build/packages.dart', function(done) { gulp.task('build/packages.dart', function(done) {
runSequence( runSequence(
['build/transpile.dart', 'build/html.dart', 'build/copy.dart', 'build/multicopy.dart'], 'build/transpile.dart', // Creates the folder structure needed by subsequent tasks.
['build/html.dart', 'build/copy.dart', 'build/multicopy.dart'],
'build/format.dart', 'build/format.dart',
'build/pubspec.dart', 'build/pubspec.dart',
done done

View File

@ -0,0 +1,2 @@
// Globals are provided by lang.dart in Dart.
// This file exists to prevent global.ts from being transpiled.

View File

@ -72,7 +72,6 @@
"gulp-sourcemaps": "1.3.*", "gulp-sourcemaps": "1.3.*",
"gulp-template": "^3.0.0", "gulp-template": "^3.0.0",
"gulp-traceur": "0.17.*", "gulp-traceur": "0.17.*",
"gulp-ts2dart": "^1.0.6",
"gulp-typescript": "ivogabe/gulp-typescript#3422fbff06532ccc57368f3b4c8801de8f72ef27", "gulp-typescript": "ivogabe/gulp-typescript#3422fbff06532ccc57368f3b4c8801de8f72ef27",
"gulp-webserver": "^0.8.7", "gulp-webserver": "^0.8.7",
"js-yaml": "^3.2.7", "js-yaml": "^3.2.7",
@ -97,7 +96,7 @@
"ternary-stream": "^1.2.3", "ternary-stream": "^1.2.3",
"through2": "^0.6.1", "through2": "^0.6.1",
"typescript": "alexeagle/TypeScript#93dbbe2a2d0b42cefd02ac949e4bc8ab6b5b5823", "typescript": "alexeagle/TypeScript#93dbbe2a2d0b42cefd02ac949e4bc8ab6b5b5823",
"ts2dart": "^0.2.0", "ts2dart": "^0.3.0",
"vinyl": "^0.4.6", "vinyl": "^0.4.6",
"walk-sync": "^0.1.3", "walk-sync": "^0.1.3",
"xtend": "^4.0.0", "xtend": "^4.0.0",

View File

@ -0,0 +1,56 @@
/// <reference path="./broccoli-writer.d.ts" />
/// <reference path="../typings/node/node.d.ts" />
/// <reference path="../typings/fs-extra/fs-extra.d.ts" />
import Writer = require('broccoli-writer');
import fs = require('fs');
import fse = require('fs-extra');
import path = require('path');
import ts2dart = require('ts2dart');
type Set = {
[s:string]: boolean
};
class TypeScriptToDartTranspiler extends Writer {
constructor(private inputTree, private includePattern = /\.(js|ts)$/) { super(); }
write(readTree, destDir): Promise<void> {
return readTree(this.inputTree).then(dir => this.transpile(dir, destDir));
}
private transpile(inputDir: string, destDir: string) {
var files = this.listRecursive(inputDir);
var toTranspile = [];
for (var f in files) {
// If it's not matching, don't translate.
if (!f.match(this.includePattern)) continue;
var dartVariant = f.replace(this.includePattern, '.dart');
// A .dart file of the same name takes precedence over transpiled code.
if (files.hasOwnProperty(dartVariant)) continue;
toTranspile.push(f);
}
var transpiler = new ts2dart.Transpiler(
{generateLibraryName: true, generateSourceMap: false, basePath: inputDir});
transpiler.transpile(toTranspile, destDir);
}
private listRecursive(root: string, res: Set = {}): Set {
var paths = fs.readdirSync(root);
paths.forEach((p) => {
p = path.join(root, p);
var stat = fs.statSync(p);
if (stat.isDirectory()) {
this.listRecursive(p, res);
} else {
// Collect *all* files so we can check .dart files that already exist and exclude them.
res[p] = true;
}
});
return res;
}
}
export function transpile(inputTree) {
return new TypeScriptToDartTranspiler(inputTree);
}

View File

@ -2,7 +2,7 @@
declare class Writer { declare class Writer {
write(readTree: (tree) => Promise<string>, destDir: string); write(readTree: (tree) => Promise<string>, destDir: string): Promise<any>;
} }
export = Writer; export = Writer;

14
tools/broccoli/ts2dart.d.ts vendored Normal file
View File

@ -0,0 +1,14 @@
// TODO(martinprobst): This is a hand-written declarations file. Replace with an automatically
// generated one when TypeScript has a strategy to distribute TS source via npm.
export interface TranspilerOptions {
failFast?: boolean;
generateLibraryName?: boolean;
generateSourceMap?: boolean;
basePath?: string;
}
export class Transpiler{
constructor(options: TranspilerOptions);
transpile(fileNames: string[], outdir?: string);
}