Skip to content

Commit 47bd5af

Browse files
author
Andy
authored
Allow configurable npmLocation for typingsInstaller (#16084) (#16102)
* Allow configurable npmLocation for typingsInstaller * Undo "export class" changes * Add log for npmLocation * Log whether '--npmLocation' was provided
1 parent d333378 commit 47bd5af

File tree

3 files changed

+34
-20
lines changed

3 files changed

+34
-20
lines changed

src/server/server.ts

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ namespace ts.server {
1313
globalTypingsCacheLocation: string;
1414
logger: Logger;
1515
typingSafeListLocation: string;
16+
npmLocation: string | undefined;
1617
telemetryEnabled: boolean;
1718
globalPlugins: string[];
1819
pluginProbeLocations: string[];
@@ -234,6 +235,7 @@ namespace ts.server {
234235
eventPort: number,
235236
readonly globalTypingsCacheLocation: string,
236237
readonly typingSafeListLocation: string,
238+
private readonly npmLocation: string | undefined,
237239
private newLine: string) {
238240
this.throttledOperations = new ThrottledOperations(host);
239241
if (eventPort) {
@@ -278,19 +280,21 @@ namespace ts.server {
278280
if (this.typingSafeListLocation) {
279281
args.push(Arguments.TypingSafeListLocation, this.typingSafeListLocation);
280282
}
283+
if (this.npmLocation) {
284+
args.push(Arguments.NpmLocation, this.npmLocation);
285+
}
286+
281287
const execArgv: string[] = [];
282-
{
283-
for (const arg of process.execArgv) {
284-
const match = /^--(debug|inspect)(=(\d+))?$/.exec(arg);
285-
if (match) {
286-
// if port is specified - use port + 1
287-
// otherwise pick a default port depending on if 'debug' or 'inspect' and use its value + 1
288-
const currentPort = match[3] !== undefined
289-
? +match[3]
290-
: match[1] === "debug" ? 5858 : 9229;
291-
execArgv.push(`--${match[1]}=${currentPort + 1}`);
292-
break;
293-
}
288+
for (const arg of process.execArgv) {
289+
const match = /^--(debug|inspect)(=(\d+))?$/.exec(arg);
290+
if (match) {
291+
// if port is specified - use port + 1
292+
// otherwise pick a default port depending on if 'debug' or 'inspect' and use its value + 1
293+
const currentPort = match[3] !== undefined
294+
? +match[3]
295+
: match[1] === "debug" ? 5858 : 9229;
296+
execArgv.push(`--${match[1]}=${currentPort + 1}`);
297+
break;
294298
}
295299
}
296300

@@ -389,10 +393,10 @@ namespace ts.server {
389393

390394
class IOSession extends Session {
391395
constructor(options: IOSessionOptions) {
392-
const { host, installerEventPort, globalTypingsCacheLocation, typingSafeListLocation, canUseEvents } = options;
396+
const { host, installerEventPort, globalTypingsCacheLocation, typingSafeListLocation, npmLocation, canUseEvents } = options;
393397
const typingsInstaller = disableAutomaticTypingAcquisition
394398
? undefined
395-
: new NodeTypingsInstaller(telemetryEnabled, logger, host, installerEventPort, globalTypingsCacheLocation, typingSafeListLocation, host.newLine);
399+
: new NodeTypingsInstaller(telemetryEnabled, logger, host, installerEventPort, globalTypingsCacheLocation, typingSafeListLocation, npmLocation, host.newLine);
396400

397401
super({
398402
host,
@@ -742,7 +746,8 @@ namespace ts.server {
742746
validateLocaleAndSetLanguage(localeStr, sys);
743747
}
744748

745-
const typingSafeListLocation = findArgument("--typingSafeListLocation");
749+
const typingSafeListLocation = findArgument(Arguments.TypingSafeListLocation);
750+
const npmLocation = findArgument(Arguments.NpmLocation);
746751

747752
const globalPlugins = (findArgument("--globalPlugins") || "").split(",");
748753
const pluginProbeLocations = (findArgument("--pluginProbeLocations") || "").split(",");
@@ -761,6 +766,7 @@ namespace ts.server {
761766
disableAutomaticTypingAcquisition,
762767
globalTypingsCacheLocation: getGlobalTypingsCacheLocation(),
763768
typingSafeListLocation,
769+
npmLocation,
764770
telemetryEnabled,
765771
logger,
766772
globalPlugins,

src/server/shared.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,18 @@ namespace ts.server {
1212
export const LogFile = "--logFile";
1313
export const EnableTelemetry = "--enableTelemetry";
1414
export const TypingSafeListLocation = "--typingSafeListLocation";
15+
/**
16+
* This argument specifies the location of the NPM executable.
17+
* typingsInstaller will run the command with `${npmLocation} install ...`.
18+
*/
19+
export const NpmLocation = "--npmLocation";
1520
}
1621

1722
export function hasArgument(argumentName: string) {
1823
return sys.args.indexOf(argumentName) >= 0;
1924
}
2025

21-
export function findArgument(argumentName: string) {
26+
export function findArgument(argumentName: string): string | undefined {
2227
const index = sys.args.indexOf(argumentName);
2328
return index >= 0 && index < sys.args.length - 1
2429
? sys.args[index + 1]

src/server/typingsInstaller/nodeTypingsInstaller.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ namespace ts.server.typingsInstaller {
3030
}
3131
}
3232

33-
function getNPMLocation(processName: string) {
33+
/** Used if `--npmLocation` is not passed. */
34+
function getDefaultNPMLocation(processName: string) {
3435
if (path.basename(processName).indexOf("node") === 0) {
3536
return `"${path.join(path.dirname(process.argv[0]), "npm")}"`;
3637
}
@@ -76,17 +77,18 @@ namespace ts.server.typingsInstaller {
7677

7778
private delayedInitializationError: InitializationFailedResponse;
7879

79-
constructor(globalTypingsCacheLocation: string, typingSafeListLocation: string, throttleLimit: number, log: Log) {
80+
constructor(globalTypingsCacheLocation: string, typingSafeListLocation: string, npmLocation: string | undefined, throttleLimit: number, log: Log) {
8081
super(
8182
sys,
8283
globalTypingsCacheLocation,
8384
typingSafeListLocation ? toPath(typingSafeListLocation, "", createGetCanonicalFileName(sys.useCaseSensitiveFileNames)) : toPath("typingSafeList.json", __dirname, createGetCanonicalFileName(sys.useCaseSensitiveFileNames)),
8485
throttleLimit,
8586
log);
87+
this.npmPath = npmLocation !== undefined ? npmLocation : getDefaultNPMLocation(process.argv[0]);
8688
if (this.log.isEnabled()) {
8789
this.log.writeLine(`Process id: ${process.pid}`);
90+
this.log.writeLine(`NPM location: ${this.npmPath} (explicit '${Arguments.NpmLocation}' ${npmLocation === undefined ? "not " : ""} provided)`);
8891
}
89-
this.npmPath = getNPMLocation(process.argv[0]);
9092
({ execSync: this.execSync } = require("child_process"));
9193

9294
this.ensurePackageDirectoryExists(globalTypingsCacheLocation);
@@ -165,6 +167,7 @@ namespace ts.server.typingsInstaller {
165167
const logFilePath = findArgument(server.Arguments.LogFile);
166168
const globalTypingsCacheLocation = findArgument(server.Arguments.GlobalCacheLocation);
167169
const typingSafeListLocation = findArgument(server.Arguments.TypingSafeListLocation);
170+
const npmLocation = findArgument(server.Arguments.NpmLocation);
168171

169172
const log = new FileLog(logFilePath);
170173
if (log.isEnabled()) {
@@ -178,6 +181,6 @@ namespace ts.server.typingsInstaller {
178181
}
179182
process.exit(0);
180183
});
181-
const installer = new NodeTypingsInstaller(globalTypingsCacheLocation, typingSafeListLocation, /*throttleLimit*/5, log);
184+
const installer = new NodeTypingsInstaller(globalTypingsCacheLocation, typingSafeListLocation, npmLocation, /*throttleLimit*/5, log);
182185
installer.listen();
183186
}

0 commit comments

Comments
 (0)