Migrate profile setting and fallback properly

Fixes #125177
This commit is contained in:
Daniel Imms
2021-06-02 16:43:38 -07:00
parent 9bd7cbd140
commit 0f8c499d10
3 changed files with 29 additions and 11 deletions
@@ -46,7 +46,7 @@ import { TypeAheadAddon } from 'vs/workbench/contrib/terminal/browser/terminalTy
import { BrowserFeatures } from 'vs/base/browser/canIUse';
import { IPreferencesService } from 'vs/workbench/services/preferences/common/preferences';
import { IEnvironmentVariableInfo } from 'vs/workbench/contrib/terminal/common/environmentVariable';
import { IProcessDataEvent, IShellLaunchConfig, ITerminalDimensionsOverride, ITerminalLaunchError, TerminalShellType, TerminalSettingId, TitleEventSource, TerminalIcon, TerminalSettingPrefix } from 'vs/platform/terminal/common/terminal';
import { IProcessDataEvent, IShellLaunchConfig, ITerminalDimensionsOverride, ITerminalLaunchError, TerminalShellType, TerminalSettingId, TitleEventSource, TerminalIcon, TerminalSettingPrefix, ITerminalProfileObject } from 'vs/platform/terminal/common/terminal';
import { IProductService } from 'vs/platform/product/common/productService';
import { formatMessageForTerminal } from 'vs/workbench/contrib/terminal/common/terminalStrings';
import { AutoOpenBarrier } from 'vs/base/common/async';
@@ -373,14 +373,22 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
const shell = this._configurationService.getValue(TerminalSettingPrefix.Shell + platform);
const shellArgs = this._configurationService.getValue(TerminalSettingPrefix.ShellArgs + platform);
const profile = await this._terminalProfileResolverService.createProfileFromShellAndShellArgs(shell, shellArgs);
if (profile) {
this._configurationService.updateValue(TerminalSettingPrefix.DefaultProfile + platform, profile.profileName);
this._configurationService.updateValue(TerminalSettingPrefix.Shell + platform, undefined);
this._configurationService.updateValue(TerminalSettingPrefix.ShellArgs + platform, undefined);
this._logService.trace(`migrated from shell/shellArgs, ${shell} ${shellArgs} to profile ${JSON.stringify(profile)}`);
if (typeof profile === 'string') {
await this._configurationService.updateValue(TerminalSettingPrefix.DefaultProfile + platform, profile);
this._logService.trace(`migrated from shell/shellArgs, using existing profile ${profile}`);
} else {
this._logService.trace('migration from shell/shellArgs to profile did not occur bc created profile was an exact match for existing one', shell, shellArgs);
const profiles = this._configurationService.inspect<{ [key: string]: ITerminalProfileObject }>(TerminalSettingPrefix.Profiles + platform).userValue || {};
const profileConfig: ITerminalProfileObject = { path: profile.path };
if (profile.args) {
profileConfig.args = profile.args;
}
profiles[profile.profileName] = profileConfig;
await this._configurationService.updateValue(TerminalSettingPrefix.Profiles + platform, profiles);
await this._configurationService.updateValue(TerminalSettingPrefix.DefaultProfile + platform, profile.profileName);
this._logService.trace(`migrated from shell/shellArgs, ${shell} ${shellArgs} to profile ${JSON.stringify(profile)}`);
}
await this._configurationService.updateValue(TerminalSettingPrefix.Shell + platform, undefined);
await this._configurationService.updateValue(TerminalSettingPrefix.ShellArgs + platform, undefined);
}
} as IPromptChoice,
],
@@ -21,6 +21,7 @@ import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteA
import { debounce } from 'vs/base/common/decorators';
import { ThemeIcon } from 'vs/platform/theme/common/themeService';
import { URI, UriComponents } from 'vs/base/common/uri';
import { equals } from 'vs/base/common/arrays';
export interface IProfileContextProvider {
getDefaultSystemShell: (remoteAuthority: string | undefined, os: OperatingSystem) => Promise<string>;
@@ -392,12 +393,21 @@ export abstract class BaseTerminalProfileResolverService implements ITerminalPro
return false;
}
async createProfileFromShellAndShellArgs(shell?: unknown, shellArgs?: unknown): Promise<ITerminalProfile | undefined> {
const detectedProfile = this._terminalService.availableProfiles?.find(p => p.path === shell);
async createProfileFromShellAndShellArgs(shell?: unknown, shellArgs?: unknown): Promise<ITerminalProfile | string> {
const detectedProfile = this._terminalService.availableProfiles?.find(p => {
if (p.path !== shell) {
return false;
}
if (p.args === undefined || typeof p.args === 'string') {
return p.args === shellArgs;
}
return p.path === shell && equals(p.args, (shellArgs || []) as string[]);
});
const fallbackProfile = (await this.getDefaultProfile({
remoteAuthority: this._remoteAgentService.getConnection()?.remoteAuthority,
os: this._primaryBackendOs!
}));
fallbackProfile.profileName = `${fallbackProfile.path} (migrated)`;
const profile = detectedProfile || fallbackProfile;
const args = this._isValidShellArgs(shellArgs, this._primaryBackendOs!) ? shellArgs : profile.args;
const createdProfile = {
@@ -407,7 +417,7 @@ export abstract class BaseTerminalProfileResolverService implements ITerminalPro
isDefault: true
};
if (detectedProfile && detectedProfile.profileName === createdProfile.profileName && detectedProfile.path === createdProfile.path && this._argsMatch(detectedProfile.args, createdProfile.args)) {
return undefined;
return detectedProfile.profileName;
}
return createdProfile;
}
@@ -112,7 +112,7 @@ export interface ITerminalProfileResolverService {
getDefaultShell(options: IShellLaunchConfigResolveOptions): Promise<string>;
getDefaultShellArgs(options: IShellLaunchConfigResolveOptions): Promise<string | string[]>;
getEnvironment(remoteAuthority: string | undefined): Promise<IProcessEnvironment>;
createProfileFromShellAndShellArgs(shell?: unknown, shellArgs?: unknown): Promise<ITerminalProfile | undefined>;
createProfileFromShellAndShellArgs(shell?: unknown, shellArgs?: unknown): Promise<ITerminalProfile | string>;
}
export interface IShellLaunchConfigResolveOptions {