Merge from vscode 05fc61ffb1aee9fd19173c32113daed079f9b7bd (#5074)

* Merge from vscode 05fc61ffb1aee9fd19173c32113daed079f9b7bd

* fix tests
This commit is contained in:
Anthony Dresser
2019-04-16 22:11:30 -07:00
committed by GitHub
parent 2f8519cb6b
commit 8956b591f7
217 changed files with 5120 additions and 3926 deletions

View File

@@ -6,7 +6,7 @@
import * as platform from 'vs/base/common/platform';
import * as terminalEnvironment from 'vs/workbench/contrib/terminal/common/terminalEnvironment';
import { IDisposable } from 'vs/base/common/lifecycle';
import { ProcessState, ITerminalProcessManager, IShellLaunchConfig, ITerminalConfigHelper, ITerminalChildProcess, IBeforeProcessDataEvent } from 'vs/workbench/contrib/terminal/common/terminal';
import { ProcessState, ITerminalProcessManager, IShellLaunchConfig, ITerminalConfigHelper, ITerminalChildProcess, IBeforeProcessDataEvent, ITerminalEnvironment } from 'vs/workbench/contrib/terminal/common/terminal';
import { ILogService } from 'vs/platform/log/common/log';
import { Emitter, Event } from 'vs/base/common/event';
import { IHistoryService } from 'vs/workbench/services/history/common/history';
@@ -22,6 +22,7 @@ import { IProductService } from 'vs/platform/product/common/product';
import { ITerminalInstanceService } from 'vs/workbench/contrib/terminal/browser/terminal';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService';
import { URI } from 'vs/base/common/uri';
/** The amount of time to consider terminal errors to be related to the launch */
const LAUNCHING_DURATION = 500;
@@ -133,16 +134,13 @@ export class TerminalProcessManager implements ITerminalProcessManager {
}
const activeWorkspaceRootUri = this._historyService.getLastActiveWorkspaceRoot(hasRemoteAuthority ? REMOTE_HOST_SCHEME : undefined);
this._process = this._instantiationService.createInstance(TerminalProcessExtHostProxy, this._terminalId, shellLaunchConfig, activeWorkspaceRootUri, cols, rows);
this._process = this._instantiationService.createInstance(TerminalProcessExtHostProxy, this._terminalId, shellLaunchConfig, activeWorkspaceRootUri, cols, rows, this._configHelper);
} else {
this._process = this._launchProcess(shellLaunchConfig, cols, rows);
}
this.processState = ProcessState.LAUNCHING;
// The process is non-null, but TS isn't clever enough to know
const p = this._process!;
p.onProcessData(data => {
this._process.onProcessData(data => {
const beforeProcessDataEvent: IBeforeProcessDataEvent = { data };
this._onBeforeProcessData.fire(beforeProcessDataEvent);
if (beforeProcessDataEvent.data && beforeProcessDataEvent.data.length > 0) {
@@ -150,19 +148,19 @@ export class TerminalProcessManager implements ITerminalProcessManager {
}
});
p.onProcessIdReady(pid => {
this._process.onProcessIdReady(pid => {
this.shellProcessId = pid;
this._onProcessReady.fire();
// Send any queued data that's waiting
if (this._preLaunchInputQueue.length > 0) {
p.input(this._preLaunchInputQueue.join(''));
if (this._preLaunchInputQueue.length > 0 && this._process) {
this._process.input(this._preLaunchInputQueue.join(''));
this._preLaunchInputQueue.length = 0;
}
});
p.onProcessTitleChanged(title => this._onProcessTitle.fire(title));
p.onProcessExit(exitCode => this._onExit(exitCode));
this._process.onProcessTitleChanged(title => this._onProcessTitle.fire(title));
this._process.onProcessExit(exitCode => this._onExit(exitCode));
setTimeout(() => {
if (this.processState === ProcessState.LAUNCHING) {
@@ -175,32 +173,41 @@ export class TerminalProcessManager implements ITerminalProcessManager {
if (!shellLaunchConfig.executable) {
this._configHelper.mergeDefaultShellPathAndArgs(shellLaunchConfig);
}
const activeWorkspaceRootUri = this._historyService.getLastActiveWorkspaceRoot(Schemas.file);
const initialCwd = terminalEnvironment.getCwd(shellLaunchConfig, this._environmentService.userHome, activeWorkspaceRootUri, this._configHelper.config.cwd);
const env = this._createEnvironment(shellLaunchConfig, activeWorkspaceRootUri);
// Compel type system as process.env should not have any undefined entries
this._logService.debug(`Terminal process launching`, shellLaunchConfig, initialCwd, cols, rows, env);
return this._terminalInstanceService.createTerminalProcess(shellLaunchConfig, initialCwd, cols, rows, env, this._configHelper.config.windowsEnableConpty);
}
private _createEnvironment(shellLaunchConfig: IShellLaunchConfig, activeWorkspaceRootUri: URI | undefined): platform.IProcessEnvironment {
// Create a terminal environment based on settings, launch config and permissions
let env: platform.IProcessEnvironment = {};
if (shellLaunchConfig.strictEnv) {
// Only base the terminal process environment on this environment and add the
// various mixins when strictEnv is false
env = { ...shellLaunchConfig.env } as any;
// strictEnv is true, only use the requested env (ignoring null entries)
terminalEnvironment.mergeNonNullKeys(env, shellLaunchConfig.env);
} else {
// Merge process env with the env from config and from shellLaunchConfig
env = { ...process.env } as any;
terminalEnvironment.mergeNonNullKeys(env, process.env);
// Resolve env vars from config and shell
// Determine config env based on workspace shell permissions
const lastActiveWorkspaceRoot = activeWorkspaceRootUri ? this._workspaceContextService.getWorkspaceFolder(activeWorkspaceRootUri) : null;
const platformKey = platform.isWindows ? 'windows' : (platform.isMacintosh ? 'osx' : 'linux');
const isWorkspaceShellAllowed = this._configHelper.checkWorkspaceShellPermissions();
const envFromConfigValue = this._workspaceConfigurationService.inspect<{ [key: string]: string }>(`terminal.integrated.env.${platformKey}`);
const allowedEnvFromConfig = (isWorkspaceShellAllowed ? envFromConfigValue.value : envFromConfigValue.user);
const envFromConfig = terminalEnvironment.resolveConfigurationVariables(this._configurationResolverService, { ...allowedEnvFromConfig }, lastActiveWorkspaceRoot);
const envFromShell = terminalEnvironment.resolveConfigurationVariables(this._configurationResolverService, { ...shellLaunchConfig.env }, lastActiveWorkspaceRoot);
shellLaunchConfig.env = envFromShell;
const envFromConfigValue = this._workspaceConfigurationService.inspect<ITerminalEnvironment | undefined>(`terminal.integrated.env.${platformKey}`);
const allowedEnvFromConfig = { ...(isWorkspaceShellAllowed ? envFromConfigValue.value : envFromConfigValue.user) };
terminalEnvironment.mergeEnvironments(env, envFromConfig);
// Resolve env vars from config and shell
if (allowedEnvFromConfig) {
terminalEnvironment.resolveConfigurationVariables(this._configurationResolverService, allowedEnvFromConfig, lastActiveWorkspaceRoot);
}
if (shellLaunchConfig.env) {
terminalEnvironment.resolveConfigurationVariables(this._configurationResolverService, shellLaunchConfig.env, lastActiveWorkspaceRoot);
}
// Merge config (settings) and ShellLaunchConfig environments
terminalEnvironment.mergeEnvironments(env, allowedEnvFromConfig);
terminalEnvironment.mergeEnvironments(env, shellLaunchConfig.env);
// Sanitize the environment, removing any undesirable VS Code and Electron environment
@@ -210,9 +217,7 @@ export class TerminalProcessManager implements ITerminalProcessManager {
// Adding other env keys necessary to create the process
terminalEnvironment.addTerminalEnvironmentKeys(env, this._productService.version, platform.locale, this._configHelper.config.setLocaleVariables);
}
this._logService.debug(`Terminal process launching`, shellLaunchConfig, initialCwd, cols, rows, env);
return this._terminalInstanceService.createTerminalProcess(shellLaunchConfig, initialCwd, cols, rows, env, this._configHelper.config.windowsEnableConpty);
return env;
}
public setDimensions(cols: number, rows: number): void {