diff --git a/Gulpfile.js b/Gulpfile.js index 52744e12740..db7bb76d34b 100644 --- a/Gulpfile.js +++ b/Gulpfile.js @@ -12,6 +12,7 @@ const clone = require("gulp-clone"); const newer = require("gulp-newer"); const tsc = require("gulp-typescript"); const tsc_oop = require("./scripts/build/gulp-typescript-oop"); +const getDirSize = require("./scripts/build/getDirSize"); const insert = require("gulp-insert"); const sourcemaps = require("gulp-sourcemaps"); const Q = require("q"); @@ -588,7 +589,13 @@ gulp.task("VerifyLKG", /*help*/ false, [], () => { gulp.task("LKGInternal", /*help*/ false, ["lib", "local"]); gulp.task("LKG", "Makes a new LKG out of the built js files", ["clean", "dontUseDebugMode"], () => { - return runSequence("LKGInternal", "VerifyLKG"); + const sizeBefore = getDirSize(lkgDirectory); + const seq = runSequence("LKGInternal", "VerifyLKG"); + const sizeAfter = getDirSize(lkgDirectory); + if (sizeAfter > (sizeBefore * 1.10)) { + throw new Error("The lib folder increased by 10% or more. This likely indicates a bug."); + } + return seq; }); diff --git a/Jakefile.js b/Jakefile.js index 55729eecaad..a6483355c73 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -8,6 +8,7 @@ var path = require("path"); var child_process = require("child_process"); var fold = require("travis-fold"); var ts = require("./lib/typescript"); +const getDirSize = require("./scripts/build/getDirSize"); // Variables var compilerDirectory = "src/compiler/"; @@ -642,26 +643,24 @@ task("generate-spec", [specMd]); // Makes a new LKG. This target does not build anything, but errors if not all the outputs are present in the built/local directory desc("Makes a new LKG out of the built js files"); -task("LKG", ["clean", "release", "local"].concat(libraryTargets), function () { +task("LKG", ["clean", "release", "local"].concat(libraryTargets), () => { + const sizeBefore = getDirSize(LKGDirectory); var expectedFiles = [tscFile, servicesFile, serverFile, nodePackageFile, nodeDefinitionsFile, standaloneDefinitionsFile, tsserverLibraryFile, tsserverLibraryDefinitionFile, cancellationTokenFile, typingsInstallerFile, buildProtocolDts, watchGuardFile]. concat(libraryTargets). concat(localizationTargets); - var missingFiles = expectedFiles.filter(function (f) { - return !fs.existsSync(f); - }); + var missingFiles = expectedFiles.filter(f => !fs.existsSync(f)); if (missingFiles.length > 0) { fail(new Error("Cannot replace the LKG unless all built targets are present in directory " + builtLocalDirectory + ". The following files are missing:\n" + missingFiles.join("\n"))); } // Copy all the targets into the LKG directory jake.mkdirP(LKGDirectory); - for (i in expectedFiles) { - jake.cpR(expectedFiles[i], LKGDirectory); + expectedFiles.forEach(f => jake.cpR(f, LKGDirectory)); + + const sizeAfter = getDirSize(LKGDirectory); + if (sizeAfter > (sizeBefore * 1.10)) { + throw new Error("The lib folder increased by 10% or more. This likely indicates a bug."); } - //var resourceDirectories = fs.readdirSync(builtLocalResourcesDirectory).map(function(p) { return path.join(builtLocalResourcesDirectory, p); }); - //resourceDirectories.map(function(d) { - // jake.cpR(d, LKGResourcesDirectory); - //}); }); // Test directory diff --git a/scripts/build/getDirSize.js b/scripts/build/getDirSize.js new file mode 100644 index 00000000000..278c4e7f009 --- /dev/null +++ b/scripts/build/getDirSize.js @@ -0,0 +1,30 @@ +// @ts-check +const { lstatSync, readdirSync } = require("fs"); +const { join } = require("path"); + +/** + * Find the size of a directory recursively. + * Symbolic links are counted once (same inode). + * @param {string} root + * @param {Set} seen + * @returns {number} bytes + */ +function getDirSize(root, seen = new Set()) { + const stats = lstatSync(root); + + if (seen.has(stats.ino)) { + return 0; + } + + seen.add(stats.ino); + + if (!stats.isDirectory()) { + return stats.size; + } + + return readdirSync(root) + .map(file => getDirSize(join(root, file), seen)) + .reduce((acc, num) => acc + num, 0); +} + +module.exports = getDirSize;