From 6b32f4edcb3b8e98b6c8fc90e7ee68ec904a2ea8 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Wed, 16 Jan 2019 14:56:48 -0800 Subject: [PATCH] Fix gulp builds not building some targets --- Gulpfile.js | 63 +++++++++++++---------- scripts/build/options.js | 2 +- scripts/build/project.js | 106 ++++++++++++++------------------------- 3 files changed, 76 insertions(+), 95 deletions(-) diff --git a/Gulpfile.js b/Gulpfile.js index df8a832426dda..3616e25ee80af 100644 --- a/Gulpfile.js +++ b/Gulpfile.js @@ -488,29 +488,28 @@ gulp.task( "Runs 'local'", ["local"]); -gulp.task( - "watch-diagnostics", - /*help*/ false, - [processDiagnosticMessagesJs], - () => gulp.watch([diagnosticMessagesJson], [diagnosticInformationMapTs, builtGeneratedDiagnosticMessagesJson])); - gulp.task( "watch-lib", /*help*/ false, () => gulp.watch(["src/lib/**/*"], ["lib"])); +const watchTscPatterns = [ + "src/tsconfig-base.json", + "src/lib/**/*", + "src/compiler/**/*", + "src/tsc/**/*", +]; gulp.task( "watch-tsc", /*help*/ false, - ["watch-diagnostics", "watch-lib"].concat(useCompilerDeps), - () => project.watch(tscProject, { typescript: useCompiler })); + useCompilerDeps, + () => gulp.watch(watchTscPatterns, ["tsc"])); const watchServicesPatterns = [ "src/compiler/**/*", "src/jsTypings/**/*", "src/services/**/*" ]; - gulp.task( "watch-services", /*help*/ false, @@ -522,39 +521,49 @@ const watchLsslPatterns = [ "src/server/**/*", "src/tsserver/tsconfig.json" ]; - gulp.task( "watch-lssl", /*help*/ false, () => gulp.watch(watchLsslPatterns, ["lssl"])); -gulp.task( - "watch-server", - /*help*/ false, - ["watch-diagnostics", "watch-lib"].concat(useCompilerDeps), - () => project.watch(tsserverProject, { typescript: useCompiler })); - -gulp.task( - "watch-runner", - /*help*/ false, - useCompilerDeps, - () => project.watch(testRunnerProject, { typescript: useCompiler })); - +const watchLocalPatterns = [ + "src/tsconfig-base.json", + "src/lib/**/*", + "src/compiler/**/*", + "src/tsc/**/*", + "src/services/**/*", + "src/jsTyping/**/*", + "src/server/**/*", + "src/tsserver/**/*", + "src/typingsInstallerCore/**/*", + "src/harness/**/*", + "src/testRunner/**/*", +]; gulp.task( "watch-local", "Watches for changes to projects in src/ (but does not execute tests).", - ["watch-lib", "watch-tsc", "watch-services", "watch-server", "watch-runner", "watch-lssl"]); + () => gulp.watch(watchLocalPatterns, "local")); +const watchPatterns = [ + "src/tsconfig-base.json", + "src/lib/**/*", + "src/compiler/**/*", + "src/services/**/*", + "src/jsTyping/**/*", + "src/server/**/*", + "src/tsserver/**/*", + "src/typingsInstallerCore/**/*", + "src/harness/**/*", + "src/testRunner/**/*", +]; gulp.task( "watch", "Watches for changes to the build inputs for built/local/run.js, then runs tests.", - ["build-rules", "watch-runner", "watch-services", "watch-lssl"], + ["build-rules"], () => { const sem = new Semaphore(1); - gulp.watch([runJs, typescriptDts, tsserverlibraryDts], () => { - runTests(); - }); + gulp.watch(watchPatterns, () => { runTests(); }); // NOTE: gulp.watch is far too slow when watching tests/cases/**/* as it first enumerates *every* file const testFilePattern = /(\.ts|[\\/]tsconfig\.json)$/; diff --git a/scripts/build/options.js b/scripts/build/options.js index e9e3bfb7b1bc6..ba1b669188dc5 100644 --- a/scripts/build/options.js +++ b/scripts/build/options.js @@ -34,7 +34,7 @@ module.exports = minimist(process.argv.slice(2), { workers: process.env.workerCount || os.cpus().length, failed: false, keepFailed: false, - lkg: false, + lkg: true, dirty: false } }); diff --git a/scripts/build/project.js b/scripts/build/project.js index 6c1ac0f3e04e2..fb193907bbe11 100644 --- a/scripts/build/project.js +++ b/scripts/build/project.js @@ -14,71 +14,14 @@ const ts = require("../../lib/typescript"); const del = require("del"); const needsUpdate = require("./needsUpdate"); const mkdirp = require("./mkdirp"); -const prettyTime = require("pretty-hrtime"); const { reportDiagnostics } = require("./diagnostics"); -const { CountdownEvent, ManualResetEvent } = require("prex"); +const { CountdownEvent, ManualResetEvent, Semaphore } = require("prex"); const workStartedEvent = new ManualResetEvent(); const countdown = new CountdownEvent(0); -class CompilationGulp extends gulp.Gulp { - /** - * @param {boolean} [verbose] - */ - fork(verbose) { - const child = new ForkedGulp(this.tasks); - child.on("task_start", e => { - if (countdown.remainingCount === 0) { - countdown.reset(1); - workStartedEvent.set(); - workStartedEvent.reset(); - } - else { - countdown.add(); - } - if (verbose) { - log('Starting', `'${chalk.cyan(e.task)}' ${chalk.gray(`(${countdown.remainingCount} remaining)`)}...`); - } - }); - child.on("task_stop", e => { - countdown.signal(); - if (verbose) { - log('Finished', `'${chalk.cyan(e.task)}' after ${chalk.magenta(prettyTime(/** @type {*}*/(e).hrDuration))} ${chalk.gray(`(${countdown.remainingCount} remaining)`)}`); - } - }); - child.on("task_err", e => { - countdown.signal(); - if (verbose) { - log(`'${chalk.cyan(e.task)}' ${chalk.red("errored after")} ${chalk.magenta(prettyTime(/** @type {*}*/(e).hrDuration))} ${chalk.gray(`(${countdown.remainingCount} remaining)`)}`); - log(e.err ? e.err.stack : e.message); - } - }); - return child; - } - - // @ts-ignore - start() { - throw new Error("Not supported, use fork."); - } -} - -class ForkedGulp extends gulp.Gulp { - /** - * @param {gulp.Gulp["tasks"]} tasks - */ - constructor(tasks) { - super(); - this.tasks = tasks; - } - - // Do not reset tasks - _resetAllTasks() {} - _resetSpecificTasks() {} - _resetTask() {} -} - // internal `Gulp` instance for compilation artifacts. -const compilationGulp = new CompilationGulp(); +const compilationGulp = new gulp.Gulp(); /** @type {Map} */ const projectGraphCache = new Map(); @@ -86,6 +29,39 @@ const projectGraphCache = new Map(); /** @type {Map} */ const typescriptAliasMap = new Map(); +// TODO: allow concurrent outer builds to be run in parallel +const sem = new Semaphore(1); + +/** + * @param {string|string[]} taskName + * @param {() => any} [cb] + */ +function start(taskName, cb) { + return sem.wait().then(() => new Promise((resolve, reject) => { + compilationGulp.start(taskName, err => { + if (err) { + reject(err); + } + else if (cb) { + try { + resolve(cb()); + } + catch (e) { + reject(err); + } + } + else { + resolve(); + } + }); + })).then(() => { + sem.release() + }, e => { + sem.release(); + throw e; + }); +} + /** * Defines a gulp orchestration for a TypeScript project, returning a callback that can be used to trigger compilation. * @param {string} projectSpec The path to a tsconfig.json file or its containing directory. @@ -98,9 +74,7 @@ function createCompiler(projectSpec, options) { const projectGraph = getOrCreateProjectGraph(resolvedProjectSpec, resolvedOptions.paths); projectGraph.isRoot = true; const taskName = compileTaskName(ensureCompileTask(projectGraph, resolvedOptions), resolvedOptions.typescript); - return () => new Promise((resolve, reject) => compilationGulp - .fork(resolvedOptions.verbose) - .start(taskName, err => err ? reject(err) : resolve())); + return () => start(taskName); } exports.createCompiler = createCompiler; @@ -139,9 +113,7 @@ function createCleaner(projectSpec, options) { const projectGraph = getOrCreateProjectGraph(resolvedProjectSpec, paths); projectGraph.isRoot = true; const taskName = cleanTaskName(ensureCleanTask(projectGraph)); - return () => new Promise((resolve, reject) => compilationGulp - .fork() - .start(taskName, err => err ? reject(err) : resolve())); + return () => start(taskName); } exports.createCleaner = createCleaner; @@ -811,7 +783,7 @@ function possiblyTriggerRecompilation(config, task) { function triggerRecompilation(task, config) { compilationGulp._resetTask(task); if (config.watchers && config.watchers.size) { - compilationGulp.fork().start(task.name, () => { + start(task.name, () => { /** @type {Set} */ const taskNames = new Set(); /** @type {((err?: any) => void)[]} */ @@ -831,7 +803,7 @@ function triggerRecompilation(task, config) { }); } else { - compilationGulp.fork(/*verbose*/ true).start(task.name); + start(task.name); } }