diff --git a/gulpfile.js b/gulpfile.js index 69e62b7bdb..8a9417d1dd 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -1,5 +1,3 @@ -var broccoliBuild = require('./tools/broccoli/gulp'); - var format = require('gulp-clang-format'); var gulp = require('gulp'); var gulpPlugins = require('gulp-load-plugins')(); @@ -33,7 +31,12 @@ var util = require('./tools/build/util'); var bundler = require('./tools/build/bundle'); var replace = require('gulp-replace'); var insert = require('gulp-insert'); -var makeBroccoliTree = require('./tools/broccoli/make-broccoli-tree'); + +// dynamic require in build.broccoli.tools so we can bootstrap TypeScript compilation +function missingDynamicBroccoli() { + throw new Error('ERROR: build.broccoli.tools task should have been run before using broccoli'); +} +var makeBroccoliTree = missingDynamicBroccoli, broccoliBuild = missingDynamicBroccoli; // Note: when DART_SDK is not found, all gulp tasks ending with `.dart` will be skipped. @@ -769,7 +772,11 @@ gulp.task('build.dart', function(done) { gulp.task('build.broccoli.tools', function() { var tsResult = gulp.src('tools/broccoli/**/*.ts') .pipe(tsc({ target: 'ES5', module: 'commonjs' })); - return tsResult.js.pipe(gulp.dest('dist/broccoli')); + return tsResult.js.pipe(gulp.dest('dist/broccoli')) + .on('end', function() { + makeBroccoliTree = require('./dist/broccoli/make-broccoli-tree'); + broccoliBuild = require('./dist/broccoli/gulp'); + }); }); gulp.task('broccoli.js.dev', ['build.broccoli.tools'], function() { diff --git a/tools/broccoli/gulp/index.js b/tools/broccoli/gulp/index.ts similarity index 55% rename from tools/broccoli/gulp/index.js rename to tools/broccoli/gulp/index.ts index f4a150e030..530d997ffe 100644 --- a/tools/broccoli/gulp/index.js +++ b/tools/broccoli/gulp/index.ts @@ -1,5 +1,3 @@ -'use strict'; - var broccoli = require('broccoli'); var copyDereferenceSync = require('copy-dereference').sync; var fse = require('fs-extra'); @@ -32,45 +30,43 @@ function broccoliBuild(tree, outputRoot) { var builder = new broccoli.Builder(tree); return builder.build() - .then(function (hash) { - console.log('=== Stats for %s (total: %ds) ===', outputRoot, Math.round(hash.totalTime/1000000)/1000); - printSlowTrees(hash.graph); + .then(function(hash) { + console.log('=== Stats for %s (total: %ds) ===', outputRoot, + Math.round(hash.totalTime / 1000000) / 1000); + printSlowTrees(hash.graph); - var dir = hash.directory; - try { - time('Write build output', function() { - copyDereferenceSync(path.join(dir, outputRoot), distPath); - }); - } catch (err) { - if (err.code === 'EEXIST') err.message += ' (we cannot build into an existing directory)'; - throw err; - } - }) - .finally(function () { - time('Build cleanup', function() { - builder.cleanup(); + var dir = hash.directory; + try { + time('Write build output', function() { + copyDereferenceSync(path.join(dir, outputRoot), distPath); + }); + } catch (err) { + if (err.code === 'EEXIST') err.message += ' (we cannot build into an existing directory)'; + throw err; + } + }) + .finally(function() { + time('Build cleanup', function() { builder.cleanup(); }); + + console.log('=== Done building %s ===', outputRoot); + }) + .catch(function(err) { + // Should show file and line/col if present + if (err.file) { + console.error('File: ' + err.file); + } + if (err.stack) { + console.error(err.stack); + } else { + console.error(err); + } + console.error('\nBuild failed'); + process.exit(1); }); - - console.log('=== Done building %s ===', outputRoot); - }) - .catch(function (err) { - // Should show file and line/col if present - if (err.file) { - console.error('File: ' + err.file); - } - if (err.stack) { - console.error(err.stack); - } else { - console.error(err); - } - console.error('\nBuild failed'); - process.exit(1); - }); } function time(label, work) { - var start = Date.now(); work(); var duration = Date.now() - start; diff --git a/tools/broccoli/html-replace/index.js b/tools/broccoli/html-replace/index.ts similarity index 54% rename from tools/broccoli/html-replace/index.js rename to tools/broccoli/html-replace/index.ts index 42c4f5121f..5f401061ac 100644 --- a/tools/broccoli/html-replace/index.js +++ b/tools/broccoli/html-replace/index.ts @@ -3,8 +3,9 @@ var path = require('path'); module.exports = read; function read(file) { - var content = fs.readFileSync(path.join(__dirname, file + '.html'), {encoding: 'utf-8'}); - // TODO(broccoli): we don't really need this, it's here to make the output match the tools/build/html + var content = fs.readFileSync(path.join('tools/broccoli/html-replace', file + '.html'), + {encoding: 'utf-8'}); + // TODO(broccoli): we don't really need this, it's here to make the output match the + // tools/build/html return content.substring(0, content.lastIndexOf("\n")); } - diff --git a/tools/broccoli/make-broccoli-tree.js b/tools/broccoli/make-broccoli-tree.ts similarity index 82% rename from tools/broccoli/make-broccoli-tree.js rename to tools/broccoli/make-broccoli-tree.ts index 359cc01469..d1e27ace21 100644 --- a/tools/broccoli/make-broccoli-tree.js +++ b/tools/broccoli/make-broccoli-tree.ts @@ -8,34 +8,33 @@ var path = require('path'); var renderLodashTemplate = require('broccoli-lodash'); var replace = require('broccoli-replace'); var stew = require('broccoli-stew'); -var ts2dart; -var TraceurCompiler; -var TypescriptCompiler; +var ts2dart = require('./broccoli-ts2dart'); +var TraceurCompiler = require('./traceur'); +var TypescriptCompiler = require('./typescript'); var projectRootDir = path.normalize(path.join(__dirname, '..', '..')); module.exports = function makeBroccoliTree(name) { - if (!TraceurCompiler) TraceurCompiler = require('../../dist/broccoli/traceur'); - if (!TypescriptCompiler) TypescriptCompiler = require('../../dist/broccoli/typescript'); - if (!ts2dart) ts2dart = require('../../dist/broccoli/broccoli-ts2dart'); - switch (name) { - case 'dev': return makeBrowserTree({name: name, typeAssertions: true}); - case 'prod': return makeBrowserTree({name: name, typeAssertions: false}); - case 'cjs': return makeCjsTree(); - case 'dart': return makeDartTree(); - default: throw new Error('Unknown build type: ' + name); + case 'dev': + return makeBrowserTree({name: name, typeAssertions: true}); + case 'prod': + return makeBrowserTree({name: name, typeAssertions: false}); + case 'cjs': + return makeCjsTree(); + case 'dart': + return makeDartTree(); + default: + throw new Error('Unknown build type: ' + name); } }; function makeBrowserTree(options) { - var modulesTree = new Funnel('modules', { - include: ['**/**'], - exclude: ['**/*.cjs', 'benchmarks/e2e_test/**'], - destDir: '/' - }); + var modulesTree = new Funnel( + 'modules', + {include: ['**/**'], exclude: ['**/*.cjs', 'benchmarks/e2e_test/**'], destDir: '/'}); // Use Traceur to transpile original sources to ES6 var es6Tree = new TraceurCompiler(modulesTree, '.es6', '.map', { @@ -52,14 +51,14 @@ function makeBrowserTree(options) { // Call Traceur again to lower the ES6 build tree to ES5 - var es5Tree = new TraceurCompiler(es6Tree, '.js', '.js.map', {modules: 'instantiate', sourceMaps: true}); + var es5Tree = + new TraceurCompiler(es6Tree, '.js', '.js.map', {modules: 'instantiate', sourceMaps: true}); // Now we add a few more files to the es6 tree that Traceur should not see - ['angular2', 'rtts_assert'].forEach( - function (destDir) { - var extras = new Funnel('tools/build', {files: ['es5build.js'], destDir: destDir}); - es6Tree = mergeTrees([es6Tree, extras]); - }); + ['angular2', 'rtts_assert'].forEach(function(destDir) { + var extras = new Funnel('tools/build', {files: ['es5build.js'], destDir: destDir}); + es6Tree = mergeTrees([es6Tree, extras]); + }); var vendorScriptsTree = flatten(new Funnel('.', { @@ -76,9 +75,9 @@ function makeBrowserTree(options) { ] })); var vendorScripts_benchmark = - new Funnel('tools/build/snippets', {files: ['url_params_to_form.js'], destDir: '/'}); + new Funnel('tools/build/snippets', {files: ['url_params_to_form.js'], destDir: '/'}); var vendorScripts_benchmarks_external = - new Funnel('node_modules/angular', {files: ['angular.js'], destDir: '/'}); + new Funnel('node_modules/angular', {files: ['angular.js'], destDir: '/'}); var servingTrees = []; @@ -89,7 +88,7 @@ function makeBrowserTree(options) { } if (destDir.indexOf('benchmarks_external') > -1) { servingTrees.push( - new Funnel(vendorScripts_benchmarks_external, {srcDir: '/', destDir: destDir})); + new Funnel(vendorScripts_benchmarks_external, {srcDir: '/', destDir: destDir})); } } @@ -117,7 +116,7 @@ function makeBrowserTree(options) { // Copy all vendor scripts into all examples and benchmarks ['benchmarks/src', 'benchmarks_external/src', 'examples/src/benchpress'].forEach( - copyVendorScriptsTo); + copyVendorScriptsTo); var scripts = mergeTrees(servingTrees, {overwrite: true}); var css = new Funnel(modulesTree, {include: ["**/*.css"]}); @@ -161,11 +160,10 @@ function makeCjsTree() { }); // Now we add the LICENSE file into all the folders that will become npm packages - outputPackages.forEach( - function(destDir) { - var license = new Funnel('.', {files: ['LICENSE'], destDir: destDir}); - cjsTree = mergeTrees([cjsTree, license]); - }); + outputPackages.forEach(function(destDir) { + var license = new Funnel('.', {files: ['LICENSE'], destDir: destDir}); + cjsTree = mergeTrees([cjsTree, license]); + }); // Get all docs and related assets and prepare them for js build var docs = new Funnel(modulesTree, {include: ['**/*.md', '**/*.png'], exclude: ['**/*.dart.md']}); @@ -191,11 +189,10 @@ function makeCjsTree() { }; // Add a .template extension since renderLodashTemplate strips one extension - var packageJsons = stew.rename(new Funnel(modulesTree, {include: ['**/package.json']}), '.json', '.json.template'); - packageJsons = renderLodashTemplate(packageJsons, { - files: ["**/**"], - context: { 'packageJson': COMMON_PACKAGE_JSON } - }); + var packageJsons = stew.rename(new Funnel(modulesTree, {include: ['**/package.json']}), '.json', + '.json.template'); + packageJsons = renderLodashTemplate( + packageJsons, {files: ["**/**"], context: {'packageJson': COMMON_PACKAGE_JSON}}); var typescriptTree = new TypescriptCompiler(modulesTree, { @@ -251,7 +248,7 @@ function makeDartTree() { return path.join.apply(path, parts); } } - throw new Error('Failed to match any path', relativePath); + throw new Error('Failed to match any path: ' + relativePath); }); // Move the tree under the 'dart' folder.