diff --git a/Gulpfile.ts b/Gulpfile.ts index f6e5ed627d8b9..757cd4fed0888 100644 --- a/Gulpfile.ts +++ b/Gulpfile.ts @@ -28,7 +28,6 @@ import minimist = require("minimist"); import browserify = require("browserify"); import through2 = require("through2"); import merge2 = require("merge2"); -import intoStream = require("into-stream"); import * as os from "os"; import fold = require("travis-fold"); const gulp = helpMaker(originalGulp); @@ -737,50 +736,75 @@ gulp.task(nodeServerOutFile, /*help*/ false, [servicesFile], () => { import convertMap = require("convert-source-map"); import sorcery = require("sorcery"); -declare module "convert-source-map" { - export function fromSource(source: string, largeSource?: boolean): SourceMapConverter; -} +import Vinyl = require("vinyl"); -gulp.task("browserify", "Runs browserify on run.js to produce a file suitable for running tests in the browser", [servicesFile, run], (done) => { - const testProject = tsc.createProject("src/harness/tsconfig.json", getCompilerSettings({ outFile: "../../built/local/bundle.js" }, /*useBuiltCompiler*/ true)); - return testProject.src() - .pipe(newer("built/local/bundle.js")) +const bundlePath = path.resolve("built/local/bundle.js"); + +gulp.task("browserify", "Runs browserify on run.js to produce a file suitable for running tests in the browser", [servicesFile], (done) => { + const testProject = tsc.createProject("src/harness/tsconfig.json", getCompilerSettings({ outFile: bundlePath, inlineSourceMap: true }, /*useBuiltCompiler*/ true)); + let originalMap: any; + let prebundledContent: string; + browserify(testProject.src() + .pipe(newer(bundlePath)) .pipe(sourcemaps.init()) .pipe(testProject()) .pipe(through2.obj((file, enc, next) => { - const originalMap = file.sourceMap; - const prebundledContent = file.contents.toString(); + if (originalMap) { + throw new Error("Should only recieve one file!"); + } + console.log(`Saving sourcemaps for ${file.path}`); + originalMap = file.sourceMap; + prebundledContent = file.contents.toString(); // Make paths absolute to help sorcery deal with all the terrible paths being thrown around originalMap.sources = originalMap.sources.map(s => path.resolve(path.join("src/harness", s))); - // intoStream (below) makes browserify think the input file is named this, so this is what it puts in the sourcemap + // browserify names input files this when they are streamed in, so this is what it puts in the sourcemap originalMap.file = "built/local/_stream_0.js"; - browserify(intoStream(file.contents), { debug: true }) - .bundle((err, res) => { - // assumes file.contents is a Buffer - const maps = JSON.parse(convertMap.fromSource(res.toString(), /*largeSource*/ true).toJSON()); - delete maps.sourceRoot; - maps.sources = maps.sources.map(s => path.resolve(s === "_stream_0.js" ? "built/local/_stream_0.js" : s)); - // Strip browserify's inline comments away (could probably just let sorcery do this, but then we couldn't fix the paths) - file.contents = new Buffer(convertMap.removeComments(res.toString())); - const chain = sorcery.loadSync("built/local/bundle.js", { - content: { - "built/local/_stream_0.js": prebundledContent, - "built/local/bundle.js": file.contents.toString() - }, - sourcemaps: { - "built/local/_stream_0.js": originalMap, - "built/local/bundle.js": maps, - "node_modules/source-map-support/source-map-support.js": undefined, - } - }); - const finalMap = chain.apply(); - file.sourceMap = finalMap; - next(/*err*/ undefined, file); - }); + next(/*err*/ undefined, file.contents); })) - .pipe(sourcemaps.write(".", { includeContent: false })) - .pipe(gulp.dest("src/harness")); + .on("error", err => { + return done(err); + }), { debug: true, basedir: __dirname }) // Attach error handler to inner stream + .bundle((err, contents) => { + if (err) { + if (err.message.match(/Cannot find module '.*_stream_0.js'/)) { + return done(); // Browserify errors when we pass in no files when `newer` filters the input, we should count that as a success, though + } + return done(err); + } + const stringContent = contents.toString(); + const file = new Vinyl({ contents, path: bundlePath }); + console.log(`Fixing sourcemaps for ${file.path}`); + // assumes contents is a Buffer, since that's what browserify yields + const maps = convertMap.fromSource(stringContent, /*largeSource*/ true).toObject(); + delete maps.sourceRoot; + maps.sources = maps.sources.map(s => path.resolve(s === "_stream_0.js" ? "built/local/_stream_0.js" : s)); + // Strip browserify's inline comments away (could probably just let sorcery do this, but then we couldn't fix the paths) + file.contents = new Buffer(convertMap.removeComments(stringContent)); + const chain = sorcery.loadSync(bundlePath, { + content: { + "built/local/_stream_0.js": prebundledContent, + [bundlePath]: stringContent + }, + sourcemaps: { + "built/local/_stream_0.js": originalMap, + [bundlePath]: maps, + "node_modules/source-map-support/source-map-support.js": undefined, + } + }); + const finalMap = chain.apply(); + file.sourceMap = finalMap; + + const stream = through2.obj((file, enc, callback) => { + return callback(/*err*/ undefined, file); + }); + stream.pipe(sourcemaps.write(".", { includeContent: false })) + .pipe(gulp.dest(".")) + .on("end", done) + .on("error", done); + stream.write(file); + stream.end(); + }); }); diff --git a/package.json b/package.json index 5a3bc7ad58c6c..a114ac68a2d80 100644 --- a/package.json +++ b/package.json @@ -60,7 +60,6 @@ "gulp-newer": "latest", "gulp-sourcemaps": "latest", "gulp-typescript": "latest", - "into-stream": "latest", "istanbul": "latest", "jake": "latest", "merge2": "latest", diff --git a/scripts/types/ambient.d.ts b/scripts/types/ambient.d.ts index 4f4b118c432db..f99bf0101981b 100644 --- a/scripts/types/ambient.d.ts +++ b/scripts/types/ambient.d.ts @@ -13,13 +13,5 @@ declare module "gulp-insert" { export function transform(cb: (contents: string, file: {path: string, relative: string}) => string): NodeJS.ReadWriteStream; // file is a vinyl file } -declare module "into-stream" { - function IntoStream(content: string | Buffer | (string | Buffer)[]): NodeJS.ReadableStream; - namespace IntoStream { - export function obj(content: any): NodeJS.ReadableStream - } - export = IntoStream; -} - declare module "sorcery"; declare module "travis-fold"; diff --git a/src/harness/rwcRunner.ts b/src/harness/rwcRunner.ts index a25a01815116b..98663863a937b 100644 --- a/src/harness/rwcRunner.ts +++ b/src/harness/rwcRunner.ts @@ -54,7 +54,8 @@ namespace RWC { useCustomLibraryFile = undefined; }); - it("can compile", () => { + it("can compile", function(this: Mocha.ITestCallbackContext) { + this.timeout(800000); // Allow long timeouts for RWC compilations let opts: ts.ParsedCommandLine; const ioLog: IOLog = JSON.parse(Harness.IO.readFile(jsonPath));