src/vs/platform/shell/node/shellEnv.ts

222 LOC · 41 covered · 181 uncovered · 4 ranges · 44 concepts · 2 introducers · 32 tests

File neighbourhood

The centred file is linked to every concept that introduces one of its ranges, every test that runs code from the file, and the gray connector concepts standing between those tests and the file's own introducer concepts. Undirected links join concepts to every file where they introduce source and concepts to the tests they introduce; arrows show specialization between the displayed concepts and bridge only concepts omitted from this view. Concept colors match the source ranges below; connector concepts have no source color and are shown in gray.

Focused file, its introducer and connector concepts, their introduced files, and tests that run code from the file

In the embedded map, ordinary wheel input scrolls the page; use the visible controls to zoom and drag to pan. Open the full-screen map for canvas navigation: wheel pans, Ctrl/Command plus wheel zooms, and arrow keys pan when this region is focused. On touch screens, open the full-screen map to pan or pinch. If JavaScript or WebGL is unavailable, use the related-file, concept, and source links on this page.

Focused file, its introducer and connector concepts, their introduced files, and tests that run code from the filesrc/vs/base/node/pfs.ts · 866 LOCnode/pfs.tssrc/vs/platform/agentHost/node/agentSdkDownloader.ts · 626 LOCnode/agentSdkDownloader.…src/vs/platform/files/common/fileService.ts · 1491 LOCcommon/fileService.tssrc/vs/platform/files/node/diskFileSystemProvider.ts · 898 LOCnode/diskFileSystemProvi…src/vs/platform/request/node/proxy.ts · 54 LOCnode/proxy.tssrc/vs/platform/request/node/requestService.ts · 296 LOCnode/requestService.tsagentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: cache hit returns immediately without re-downloading|occurrence=1 · 0 introduced LOCagentSdkDownloader.test|…diskFileSystemProvider.ts ×11 · 79 introduced LOCdiskFileSystemProvider.t…agentSdkDownloader.ts ×3 · 28 introduced LOCagentSdkDownloader.ts ×3diskFileSystemProvider.ts ×20 · 260 introduced LOCdiskFileSystemProvider.t…agentSdkDownloader.ts ×1 · 2 introduced LOCagentSdkDownloader.ts ×1agentSdkDownloader.ts ×1 · 2 introduced LOCagentSdkDownloader.ts ×1agentSdkDownloader.ts ×2 · 20 introduced LOCagentSdkDownloader.ts ×2agentSdkDownloader.ts ×1 · 6 introduced LOCagentSdkDownloader.ts ×1agentSdkDownloader.ts ×2 · 8 introduced LOCagentSdkDownloader.ts ×2agentSdkDownloader.ts ×1 · 5 introduced LOCagentSdkDownloader.ts ×1agentSdkDownloader.ts ×2 · 8 introduced LOCagentSdkDownloader.ts ×2agentSdkDownloader.ts ×5 · 10 introduced LOCagentSdkDownloader.ts ×5agentSdkDownloader.ts ×1 · 3 introduced LOCagentSdkDownloader.ts ×1agentSdkDownloader.ts ×3 · 5 introduced LOCagentSdkDownloader.ts ×3agentSdkDownloader.test|title=AgentSdkDownloader isAvailable: true when product config populated and host has a target|occurrence=1 · 0 introduced LOCagentSdkDownloader.test|…agentSdkDownloader.ts ×1 · 2 introduced LOCagentSdkDownloader.ts ×1agentSdkDownloader.ts ×2 · 3 introduced LOCagentSdkDownloader.ts ×2agentSdkDownloader.ts ×1 · 8 introduced LOCagentSdkDownloader.ts ×1agentSdkDownloader.ts ×1 · 2 introduced LOCagentSdkDownloader.ts ×1agentSdkDownloader.ts ×1 · 2 introduced LOCagentSdkDownloader.ts ×1agentSdkDownloader.ts ×1 · 2 introduced LOCagentSdkDownloader.ts ×1agentSdkDownloader.ts ×2 · 5 introduced LOCagentSdkDownloader.ts ×2ptyHostService.ts ×54 · 735 introduced LOCptyHostService.ts ×54agentHostRequestService.ts ×2 · 7 introduced LOCagentHostRequestService.…agentHostRequestService.ts ×4 · 10 introduced LOCagentHostRequestService.…agentHostRequestService.ts ×6 · 32 introduced LOCagentHostRequestService.…agentHostRequestService.ts ×2 · 4 introduced LOCagentHostRequestService.…agentHostRequestService.ts ×1 · 2 introduced LOCagentHostRequestService.…agentHostRequestService.ts ×1 · 2 introduced LOCagentHostRequestService.…agentHostRequestService.ts ×5 · 8 introduced LOCagentHostRequestService.…agentHostRequestService.ts ×12 · 46 introduced LOCagentHostRequestService.…requestService.ts ×5 · 18 introduced LOCrequestService.ts ×5networkDiagnosticsService.ts ×11 · 83 introduced LOCnetworkDiagnosticsServic…agentHostClientProxyChannel.ts ×4 · 26 introduced LOCagentHostClientProxyChan…agentHostRequestService.ts ×11 · 179 introduced LOCagentHostRequestService.…requestService.ts ×1 · 4 introduced LOCrequestService.ts ×1requestService.ts ×1 · 1 introduced LOCrequestService.ts ×1requestService.ts ×3 · 14 introduced LOCrequestService.ts ×3requestService.ts ×2 · 7 introduced LOCrequestService.ts ×2requestService.ts ×1 · 2 introduced LOCrequestService.ts ×1requestService.ts ×3 · 5 introduced LOCrequestService.ts ×3requestService.ts ×11 · 51 introduced LOCrequestService.ts ×11requestService.ts ×13 · 96 introduced LOCrequestService.ts ×13shellEnv.ts ×2 · 32 introduced LOCshellEnv.ts ×2agentHostRequestService.test|title=AgentHostRequestService does not retry non-idempotent requests|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentHostRequestService.test|title=AgentHostRequestService does not retry non-idempotent requests|occurrence=1agentHostRequestService.…agentHostRequestService.test|title=AgentHostRequestService forwards cancellation to resolver fetch|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentHostRequestService.test|title=AgentHostRequestService forwards cancellation to resolver fetch|occurrence=1agentHostRequestService.…agentHostRequestService.test|title=AgentHostRequestService forwards proxy and authorization lookups through the client channel|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentHostRequestService.test|title=AgentHostRequestService forwards proxy and authorization lookups through the client channel|occurrence=1agentHostRequestService.…agentHostRequestService.test|title=AgentHostRequestService retries idempotent requests on transient errors|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentHostRequestService.test|title=AgentHostRequestService retries idempotent requests on transient errors|occurrence=1agentHostRequestService.…agentHostRequestService.test|title=AgentHostRequestService uses resolver fetch and streams the response|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentHostRequestService.test|title=AgentHostRequestService uses resolver fetch and streams the response|occurrence=1agentHostRequestService.…agentHostRequestService.test|title=NetworkDiagnosticsService includes nested proxy response errors|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentHostRequestService.test|title=NetworkDiagnosticsService includes nested proxy response errors|occurrence=1agentHostRequestService.…agentSdkDownloader.test|title=AgentSdkDownloader isAvailable: false when no env override and no product config|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentSdkDownloader.test|title=AgentSdkDownloader isAvailable: false when no env override and no product config|occurrence=1agentSdkDownloader.test|…agentSdkDownloader.test|title=AgentSdkDownloader isAvailable: true when env override set|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentSdkDownloader.test|title=AgentSdkDownloader isAvailable: true when env override set|occurrence=1agentSdkDownloader.test|…agentSdkDownloader.test|title=AgentSdkDownloader isAvailable: true when product config populated and host has a target|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentSdkDownloader.test|title=AgentSdkDownloader isAvailable: true when product config populated and host has a target|occurrence=1agentSdkDownloader.test|…agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: cache dir includes sdkTarget so Universal launches stay separate|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: cache dir includes sdkTarget so Universal launches stay separate|occurrence=1agentSdkDownloader.test|…agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: cache hit returns immediately without re-downloading|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: cache hit returns immediately without re-downloading|occurrence=1agentSdkDownloader.test|…agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: cache miss → downloads, extracts, writes sentinel|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: cache miss → downloads, extracts, writes sentinel|occurrence=1agentSdkDownloader.test|…agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: cancel before download completes cleans up scratch dir|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: cancel before download completes cleans up scratch dir|occurrence=1agentSdkDownloader.test|…agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: concurrent calls in same process share one download|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: concurrent calls in same process share one download|occurrence=1agentSdkDownloader.test|…agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: dev override returns the path unchanged|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: dev override returns the path unchanged|occurrence=1agentSdkDownloader.test|…agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: missing product config and no env override throws actionable error|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: missing product config and no env override throws actionable error|occurrence=1agentSdkDownloader.test|…agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: rename-loser path returns existing cache when winner already published|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: rename-loser path returns existing cache when winner already published|occurrence=1agentSdkDownloader.test|…agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: reports monotonic download progress ending at totalBytes|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: reports monotonic download progress ending at totalBytes|occurrence=1agentSdkDownloader.test|…agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: substitutes {sdkTarget} into urlTemplate|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: substitutes {sdkTarget} into urlTemplate|occurrence=1agentSdkDownloader.test|…agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: urlTemplate with unknown placeholder throws config error|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: urlTemplate with unknown placeholder throws config error|occurrence=1agentSdkDownloader.test|…agentSdkDownloader.test|title=resolveSdkTarget appends -musl on musl Linux iff the package has separate musl SKUs|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentSdkDownloader.test|title=resolveSdkTarget appends -musl on musl Linux iff the package has separate musl SKUs|occurrence=1agentSdkDownloader.test|…agentSdkDownloader.test|title=resolveSdkTarget returns <platform>-<arch> for supported (platform, arch)|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentSdkDownloader.test|title=resolveSdkTarget returns <platform>-<arch> for supported (platform, arch)|occurrence=1agentSdkDownloader.test|…agentSdkDownloader.test|title=resolveSdkTarget returns undefined for unsupported (platform, arch)|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentSdkDownloader.test|title=resolveSdkTarget returns undefined for unsupported (platform, arch)|occurrence=1agentSdkDownloader.test|…requestService.test|title=Request Service Request cancellation during retry backoff|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/request/test/node/requestService.test|title=Request Service Request cancellation during retry backoff|occurrence=1requestService.test|titl…requestService.test|title=Request Service should NOT retry DELETE requests|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/request/test/node/requestService.test|title=Request Service should NOT retry DELETE requests|occurrence=1requestService.test|titl…requestService.test|title=Request Service should NOT retry PATCH requests|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/request/test/node/requestService.test|title=Request Service should NOT retry PATCH requests|occurrence=1requestService.test|titl…requestService.test|title=Request Service should NOT retry POST requests|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/request/test/node/requestService.test|title=Request Service should NOT retry POST requests|occurrence=1requestService.test|titl…requestService.test|title=Request Service should NOT retry PUT requests|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/request/test/node/requestService.test|title=Request Service should NOT retry PUT requests|occurrence=1requestService.test|titl…requestService.test|title=Request Service should retry GET requests on transient errors|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/request/test/node/requestService.test|title=Request Service should retry GET requests on transient errors|occurrence=1requestService.test|titl…requestService.test|title=Request Service should retry HEAD requests on transient errors|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/request/test/node/requestService.test|title=Request Service should retry HEAD requests on transient errors|occurrence=1requestService.test|titl…requestService.test|title=Request Service should retry OPTIONS requests on transient errors|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/request/test/node/requestService.test|title=Request Service should retry OPTIONS requests on transient errors|occurrence=1requestService.test|titl…ptyHostService.test|title=PtyHostService restartPtyHost disposes listeners registered during pty host startup|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/terminal/test/node/ptyHostService.test|title=PtyHostService restartPtyHost disposes listeners registered during pty host startup|occurrence=1ptyHostService.test|titl…Focused file · src/vs/platform/shell/node/shellEnv.ts · 222 LOCnode/shellEnv.ts

Graph controls are ready.

Interactive rendering requires JavaScript and WebGL. Use the related-file, concept, and source links on this page while the interactive map is unavailable.

1 > /*--------------------------------------------------------------------------------------------- shellEnv.ts ×2
2 > * Copyright (c) Microsoft Corporation. All rights reserved.
3 > * Licensed under the MIT License. See License.txt in the project root for license information.
4 > *--------------------------------------------------------------------------------------------*/
5 >
6 > import { spawn } from 'child_process';
7 > import { basename } from '../../../base/common/path.js';
8 > import { localize } from '../../../nls.js';
9 > import { CancellationToken, CancellationTokenSource } from '../../../base/common/cancellation.js';
10 > import { toErrorMessage } from '../../../base/common/errorMessage.js';
11 > import { CancellationError, isCancellationError } from '../../../base/common/errors.js';
12 > import { IProcessEnvironment, isWindows, OS } from '../../../base/common/platform.js';
13 > import { generateUuid } from '../../../base/common/uuid.js';
14 > import { getSystemShell } from '../../../base/node/shell.js';
15 > import { NativeParsedArgs } from '../../environment/common/argv.js';
16 > import { isLaunchedFromCli } from '../../environment/node/argvHelper.js';
17 > import { ILogService } from '../../log/common/log.js';
18 > import { Promises } from '../../../base/common/async.js';
19 > import { IConfigurationService } from '../../configuration/common/configuration.js';
20 > import { clamp } from '../../../base/common/numbers.js';
21 >
22 > let unixShellEnvPromise: Promise<typeof process.env> | undefined = undefined;
23 >
24 > /**
25 > * Resolves the shell environment by spawning a shell. This call will cache
26 > * the shell spawning so that subsequent invocations use that cached result.
27 > *
28 > * Will throw an error if:
29 > * - we hit a timeout of `MAX_SHELL_RESOLVE_TIME`
30 > * - any other error from spawning a shell to figure out the environment
31 > */
32 > export async function getResolvedShellEnv(configurationService: IConfigurationService, logService: ILogService, args: NativeParsedArgs, env: IProcessEnvironment): Promise<typeof process.env> { diskFileSystemProvider.ts ×20
33 >
34 > // Skip if --force-disable-user-env
35 > if (args['force-disable-user-env']) {
36 > logService.trace('resolveShellEnv(): skipped (--force-disable-user-env)');
37 >
38 > return {};
39 > }
40
41 // Skip on windows
42 else if (isWindows) {
43 logService.trace('resolveShellEnv(): skipped (Windows)');
44
45 return {};
46 }
47
48 // Skip if running from CLI already
49 else if (isLaunchedFromCli(env) && !args['force-user-env']) {
50 logService.trace('resolveShellEnv(): skipped (VSCODE_CLI is set)');
51
52 return {};
53 }
54
55 // Otherwise resolve (macOS, Linux)
56 else {
57 if (isLaunchedFromCli(env)) {
58 logService.trace('resolveShellEnv(): running (--force-user-env)');
59 } else {
60 logService.trace('resolveShellEnv(): running (macOS/Linux)');
61 }
62
63 // Call this only once and cache the promise for
64 // subsequent calls since this operation can be
65 // expensive (spawns a process).
66 if (!unixShellEnvPromise) {
67 unixShellEnvPromise = Promises.withAsyncBody<NodeJS.ProcessEnv>(async (resolve, reject) => {
68 const cts = new CancellationTokenSource();
69
70 let timeoutValue = 10000; // default to 10 seconds
71 const configuredTimeoutValue = configurationService.getValue<unknown>('application.shellEnvironmentResolutionTimeout');
72 if (typeof configuredTimeoutValue === 'number') {
73 timeoutValue = clamp(configuredTimeoutValue, 1, 120) * 1000 /* convert from seconds */;
74 }
75
76 // Give up resolving shell env after some time
77 const timeout = setTimeout(() => {
78 cts.dispose(true);
79 reject(new Error(localize('resolveShellEnvTimeout', "Unable to resolve your shell environment in a reasonable time. Please review your shell configuration and restart.")));
80 }, timeoutValue);
81
82 // Resolve shell env and handle errors
83 try {
84 resolve(await doResolveUnixShellEnv(logService, cts.token));
85 } catch (error) {
86 if (!isCancellationError(error) && !cts.token.isCancellationRequested) {
87 reject(new Error(localize('resolveShellEnvError', "Unable to resolve your shell environment: {0}", toErrorMessage(error))));
88 } else {
89 resolve({});
90 }
91 } finally {
92 clearTimeout(timeout);
93 cts.dispose();
94 }
95 });
96 }
97
98 return unixShellEnvPromise;
99 }
102 async function doResolveUnixShellEnv(logService: ILogService, token: CancellationToken): Promise<typeof process.env> {
103 const runAsNode = process.env['ELECTRON_RUN_AS_NODE'];
104 logService.trace('getUnixShellEnvironment#runAsNode', runAsNode);
105
106 const noAttach = process.env['ELECTRON_NO_ATTACH_CONSOLE'];
107 logService.trace('getUnixShellEnvironment#noAttach', noAttach);
108
109 const mark = generateUuid().replace(/-/g, '').substr(0, 12);
110 const regex = new RegExp(mark + '({.*})' + mark);
111
112 const env = {
113 ...process.env,
114 ELECTRON_RUN_AS_NODE: '1',
115 ELECTRON_NO_ATTACH_CONSOLE: '1',
116 VSCODE_RESOLVING_ENVIRONMENT: '1'
117 };
118
119 logService.trace('getUnixShellEnvironment#env', env);
120 const systemShellUnix = await getSystemShell(OS, env);
121 logService.trace('getUnixShellEnvironment#shell', systemShellUnix);
122
123 return new Promise<typeof process.env>((resolve, reject) => {
124 if (token.isCancellationRequested) {
125 return reject(new CancellationError());
126 }
127
128 // handle popular non-POSIX shells
129 const name = basename(systemShellUnix);
130 let command: string, shellArgs: Array<string>;
131 const extraArgs = '';
132 if (/^(?:pwsh|powershell)(?:-preview)?$/.test(name)) {
133 // Older versions of PowerShell removes double quotes sometimes so we use "double single quotes" which is how
134 // you escape single quotes inside of a single quoted string.
135 command = `& '${process.execPath}' ${extraArgs} -p '''${mark}'' + JSON.stringify(process.env) + ''${mark}'''`;
136 shellArgs = ['-Login', '-Command'];
137 } else if (name === 'nu') { // nushell requires ^ before quoted path to treat it as a command
138 command = `^'${process.execPath}' ${extraArgs} -p '"${mark}" + JSON.stringify(process.env) + "${mark}"'`;
139 shellArgs = ['-i', '-l', '-c'];
140 } else if (name === 'xonsh') { // #200374: native implementation is shorter
141 command = `import os, json; print("${mark}", json.dumps(dict(os.environ)), "${mark}")`;
142 shellArgs = ['-i', '-l', '-c'];
143 } else {
144 command = `'${process.execPath}' ${extraArgs} -p '"${mark}" + JSON.stringify(process.env) + "${mark}"'`;
145
146 if (name === 'tcsh' || name === 'csh') {
147 shellArgs = ['-ic'];
148 } else {
149 shellArgs = ['-i', '-l', '-c'];
150 }
151 }
152
153 logService.trace('getUnixShellEnvironment#spawn', JSON.stringify(shellArgs), command);
154
155 const child = spawn(systemShellUnix, [...shellArgs, command], {
156 detached: true,
157 stdio: ['ignore', 'pipe', 'pipe'],
158 env
159 });
160
161 token.onCancellationRequested(() => {
162 child.kill();
163
164 return reject(new CancellationError());
165 });
166
167 child.on('error', err => {
168 logService.error('getUnixShellEnvironment#errorChildProcess', toErrorMessage(err));
169 reject(err);
170 });
171
172 const buffers: Buffer[] = [];
173 child.stdout.on('data', b => buffers.push(b));
174
175 const stderr: Buffer[] = [];
176 child.stderr.on('data', b => stderr.push(b));
177
178 child.on('close', (code, signal) => {
179 const raw = Buffer.concat(buffers).toString('utf8');
180 logService.trace('getUnixShellEnvironment#raw', raw);
181
182 const stderrStr = Buffer.concat(stderr).toString('utf8');
183 if (stderrStr.trim()) {
184 logService.trace('getUnixShellEnvironment#stderr', stderrStr);
185 }
186
187 if (code || signal) {
188 return reject(new Error(localize('resolveShellEnvExitError', "Unexpected exit code from spawned shell (code {0}, signal {1})", code, signal)));
189 }
190
191 const match = regex.exec(raw);
192 const rawStripped = match ? match[1] : '{}';
193
194 try {
195 const env = JSON.parse(rawStripped);
196
197 if (runAsNode) {
198 env['ELECTRON_RUN_AS_NODE'] = runAsNode;
199 } else {
200 delete env['ELECTRON_RUN_AS_NODE'];
201 }
202
203 if (noAttach) {
204 env['ELECTRON_NO_ATTACH_CONSOLE'] = noAttach;
205 } else {
206 delete env['ELECTRON_NO_ATTACH_CONSOLE'];
207 }
208
209 delete env['VSCODE_RESOLVING_ENVIRONMENT'];
210
211 // https://github.com/microsoft/vscode/issues/22593#issuecomment-336050758
212 delete env['XDG_RUNTIME_DIR'];
213
214 logService.trace('getUnixShellEnvironment#result', env);
215 resolve(env);
216 } catch (err) {
217 logService.error('getUnixShellEnvironment#errorCaught', toErrorMessage(err));
218 reject(err);
219 }
220 });
221 });
222 }