Only set path prefix when login shell

This commit is contained in:
Daniel Imms 2023-01-11 06:03:06 -08:00
parent 449cbc9b7b
commit ae51a0a4b3
No known key found for this signature in database
GPG key ID: 7116259D505CA628

View file

@ -129,52 +129,6 @@ export function getShellIntegrationInjection(
'VSCODE_INJECTION': '1'
};
// On macOS the profile calls path_helper which adds a bunch of standard bin directories to the
// beginning of the PATH. This causes significant problems for the environment variable
// collection API as the custom paths added to the end will now be somewhere in the middle of
// the PATH. To combat this, VSCODE_PATH_PREFIX is used to re-apply any prefix after the profile
// has run. This will cause duplication in the PATH but should fix the issue.
//
// See #99878 for more information.
if (isMacintosh && options.environmentVariableCollections) {
// Deserialize and merge
const deserialized = deserializeEnvironmentVariableCollections(options.environmentVariableCollections);
// TODO: Remove test data
const map: Map<string, IEnvironmentVariableMutator> = new Map();
map.set('PATH', { value: 'before:', type: EnvironmentVariableMutatorType.Prepend });
deserialized.set('some.ext', { map });
const map2: Map<string, IEnvironmentVariableMutator> = new Map();
map2.set('PATH', { value: 'before for ext2:', type: EnvironmentVariableMutatorType.Prepend });
deserialized.set('some.ext2', { map: map2 });
const map3: Map<string, IEnvironmentVariableMutator> = new Map();
map3.set('PATH', { value: ':after', type: EnvironmentVariableMutatorType.Append });
deserialized.set('some.ext3', { map: map3 });
logService.info('deserialized', deserialized);
env!['PATH'] = `BEFORE:${env!['PATH']}:AFTER`;
// TODO: Only need prefix?
const merged = new MergedEnvironmentVariableCollection(deserialized);
// Get all prepend PATH entries
const pathEntry = merged.map.get('PATH');
const prependToPath: string[] = [];
if (pathEntry) {
for (const mutator of pathEntry) {
if (mutator.type === EnvironmentVariableMutatorType.Prepend) {
prependToPath.push(mutator.value);
}
}
}
// Add to the environment mixin to be applied in the shell integration script
if (prependToPath.length > 0) {
envMixin['VSCODE_PATH_PREFIX'] = prependToPath.join('');
}
}
// Windows
if (isWindows) {
if (shell === 'pwsh.exe' || shell === 'powershell.exe') {
@ -201,6 +155,7 @@ export function getShellIntegrationInjection(
newArgs = shellIntegrationArgs.get(ShellIntegrationExecutable.Bash);
} else if (areZshBashLoginArgs(originalArgs)) {
envMixin['VSCODE_SHELL_LOGIN'] = '1';
addEnvMixinPathPrefix(options, envMixin);
newArgs = shellIntegrationArgs.get(ShellIntegrationExecutable.Bash);
}
if (!newArgs) {
@ -216,6 +171,7 @@ export function getShellIntegrationInjection(
const oldDataDirs = env?.XDG_DATA_DIRS ?? '/usr/local/share:/usr/share';
const newDataDir = path.join(appRoot, 'out/vs/workbench/contrib/xdg_data');
envMixin['XDG_DATA_DIRS'] = `${oldDataDirs}:${newDataDir}`;
addEnvMixinPathPrefix(options, envMixin);
return { newArgs: undefined, envMixin };
}
case 'pwsh': {
@ -236,6 +192,7 @@ export function getShellIntegrationInjection(
newArgs = shellIntegrationArgs.get(ShellIntegrationExecutable.Zsh);
} else if (areZshBashLoginArgs(originalArgs)) {
newArgs = shellIntegrationArgs.get(ShellIntegrationExecutable.ZshLogin);
addEnvMixinPathPrefix(options, envMixin);
} else if (originalArgs === shellIntegrationArgs.get(ShellIntegrationExecutable.Zsh) || originalArgs === shellIntegrationArgs.get(ShellIntegrationExecutable.ZshLogin)) {
newArgs = originalArgs;
}
@ -280,6 +237,51 @@ export function getShellIntegrationInjection(
return undefined;
}
/**
* On macOS the profile calls path_helper which adds a bunch of standard bin directories to the
* beginning of the PATH. This causes significant problems for the environment variable
* collection API as the custom paths added to the end will now be somewhere in the middle of
* the PATH. To combat this, VSCODE_PATH_PREFIX is used to re-apply any prefix after the profile
* has run. This will cause duplication in the PATH but should fix the issue.
*
* See #99878 for more information.
*/
function addEnvMixinPathPrefix(options: ITerminalProcessOptions, envMixin: IProcessEnvironment): void {
if (isMacintosh && options.environmentVariableCollections) {
// Deserialize and merge
const deserialized = deserializeEnvironmentVariableCollections(options.environmentVariableCollections);
// TODO: Remove test data
const map: Map<string, IEnvironmentVariableMutator> = new Map();
map.set('PATH', { value: 'before:', type: EnvironmentVariableMutatorType.Prepend });
deserialized.set('some.ext', { map });
const map2: Map<string, IEnvironmentVariableMutator> = new Map();
map2.set('PATH', { value: 'before for ext2:', type: EnvironmentVariableMutatorType.Prepend });
deserialized.set('some.ext2', { map: map2 });
const map3: Map<string, IEnvironmentVariableMutator> = new Map();
map3.set('PATH', { value: ':after', type: EnvironmentVariableMutatorType.Append });
deserialized.set('some.ext3', { map: map3 });
const merged = new MergedEnvironmentVariableCollection(deserialized);
// Get all prepend PATH entries
const pathEntry = merged.map.get('PATH');
const prependToPath: string[] = [];
if (pathEntry) {
for (const mutator of pathEntry) {
if (mutator.type === EnvironmentVariableMutatorType.Prepend) {
prependToPath.push(mutator.value);
}
}
}
// Add to the environment mixin to be applied in the shell integration script
if (prependToPath.length > 0) {
envMixin['VSCODE_PATH_PREFIX'] = prependToPath.join('');
}
}
}
enum ShellIntegrationExecutable {
WindowsPwsh = 'windows-pwsh',
WindowsPwshLogin = 'windows-pwsh-login',