src/vs/platform/environment/node/shellEnv.ts/resolveShellEnv
export async function resolveShellEnv(logService: ILogService, args: NativeParsedArgs, env: IProcessEnvironment): Promise<typeof process.env> {

	// Skip if --force-disable-user-env
	if (args['force-disable-user-env']) {
		logService.trace('resolveShellEnv(): skipped (--force-disable-user-env)');

		return {};
	}

	// Skip on windows
	else if (isWindows) {
		logService.trace('resolveShellEnv(): skipped (Windows)');

		return {};
	}

	// Skip if running from CLI already
	else if (isLaunchedFromCli(env) && !args['force-user-env']) {
		logService.trace('resolveShellEnv(): skipped (VSCODE_CLI is set)');

		return {};
	}

	// Otherwise resolve (macOS, Linux)
	else {
		if (isLaunchedFromCli(env)) {
			logService.trace('resolveShellEnv(): running (--force-user-env)');
		} else {
			logService.trace('resolveShellEnv(): running (macOS/Linux)');
		}

		// Call this only once and cache the promise for
		// subsequent calls since this operation can be
		// expensive (spawns a process).
		if (!unixShellEnvPromise) {
			unixShellEnvPromise = new Promise(async resolve => {
				const cts = new CancellationTokenSource();

				// Give up resolving shell env after 10 seconds
				const timeout = setTimeout(() => {
					logService.error(`[resolve shell env] Could not resolve shell environment within 10 seconds. Proceeding without shell environment...`);

					cts.dispose(true);
					resolve({});
				}, 10000);

				// Resolve shell env and handle errors
				try {
					const shellEnv = await doResolveUnixShellEnv(logService, cts.token);

					resolve(shellEnv);
				} catch (error) {
					if (!isPromiseCanceledError(error)) {
						logService.error(`[resolve shell env] Unable to resolve shell environment (${error}). Proceeding without shell environment...`);
					}

					resolve({});
				} finally {
					clearTimeout(timeout);
					cts.dispose();
				}
			});
		}

		return unixShellEnvPromise;
	}
}