From b350b1c51dac3651f9aa8f1833506d083912064d Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Mon, 14 Nov 2016 14:57:12 -0800 Subject: [PATCH 1/5] treat failures to resolve module name as missing packages (#12237) --- .../typingsInstaller/typingsInstaller.ts | 28 +++++++++++-------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/src/server/typingsInstaller/typingsInstaller.ts b/src/server/typingsInstaller/typingsInstaller.ts index 2ea0296e22a75..548aec4777ff5 100644 --- a/src/server/typingsInstaller/typingsInstaller.ts +++ b/src/server/typingsInstaller/typingsInstaller.ts @@ -19,9 +19,17 @@ namespace ts.server.typingsInstaller { writeLine: noop }; - function typingToFileName(cachePath: string, packageName: string, installTypingHost: InstallTypingHost): string { - const result = resolveModuleName(packageName, combinePaths(cachePath, "index.d.ts"), { moduleResolution: ModuleResolutionKind.NodeJs }, installTypingHost); - return result.resolvedModule && result.resolvedModule.resolvedFileName; + function typingToFileName(cachePath: string, packageName: string, installTypingHost: InstallTypingHost, log: Log): string { + try { + const result = resolveModuleName(packageName, combinePaths(cachePath, "index.d.ts"), { moduleResolution: ModuleResolutionKind.NodeJs }, installTypingHost); + return result.resolvedModule && result.resolvedModule.resolvedFileName; + } + catch (e) { + if (log.isEnabled()) { + log.writeLine(`Failed to resolve ${packageName} in folder '${cachePath}': ${(e).message}`); + } + return undefined; + } } export enum PackageNameValidationResult { @@ -192,8 +200,9 @@ namespace ts.server.typingsInstaller { if (!packageName) { continue; } - const typingFile = typingToFileName(cacheLocation, packageName, this.installTypingHost); + const typingFile = typingToFileName(cacheLocation, packageName, this.installTypingHost, this.log); if (!typingFile) { + this.missingTypingsSet[packageName] = true; continue; } const existingTypingFile = this.packageNameToTypingLocation[packageName]; @@ -321,16 +330,13 @@ namespace ts.server.typingsInstaller { // TODO: watch project directory if (this.log.isEnabled()) { - this.log.writeLine(`Requested to install typings ${JSON.stringify(scopedTypings)}, installed typings ${JSON.stringify(scopedTypings)}`); + this.log.writeLine(`Installed typings ${JSON.stringify(scopedTypings)}`); } const installedTypingFiles: string[] = []; - for (const t of scopedTypings) { - const packageName = getBaseFileName(t); - if (!packageName) { - continue; - } - const typingFile = typingToFileName(cachePath, packageName, this.installTypingHost); + for (const packageName of filteredTypings) { + const typingFile = typingToFileName(cachePath, packageName, this.installTypingHost, this.log); if (!typingFile) { + this.missingTypingsSet[packageName] = true; continue; } if (!this.packageNameToTypingLocation[packageName]) { From 18db87c6d35980eec9386a74a295040eed092587 Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Tue, 15 Nov 2016 10:59:55 -0800 Subject: [PATCH 2/5] added extra check to prevent multiple installation of the same typing, added version field to telemetry event (#12258) * added extra check to prevent multiple installation of the same typing, added version field to telemetry event * use ts.version --- src/compiler/core.ts | 3 +++ src/compiler/program.ts | 4 ---- src/server/protocol.ts | 5 +++++ src/server/server.ts | 3 ++- src/server/types.d.ts | 1 + src/server/typingsInstaller/typingsInstaller.ts | 5 +++-- 6 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/compiler/core.ts b/src/compiler/core.ts index f647480979b3f..ad440ca694ad3 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -3,6 +3,9 @@ /* @internal */ namespace ts { + + export const version = "2.0.9"; + /** * Ternary values are defined such that * x & y is False if either x or y is False. diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 85c27a6383977..041923a885766 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -3,10 +3,6 @@ /// namespace ts { - /** The version of the TypeScript compiler release */ - - export const version = "2.2.0"; - const emptyArray: any[] = []; export function findConfigFile(searchPath: string, fileExists: (fileName: string) => boolean, configName = "tsconfig.json"): string { diff --git a/src/server/protocol.ts b/src/server/protocol.ts index 0d9a0a76d7aa2..dad66f3cc7175 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -2106,6 +2106,11 @@ namespace ts.server.protocol { * true if install request succeeded, otherwise - false */ installSuccess: boolean; + + /** + * version of typings installer + */ + typingsInstallerVersion: string; } export interface NavBarResponse extends Response { diff --git a/src/server/server.ts b/src/server/server.ts index c561277c7d2e5..220b0d90c65e6 100644 --- a/src/server/server.ts +++ b/src/server/server.ts @@ -300,7 +300,8 @@ namespace ts.server { telemetryEventName: "typingsInstalled", payload: { installedPackages: response.packagesToInstall.join(","), - installSuccess: response.installSuccess + installSuccess: response.installSuccess, + typingsInstallerVersion: response.typingsInstallerVersion } }; const eventName: protocol.TelemetryEventName = "telemetry"; diff --git a/src/server/types.d.ts b/src/server/types.d.ts index 3fd90e7fd3ec8..a4032bf062e8c 100644 --- a/src/server/types.d.ts +++ b/src/server/types.d.ts @@ -69,6 +69,7 @@ declare namespace ts.server { readonly packagesToInstall: ReadonlyArray; readonly kind: EventInstall; readonly installSuccess: boolean; + readonly typingsInstallerVersion: string; } export interface InstallTypingHost extends JsTyping.TypingResolutionHost { diff --git a/src/server/typingsInstaller/typingsInstaller.ts b/src/server/typingsInstaller/typingsInstaller.ts index 548aec4777ff5..677e2c7bba098 100644 --- a/src/server/typingsInstaller/typingsInstaller.ts +++ b/src/server/typingsInstaller/typingsInstaller.ts @@ -233,7 +233,7 @@ namespace ts.server.typingsInstaller { } const result: string[] = []; for (const typing of typingsToInstall) { - if (this.missingTypingsSet[typing]) { + if (this.missingTypingsSet[typing] || this.packageNameToTypingLocation[typing]) { continue; } const validationResult = validatePackageName(typing); @@ -314,7 +314,8 @@ namespace ts.server.typingsInstaller { this.sendResponse({ kind: EventInstall, packagesToInstall: scopedTypings, - installSuccess: ok + installSuccess: ok, + typingsInstallerVersion: ts.version // qualified explicitly to prevent occasional shadowing }); } From 7a663e960a801e28d5e6c4ccd470e1276e10a50a Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Tue, 15 Nov 2016 11:00:20 -0800 Subject: [PATCH 3/5] switch to execSync to ensure that no install orders are interleaved (#12259) --- src/compiler/core.ts | 4 +- .../typingsInstaller/nodeTypingsInstaller.ts | 38 ++++++++++--------- 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/src/compiler/core.ts b/src/compiler/core.ts index ad440ca694ad3..d19fce0005437 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -4,7 +4,9 @@ /* @internal */ namespace ts { - export const version = "2.0.9"; + /** The version of the TypeScript compiler release */ + + export const version = "2.2.0"; /** * Ternary values are defined such that diff --git a/src/server/typingsInstaller/nodeTypingsInstaller.ts b/src/server/typingsInstaller/nodeTypingsInstaller.ts index 74311dae4e265..bdfdda3033cb8 100644 --- a/src/server/typingsInstaller/nodeTypingsInstaller.ts +++ b/src/server/typingsInstaller/nodeTypingsInstaller.ts @@ -61,17 +61,12 @@ namespace ts.server.typingsInstaller { return combinePaths(normalizeSlashes(globalTypingsCacheLocation), `node_modules/${TypesRegistryPackageName}/index.json`); } - - type Exec = { - (command: string, options: { cwd: string }, callback?: (error: Error, stdout: string, stderr: string) => void): any - }; - type ExecSync = { - (command: string, options: { cwd: string, stdio: "ignore" }): any - }; + (command: string, options: { cwd: string, stdio?: "ignore" }): any + } export class NodeTypingsInstaller extends TypingsInstaller { - private readonly exec: Exec; + private readonly execSync: ExecSync; private readonly npmPath: string; readonly typesRegistry: Map; @@ -87,8 +82,7 @@ namespace ts.server.typingsInstaller { this.log.writeLine(`Process id: ${process.pid}`); } this.npmPath = getNPMLocation(process.argv[0]); - let execSync: ExecSync; - ({ exec: this.exec, execSync } = require("child_process")); + ({ execSync: this.execSync } = require("child_process")); this.ensurePackageDirectoryExists(globalTypingsCacheLocation); @@ -96,7 +90,7 @@ namespace ts.server.typingsInstaller { if (this.log.isEnabled()) { this.log.writeLine(`Updating ${TypesRegistryPackageName} npm package...`); } - execSync(`${this.npmPath} install ${TypesRegistryPackageName}`, { cwd: globalTypingsCacheLocation, stdio: "ignore" }); + this.execSync(`${this.npmPath} install ${TypesRegistryPackageName}`, { cwd: globalTypingsCacheLocation, stdio: "ignore" }); } catch (e) { if (this.log.isEnabled()) { @@ -135,13 +129,21 @@ namespace ts.server.typingsInstaller { } const command = `${this.npmPath} install ${args.join(" ")} --save-dev`; const start = Date.now(); - this.exec(command, { cwd }, (err, stdout, stderr) => { - if (this.log.isEnabled()) { - this.log.writeLine(`npm install #${requestId} took: ${Date.now() - start} ms${sys.newLine}stdout: ${stdout}${sys.newLine}stderr: ${stderr}`); - } - // treat absence of error as success - onRequestCompleted(!err); - }); + let stdout: Buffer; + let stderr: Buffer; + let hasError = false; + try { + stdout = this.execSync(command, { cwd }); + } + catch (e) { + stdout = e.stdout; + stderr = e.stderr; + hasError = true; + } + if (this.log.isEnabled()) { + this.log.writeLine(`npm install #${requestId} took: ${Date.now() - start} ms${sys.newLine}stdout: ${stdout && stdout.toString()}${sys.newLine}stderr: ${stderr && stderr.toString()}`); + } + onRequestCompleted(!hasError); } } From b55c4120efe67cc70db1a2ef9e25d881f8a35241 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Tue, 15 Nov 2016 11:53:01 -0800 Subject: [PATCH 4/5] Make sure version is public --- src/compiler/core.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/compiler/core.ts b/src/compiler/core.ts index d19fce0005437..92feb5414acdb 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -1,13 +1,13 @@ /// /// -/* @internal */ namespace ts { - /** The version of the TypeScript compiler release */ - export const version = "2.2.0"; +} +/* @internal */ +namespace ts { /** * Ternary values are defined such that * x & y is False if either x or y is False. From fb026f32f6348c2980fceb30b75a32ea79815018 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Tue, 15 Nov 2016 11:53:30 -0800 Subject: [PATCH 5/5] Update file with version string for nightly release --- Gulpfile.ts | 4 ++-- Jakefile.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Gulpfile.ts b/Gulpfile.ts index d7e20a557fd78..054e99c80037e 100644 --- a/Gulpfile.ts +++ b/Gulpfile.ts @@ -177,7 +177,7 @@ for (const i in libraryTargets) { const configureNightlyJs = path.join(scriptsDirectory, "configureNightly.js"); const configureNightlyTs = path.join(scriptsDirectory, "configureNightly.ts"); const packageJson = "package.json"; -const programTs = path.join(compilerDirectory, "program.ts"); +const versionFile = path.join(compilerDirectory, "core.ts"); function needsUpdate(source: string | string[], dest: string | string[]): boolean { if (typeof source === "string" && typeof dest === "string") { @@ -285,7 +285,7 @@ gulp.task(configureNightlyJs, false, [], () => { // Nightly management tasks gulp.task("configure-nightly", "Runs scripts/configureNightly.ts to prepare a build for nightly publishing", [configureNightlyJs], (done) => { - exec(host, [configureNightlyJs, packageJson, programTs], done, done); + exec(host, [configureNightlyJs, packageJson, versionFile], done, done); }); gulp.task("publish-nightly", "Runs `npm publish --tag next` to create a new nightly build on npm", ["LKG"], () => { return runSequence("clean", "useDebugMode", "runtests", (done) => { diff --git a/Jakefile.js b/Jakefile.js index 2e5d660c4f1d9..646f6e00bcfac 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -593,7 +593,7 @@ task("generate-diagnostics", [diagnosticInfoMapTs]); var configureNightlyJs = path.join(scriptsDirectory, "configureNightly.js"); var configureNightlyTs = path.join(scriptsDirectory, "configureNightly.ts"); var packageJson = "package.json"; -var programTs = path.join(compilerDirectory, "program.ts"); +var versionFile = path.join(compilerDirectory, "core.ts"); file(configureNightlyTs); @@ -609,7 +609,7 @@ task("setDebugMode", function () { }); task("configure-nightly", [configureNightlyJs], function () { - var cmd = host + " " + configureNightlyJs + " " + packageJson + " " + programTs; + var cmd = host + " " + configureNightlyJs + " " + packageJson + " " + versionFile; console.log(cmd); exec(cmd); }, { async: true });