Skip to content

Commit

Permalink
env - take window configuration into account when resolving shellEnv
Browse files Browse the repository at this point in the history
  • Loading branch information
bpasero committed Nov 20, 2020
1 parent 542a827 commit fb277ed
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 38 deletions.
28 changes: 23 additions & 5 deletions src/vs/code/electron-main/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { WindowsMainService } from 'vs/platform/windows/electron-main/windowsMai
import { IWindowOpenable } from 'vs/platform/windows/common/windows';
import { OpenContext } from 'vs/platform/windows/node/window';
import { ILifecycleMainService, LifecycleMainPhase } from 'vs/platform/lifecycle/electron-main/lifecycleMainService';
import { getShellEnvironment } from 'vs/code/node/shellEnv';
import { resolveShellEnv } from 'vs/code/node/shellEnv';
import { IUpdateService } from 'vs/platform/update/common/update';
import { UpdateChannel } from 'vs/platform/update/electron-main/updateIpc';
import { Server as ElectronIPCServer } from 'vs/base/parts/ipc/electron-main/ipc.electron-main';
Expand Down Expand Up @@ -84,6 +84,7 @@ import { EncryptionMainService, IEncryptionMainService } from 'vs/platform/encry
import { ActiveWindowManager } from 'vs/platform/windows/common/windowTracker';
import { IKeyboardLayoutMainService, KeyboardLayoutMainService } from 'vs/platform/keyboardLayout/electron-main/keyboardLayoutMainService';
import { toErrorMessage } from 'vs/base/common/errorMessage';
import { NativeParsedArgs } from 'vs/platform/environment/common/argv';

export class CodeApplication extends Disposable {
private windowsMainService: IWindowsMainService | undefined;
Expand Down Expand Up @@ -283,7 +284,24 @@ export class CodeApplication extends Disposable {
}, 10000);

try {
const shellEnv = await getShellEnvironment(this.logService, this.environmentService);

// Prefer to use the args and env from the target window
// when resolving the shell env. It is possible that
// a first window was opened from the UI but a second
// from the CLI and that has implications for wether to
// resolve the shell environment or not.
let args: NativeParsedArgs;
let env: NodeJS.ProcessEnv;
if (window?.config) {
args = window.config;
env = { ...process.env, ...window.config.userEnv };
} else {
args = this.environmentService.args;
env = process.env;
}

// Resolve shell env
const shellEnv = await resolveShellEnv(this.logService, args, env);
acceptShellEnv(shellEnv);
} catch (error) {
window?.sendWhenReady('vscode:showShellEnvError', toErrorMessage(error)); // notify inside window if we have one
Expand Down Expand Up @@ -368,7 +386,7 @@ export class CodeApplication extends Disposable {
});
this.lifecycleMainService.when(LifecycleMainPhase.AfterWindowOpen).then(() => {
this._register(new RunOnceScheduler(async () => {
sharedProcess.spawn(await getShellEnvironment(this.logService, this.environmentService));
sharedProcess.spawn(await resolveShellEnv(this.logService, this.environmentService.args, process.env));
}, 3000)).schedule();
});

Expand Down Expand Up @@ -825,8 +843,8 @@ export class CodeApplication extends Disposable {
updateService.initialize();
}

// Start to fetch shell environment after window has opened
getShellEnvironment(this.logService, this.environmentService);
// Start to fetch shell environment (if needed) after window has opened
resolveShellEnv(this.logService, this.environmentService.args, process.env);

// If enable-crash-reporter argv is undefined then this is a fresh start,
// based on telemetry.enableCrashreporter settings, generate a UUID which
Expand Down
81 changes: 48 additions & 33 deletions src/vs/code/node/shellEnv.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,55 @@ import { spawn } from 'child_process';
import { generateUuid } from 'vs/base/common/uuid';
import { isWindows } from 'vs/base/common/platform';
import { ILogService } from 'vs/platform/log/common/log';
import { INativeEnvironmentService } from 'vs/platform/environment/common/environment';
import { NativeParsedArgs } from 'vs/platform/environment/common/argv';

function getUnixShellEnvironment(logService: ILogService): Promise<typeof process.env> {
/**
* We need to get the environment from a user's shell.
* This should only be done when Code itself is not launched
* from within a shell.
*/
export async function resolveShellEnv(logService: ILogService, args: NativeParsedArgs, env: NodeJS.ProcessEnv): 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 (env['VSCODE_CLI'] === '1' && !args['force-user-env']) {
logService.trace('resolveShellEnv(): skipped (VSCODE_CLI is set)');

return {};
}

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

if (!unixShellEnvPromise) {
unixShellEnvPromise = doResolveUnixShellEnv(logService);
}

return unixShellEnvPromise;
}
}

let unixShellEnvPromise: Promise<typeof process.env> | undefined = undefined;

function doResolveUnixShellEnv(logService: ILogService): Promise<typeof process.env> {
const promise = new Promise<typeof process.env>((resolve, reject) => {
const runAsNode = process.env['ELECTRON_RUN_AS_NODE'];
logService.trace('getUnixShellEnvironment#runAsNode', runAsNode);
Expand Down Expand Up @@ -81,34 +127,3 @@ function getUnixShellEnvironment(logService: ILogService): Promise<typeof proces
// swallow errors
return promise.catch(() => ({}));
}

let shellEnvPromise: Promise<typeof process.env> | undefined = undefined;

/**
* We need to get the environment from a user's shell.
* This should only be done when Code itself is not launched
* from within a shell.
*/
export function getShellEnvironment(logService: ILogService, environmentService: INativeEnvironmentService): Promise<typeof process.env> {
if (!shellEnvPromise) {
if (environmentService.args['force-disable-user-env']) {
logService.trace('getShellEnvironment(): skipped (--force-disable-user-env)');
shellEnvPromise = Promise.resolve({});
} else if (isWindows) {
logService.trace('getShellEnvironment(): skipped (Windows)');
shellEnvPromise = Promise.resolve({});
} else if (process.env['VSCODE_CLI'] === '1' && !environmentService.args['force-user-env']) {
logService.trace('getShellEnvironment(): skipped (VSCODE_CLI is set)');
shellEnvPromise = Promise.resolve({});
} else {
if (process.env['VSCODE_CLI'] === '1') {
logService.trace('getShellEnvironment(): running (--force-user-env)');
} else {
logService.trace('getShellEnvironment(): running (macOS/Linux)');
}
shellEnvPromise = getUnixShellEnvironment(logService);
}
}

return shellEnvPromise;
}

0 comments on commit fb277ed

Please sign in to comment.