Skip to content

Commit

Permalink
fix: evaluate shell if Node.js is not in PATH
Browse files Browse the repository at this point in the history
  • Loading branch information
mxschmitt committed Jan 9, 2024
1 parent 68472bc commit 054b4be
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 7 deletions.
4 changes: 2 additions & 2 deletions src/playwrightTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ export class PlaywrightTest {
// Playwright will restart itself as child process in the ESM mode and won't inherit the 3/4 pipes.
// Always use ws transport to mitigate it.
const reporterServer = new ReporterServer(this._vscode);
const node = await findNode();
const node = await findNode(this._vscode);
if (token?.isCancellationRequested)
return;
const configFolder = path.dirname(config.configFile);
Expand Down Expand Up @@ -269,7 +269,7 @@ export class PlaywrightTest {
}

private async _runNode(args: string[], cwd: string): Promise<string> {
return await spawnAsync(await findNode(), args, cwd, this._envProvider());
return await spawnAsync(await findNode(this._vscode), args, cwd, this._envProvider());
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/reusedBrowser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ export class ReusedBrowser implements vscodeTypes.Disposable {
return;
}

const node = await findNode();
const node = await findNode(this._vscode);
const allArgs = [
config.cli,
'run-server',
Expand Down
2 changes: 1 addition & 1 deletion src/traceViewer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ export class TraceViewer implements vscodeTypes.Disposable {
}

private async _startIfNeeded(config: TestConfig, file: string) {
const node = await findNode();
const node = await findNode(this._vscode);
if (this._traceViewerProcess)
return;
const allArgs = [config.cli, 'show-trace', `--stdin`];
Expand Down
33 changes: 30 additions & 3 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,18 +138,45 @@ export async function resolveSourceMap(file: string, fileToSources: Map<string,

let pathToNodeJS: string | undefined;

export async function findNode(): Promise<string> {
export async function findNode(vscode: typeof import('vscode')): Promise<string> {
if (pathToNodeJS)
return pathToNodeJS;

// Stage 1: try to find node via process.env.PATH
let node = await which('node').catch(e => undefined);
// When extension host boots, it does not have the right env set, so we might need to wait.
// Stage 2: When extension host boots, it does not have the right env set, so we might need to wait.
for (let i = 0; i < 5 && !node; ++i) {
await new Promise(f => setTimeout(f, 1000));
await new Promise(f => setTimeout(f, 200));
node = await which('node').catch(e => undefined);
}
// Stage 3: If we still haven't found node, try to find it via a subprocess.
// This evaluates shell rc/profile files and makes nvm work.
node ??= await findNodeViaSubProcess(vscode);
if (!node)
throw new Error('Unable to launch `node`, make sure it is in your PATH');
pathToNodeJS = node;
return node;
}

async function findNodeViaSubProcess(vscode: typeof import('vscode')): Promise<string | undefined> {
return new Promise<string | undefined>(resolve => {
const startToken = '___START_PW_SHELL__';
const endToken = '___END_PW_SHELL__';
const childProcess = spawn(`${vscode.env.shell} -i -c 'echo ${startToken} && which node && echo ${endToken}'`, {
stdio: 'pipe',
shell: true
});
let output = '';
childProcess.stdout.on('data', data => output += data.toString());
childProcess.on('error', () => resolve(undefined));
childProcess.on('exit', exitCode => {
if (exitCode !== 0)
return resolve(undefined);
const start = output.indexOf(startToken);
const end = output.indexOf(endToken);
if (start === -1 || end === -1)
return resolve(undefined);
return resolve(output.substring(start + startToken.length, end).trim());
});
});
}

0 comments on commit 054b4be

Please sign in to comment.