From 53d54c2b282d7bc4808941292fd91c1d41f5e4cc Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Mon, 8 Aug 2016 14:30:27 -0700 Subject: [PATCH] Make baselines faster by not writing out unneeded files --- Gulpfile.ts | 111 ++++++++++++++++++++----------------- Jakefile.js | 17 +++--- package.json | 1 + scripts/types/ambient.d.ts | 2 +- src/harness/harness.ts | 19 +++---- 5 files changed, 79 insertions(+), 71 deletions(-) diff --git a/Gulpfile.ts b/Gulpfile.ts index b9b5d2068b2..e2d37277bcf 100644 --- a/Gulpfile.ts +++ b/Gulpfile.ts @@ -17,7 +17,7 @@ declare module "gulp-typescript" { stripInternal?: boolean; types?: string[]; } - interface CompileStream extends NodeJS.ReadWriteStream {} // Either gulp or gulp-typescript has some odd typings which don't reflect reality, making this required + interface CompileStream extends NodeJS.ReadWriteStream { } // Either gulp or gulp-typescript has some odd typings which don't reflect reality, making this required } import * as insert from "gulp-insert"; import * as sourcemaps from "gulp-sourcemaps"; @@ -65,7 +65,7 @@ const cmdLineOptions = minimist(process.argv.slice(2), { } }); -function exec(cmd: string, args: string[], complete: () => void = (() => {}), error: (e: any, status: number) => void = (() => {})) { +function exec(cmd: string, args: string[], complete: () => void = (() => { }), error: (e: any, status: number) => void = (() => { })) { console.log(`${cmd} ${args.join(" ")}`); // TODO (weswig): Update child_process types to add windowsVerbatimArguments to the type definition const subshellFlag = isWin ? "/c" : "-c"; @@ -116,12 +116,12 @@ const es2015LibrarySources = [ ]; const es2015LibrarySourceMap = es2015LibrarySources.map(function(source) { - return { target: "lib." + source, sources: ["header.d.ts", source] }; + return { target: "lib." + source, sources: ["header.d.ts", source] }; }); -const es2016LibrarySource = [ "es2016.array.include.d.ts" ]; +const es2016LibrarySource = ["es2016.array.include.d.ts"]; -const es2016LibrarySourceMap = es2016LibrarySource.map(function (source) { +const es2016LibrarySourceMap = es2016LibrarySource.map(function(source) { return { target: "lib." + source, sources: ["header.d.ts", source] }; }); @@ -130,38 +130,38 @@ const es2017LibrarySource = [ "es2017.sharedmemory.d.ts" ]; -const es2017LibrarySourceMap = es2017LibrarySource.map(function (source) { +const es2017LibrarySourceMap = es2017LibrarySource.map(function(source) { return { target: "lib." + source, sources: ["header.d.ts", source] }; }); const hostsLibrarySources = ["dom.generated.d.ts", "webworker.importscripts.d.ts", "scripthost.d.ts"]; const librarySourceMap = [ - // Host library - { target: "lib.dom.d.ts", sources: ["header.d.ts", "dom.generated.d.ts"] }, - { target: "lib.dom.iterable.d.ts", sources: ["header.d.ts", "dom.iterable.d.ts"] }, - { target: "lib.webworker.d.ts", sources: ["header.d.ts", "webworker.generated.d.ts"] }, - { target: "lib.scripthost.d.ts", sources: ["header.d.ts", "scripthost.d.ts"] }, + // Host library + { target: "lib.dom.d.ts", sources: ["header.d.ts", "dom.generated.d.ts"] }, + { target: "lib.dom.iterable.d.ts", sources: ["header.d.ts", "dom.iterable.d.ts"] }, + { target: "lib.webworker.d.ts", sources: ["header.d.ts", "webworker.generated.d.ts"] }, + { target: "lib.scripthost.d.ts", sources: ["header.d.ts", "scripthost.d.ts"] }, - // JavaScript library - { target: "lib.es5.d.ts", sources: ["header.d.ts", "es5.d.ts"] }, - { target: "lib.es2015.d.ts", sources: ["header.d.ts", "es2015.d.ts"] }, - { target: "lib.es2016.d.ts", sources: ["header.d.ts", "es2016.d.ts"] }, - { target: "lib.es2017.d.ts", sources: ["header.d.ts", "es2017.d.ts"] }, + // JavaScript library + { target: "lib.es5.d.ts", sources: ["header.d.ts", "es5.d.ts"] }, + { target: "lib.es2015.d.ts", sources: ["header.d.ts", "es2015.d.ts"] }, + { target: "lib.es2016.d.ts", sources: ["header.d.ts", "es2016.d.ts"] }, + { target: "lib.es2017.d.ts", sources: ["header.d.ts", "es2017.d.ts"] }, - // JavaScript + all host library - { target: "lib.d.ts", sources: ["header.d.ts", "es5.d.ts"].concat(hostsLibrarySources) }, - { target: "lib.es6.d.ts", sources: ["header.d.ts", "es5.d.ts"].concat(es2015LibrarySources, hostsLibrarySources, "dom.iterable.d.ts") } + // JavaScript + all host library + { target: "lib.d.ts", sources: ["header.d.ts", "es5.d.ts"].concat(hostsLibrarySources) }, + { target: "lib.es6.d.ts", sources: ["header.d.ts", "es5.d.ts"].concat(es2015LibrarySources, hostsLibrarySources, "dom.iterable.d.ts") } ].concat(es2015LibrarySourceMap, es2016LibrarySourceMap, es2017LibrarySourceMap); -const libraryTargets = librarySourceMap.map(function (f) { +const libraryTargets = librarySourceMap.map(function(f) { return path.join(builtLocalDirectory, f.target); }); for (const i in libraryTargets) { const entry = librarySourceMap[i]; const target = libraryTargets[i]; - const sources = [copyright].concat(entry.sources.map(function (s) { + const sources = [copyright].concat(entry.sources.map(function(s) { return path.join(libraryDirectory, s); })); gulp.task(target, false, [], function() { @@ -391,7 +391,7 @@ gulp.task(servicesFile, false, ["lib", "generate-diagnostics"], () => { .pipe(sourcemaps.init()) .pipe(tsc(servicesProject)); const completedJs = js.pipe(prependCopyright()) - .pipe(sourcemaps.write(".")); + .pipe(sourcemaps.write(".")); const completedDts = dts.pipe(prependCopyright(/*outputCopyright*/true)) .pipe(insert.transform((contents, file) => { file.path = standaloneDefinitionsFile; @@ -434,17 +434,17 @@ const tsserverLibraryDefinitionFile = path.join(builtLocalDirectory, "tsserverli gulp.task(tsserverLibraryFile, false, [servicesFile], (done) => { const serverLibraryProject = tsc.createProject("src/server/tsconfig.library.json", getCompilerSettings({}, /*useBuiltCompiler*/ true)); - const {js, dts}: {js: NodeJS.ReadableStream, dts: NodeJS.ReadableStream} = serverLibraryProject.src() + const {js, dts}: { js: NodeJS.ReadableStream, dts: NodeJS.ReadableStream } = serverLibraryProject.src() .pipe(sourcemaps.init()) .pipe(newer(tsserverLibraryFile)) .pipe(tsc(serverLibraryProject)); return merge2([ js.pipe(prependCopyright()) - .pipe(sourcemaps.write(".")) - .pipe(gulp.dest(builtLocalDirectory)), + .pipe(sourcemaps.write(".")) + .pipe(gulp.dest(builtLocalDirectory)), dts.pipe(prependCopyright()) - .pipe(gulp.dest(builtLocalDirectory)) + .pipe(gulp.dest(builtLocalDirectory)) ]); }); @@ -476,7 +476,7 @@ gulp.task(specMd, false, [word2mdJs], (done) => { const specMDFullPath = path.resolve(specMd); const cmd = "cscript //nologo " + word2mdJs + " \"" + specWordFullPath + "\" " + "\"" + specMDFullPath + "\""; console.log(cmd); - cp.exec(cmd, function () { + cp.exec(cmd, function() { done(); }); }); @@ -492,12 +492,12 @@ gulp.task("dontUseDebugMode", false, [], (done) => { useDebugMode = false; done( gulp.task("VerifyLKG", false, [], () => { const expectedFiles = [builtLocalCompiler, servicesFile, serverFile, nodePackageFile, nodeDefinitionsFile, standaloneDefinitionsFile, tsserverLibraryFile, tsserverLibraryDefinitionFile].concat(libraryTargets); - const missingFiles = expectedFiles.filter(function (f) { + const missingFiles = expectedFiles.filter(function(f) { return !fs.existsSync(f); }); if (missingFiles.length > 0) { throw new Error("Cannot replace the LKG unless all built targets are present in directory " + builtLocalDirectory + - ". The following files are missing:\n" + missingFiles.join("\n")); + ". The following files are missing:\n" + missingFiles.join("\n")); } // Copy all the targets into the LKG directory return gulp.src(expectedFiles).pipe(gulp.dest(LKGDirectory)); @@ -627,7 +627,7 @@ function runConsoleTests(defaultReporter: string, runInParallel: boolean, done: } args.push(run); setNodeEnvToDevelopment(); - runTestsInParallel(taskConfigsFolder, run, { testTimeout: testTimeout, noColors: colors === " --no-colors " }, function (err) { + runTestsInParallel(taskConfigsFolder, run, { testTimeout: testTimeout, noColors: colors === " --no-colors " }, function(err) { // last worker clean everything and runs linter in case if there were no errors del(taskConfigsFolder).then(() => { if (!err) { @@ -679,7 +679,7 @@ gulp.task("runtests", ["build-rules", "tests"], (done) => { runConsoleTests("mocha-fivemat-progress-reporter", /*runInParallel*/ false, done); -}); + }); const nodeServerOutFile = "tests/webTestServer.js"; const nodeServerInFile = "tests/webTestServer.ts"; @@ -812,31 +812,38 @@ gulp.task("diff-rwc", "Diffs the RWC baselines using the diff tool specified by }); -gulp.task("baseline-accept", "Makes the most recent test results the new baseline, overwriting the old baseline", (done) => { - const softAccept = cmdLineOptions["soft"]; - if (!softAccept) { - del(refBaseline).then(() => { - fs.renameSync(localBaseline, refBaseline); - done(); - }, done); - } - else { - gulp.src(localBaseline) - .pipe(gulp.dest(refBaseline)) - .on("end", () => { - del(path.join(refBaseline, "local")).then(() => done(), done); - }); - } +const deleteEnding = '.delete'; +gulp.task("baseline-accept", "Makes the most recent test results the new baseline, overwriting the old baseline", () => { + return baselineAccept(""); }); + +function baselineAccept(subfolder = "") { + return merge2(baselineCopy(subfolder), baselineDelete(subfolder)); +} + +function baselineCopy(subfolder = "") { + return gulp.src([`tests/baselines/local/${subfolder}/**`, `!tests/baselines/local/${subfolder}/**/*.delete`]) + .pipe(gulp.dest(refBaseline)); +} + +function baselineDelete(subfolder = "") { + return gulp.src(['tests/baselines/local/**/*.delete']) + .pipe(insert.transform((content, fileObj) => { + const target = path.join(refBaseline, fileObj.relative.substr(0, fileObj.relative.length - '.delete'.length)); + console.log(target); + del.sync(target); + del.sync(fileObj.path); + return ''; + })); +} + gulp.task("baseline-accept-rwc", "Makes the most recent rwc test results the new baseline, overwriting the old baseline", () => { - return del(refRwcBaseline).then(() => { - fs.renameSync(localRwcBaseline, refRwcBaseline); - }); + return baselineAccept("rwc"); }); + + gulp.task("baseline-accept-test262", "Makes the most recent test262 test results the new baseline, overwriting the old baseline", () => { - return del(refTest262Baseline).then(() => { - fs.renameSync(localTest262Baseline, refTest262Baseline); - }); + return baselineAccept("test262"); }); diff --git a/Jakefile.js b/Jakefile.js index a5650a56b16..8062d8a2928 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -1,3 +1,4 @@ +"use strict"; // This file contains the build logic for the public repo var fs = require("fs"); @@ -898,16 +899,16 @@ task("tests-debug", ["setDebugMode", "tests"]); // Makes the test results the new baseline desc("Makes the most recent test results the new baseline, overwriting the old baseline"); task("baseline-accept", function(hardOrSoft) { - if (!hardOrSoft || hardOrSoft === "hard") { - jake.rmRf(refBaseline); - fs.renameSync(localBaseline, refBaseline); - } - else if (hardOrSoft === "soft") { - var files = jake.readdirR(localBaseline); - for (var i in files) { + var files = jake.readdirR(localBaseline); + var deleteEnding = '.delete'; + for (var i in files) { + if (files[i].substr(files[i].length - deleteEnding.length) === deleteEnding) { + var filename = path.basename(files[i]); + filename = filename.substr(0, filename.length - deleteEnding.length); + fs.unlink(path.join(refBaseline, filename)); + } else { jake.cpR(files[i], refBaseline); } - jake.rmRf(path.join(refBaseline, "local")); } }); diff --git a/package.json b/package.json index 9f3122c3374..1f1c52b42ed 100644 --- a/package.json +++ b/package.json @@ -69,6 +69,7 @@ "mkdirp": "latest", "mocha": "latest", "mocha-fivemat-progress-reporter": "latest", + "q": "latest", "run-sequence": "latest", "sorcery": "latest", "through2": "latest", diff --git a/scripts/types/ambient.d.ts b/scripts/types/ambient.d.ts index e77e3fe8c5a..16ec9385cb1 100644 --- a/scripts/types/ambient.d.ts +++ b/scripts/types/ambient.d.ts @@ -10,7 +10,7 @@ declare module "gulp-insert" { export function append(text: string | Buffer): NodeJS.ReadWriteStream; export function prepend(text: string | Buffer): NodeJS.ReadWriteStream; export function wrap(text: string | Buffer, tail: string | Buffer): NodeJS.ReadWriteStream; - export function transform(cb: (contents: string, file: {path: string}) => string): NodeJS.ReadWriteStream; // file is a vinyl file + export function transform(cb: (contents: string, file: {path: string, relative: string}) => string): NodeJS.ReadWriteStream; // file is a vinyl file } declare module "into-stream" { diff --git a/src/harness/harness.ts b/src/harness/harness.ts index f27e7e1c174..18a440c789b 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -1569,6 +1569,7 @@ namespace Harness { /** Support class for baseline files */ export namespace Baseline { + const NoContent = ""; export interface BaselineOptions { Subfolder?: string; @@ -1635,14 +1636,6 @@ namespace Harness { throw new Error("The generated content was \"undefined\". Return \"null\" if no baselining is required.\""); } - // Store the content in the 'local' folder so we - // can accept it later (manually) - /* tslint:disable:no-null-keyword */ - if (actual !== null) { - /* tslint:enable:no-null-keyword */ - IO.writeFile(actualFileName, actual); - } - return actual; } @@ -1659,7 +1652,7 @@ namespace Harness { /* tslint:disable:no-null-keyword */ if (actual === null) { /* tslint:enable:no-null-keyword */ - actual = ""; + actual = NoContent; } let expected = ""; @@ -1672,7 +1665,13 @@ namespace Harness { function writeComparison(expected: string, actual: string, relativeFileName: string, actualFileName: string, descriptionForDescribe: string) { const encoded_actual = Utils.encodeString(actual); - if (expected != encoded_actual) { + if (expected !== encoded_actual) { + if (actual === NoContent) { + IO.writeFile(relativeFileName + '.delete', ''); + } + else { + IO.writeFile(relativeFileName, actual); + } // Overwrite & issue error const errMsg = "The baseline file " + relativeFileName + " has changed."; throw new Error(errMsg);