Skip to content

Commit

Permalink
Initial impl of env var collection options
Browse files Browse the repository at this point in the history
Part of #179476
  • Loading branch information
Tyriar committed May 18, 2023
1 parent 4c6e0b5 commit 689c912
Show file tree
Hide file tree
Showing 7 changed files with 101 additions and 29 deletions.
12 changes: 6 additions & 6 deletions src/vs/platform/terminal/common/environmentVariable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,24 +11,24 @@ export enum EnvironmentVariableMutatorType {
Append = 2,
Prepend = 3
}
// export enum EnvironmentVariableMutatorTiming {
// AtSpawn = 1,
// AfterShellIntegration = 2
// // TODO: Do we need a both?
// }
export interface IEnvironmentVariableMutator {
readonly variable: string;
readonly value: string;
readonly type: EnvironmentVariableMutatorType;
readonly scope?: EnvironmentVariableScope;
// readonly timing?: EnvironmentVariableMutatorTiming;
readonly options?: IEnvironmentVariableMutatorOptions;
}

export interface IEnvironmentDescriptionMutator {
readonly description: string | undefined;
readonly scope?: EnvironmentVariableScope;
}

export interface IEnvironmentVariableMutatorOptions {
applyAtProcessCreation?: boolean;
applyAtShellIntegration?: boolean;
}

export type EnvironmentVariableScope = {
workspaceFolder?: IWorkspaceFolderData;
};
Expand Down
47 changes: 27 additions & 20 deletions src/vs/platform/terminal/common/environmentVariableCollection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ import { EnvironmentVariableMutatorType, EnvironmentVariableScope, IEnvironmentV

type VariableResolver = (str: string) => Promise<string>;

// const mutatorTypeToLabelMap: Map<EnvironmentVariableMutatorType, string> = new Map([
// [EnvironmentVariableMutatorType.Append, 'APPEND'],
// [EnvironmentVariableMutatorType.Prepend, 'PREPEND'],
// [EnvironmentVariableMutatorType.Replace, 'REPLACE']
// ]);
const mutatorTypeToLabelMap: Map<EnvironmentVariableMutatorType, string> = new Map([
[EnvironmentVariableMutatorType.Append, 'APPEND'],
[EnvironmentVariableMutatorType.Prepend, 'PREPEND'],
[EnvironmentVariableMutatorType.Replace, 'REPLACE']
]);

export class MergedEnvironmentVariableCollection implements IMergedEnvironmentVariableCollection {
private readonly map: Map<string, IExtensionOwnedEnvironmentVariableMutator[]> = new Map();
Expand Down Expand Up @@ -69,26 +69,33 @@ export class MergedEnvironmentVariableCollection implements IMergedEnvironmentVa
const actualVariable = isWindows ? lowerToActualVariableNames![variable.toLowerCase()] || variable : variable;
for (const mutator of mutators) {
const value = variableResolver ? await variableResolver(mutator.value) : mutator.value;
// if (mutator.timing === EnvironmentVariableMutatorTiming.AfterShellIntegration) {
// const key = `VSCODE_ENV_${mutatorTypeToLabelMap.get(mutator.type)!}`;
// env[key] = (env[key] ? env[key] + ':' : '') + variable + '=' + value;
// continue;
// }
switch (mutator.type) {
case EnvironmentVariableMutatorType.Append:
env[actualVariable] = (env[actualVariable] || '') + value;
break;
case EnvironmentVariableMutatorType.Prepend:
env[actualVariable] = value + (env[actualVariable] || '');
break;
case EnvironmentVariableMutatorType.Replace:
env[actualVariable] = value;
break;
// Default: true
if (mutator.options?.applyAtProcessCreation ?? true) {
switch (mutator.type) {
case EnvironmentVariableMutatorType.Append:
env[actualVariable] = (env[actualVariable] || '') + value;
break;
case EnvironmentVariableMutatorType.Prepend:
env[actualVariable] = value + (env[actualVariable] || '');
break;
case EnvironmentVariableMutatorType.Replace:
env[actualVariable] = value;
break;
}
}
// Default: false
if (mutator.options?.applyAtShellIntegration ?? false) {
const key = `VSCODE_ENV_${mutatorTypeToLabelMap.get(mutator.type)!}`;
env[key] = (env[key] ? env[key] + ':' : '') + variable + '=' + this._encodeColons(value);
}
}
}
}

private _encodeColons(value: string): string {
return value.replaceAll(':', '\\x3a');
}

diff(other: IMergedEnvironmentVariableCollection, scope: EnvironmentVariableScope | undefined): IMergedEnvironmentVariableCollectionDiff | undefined {
const added: Map<string, IExtensionOwnedEnvironmentVariableMutator[]> = new Map();
const changed: Map<string, IExtensionOwnedEnvironmentVariableMutator[]> = new Map();
Expand Down
1 change: 1 addition & 0 deletions src/vs/workbench/api/browser/mainThreadTerminalService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,7 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape
map: deserializeEnvironmentVariableCollection(collection),
descriptionMap: deserializeEnvironmentDescriptionMap(descriptionMap)
};
console.log('translatedCollection', translatedCollection);
this._environmentVariableService.set(extensionIdentifier, translatedCollection);
} else {
this._environmentVariableService.delete(extensionIdentifier);
Expand Down
11 changes: 8 additions & 3 deletions src/vs/workbench/api/common/extHostTerminalService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -892,15 +892,18 @@ class EnvironmentVariableCollection implements vscode.EnvironmentVariableCollect
}

replace(variable: string, value: string, scope?: vscode.EnvironmentVariableScope): void {
this._setIfDiffers(variable, { value, type: EnvironmentVariableMutatorType.Replace, scope });
// TODO: Implement options in API
this._setIfDiffers(variable, { value, type: EnvironmentVariableMutatorType.Replace, scope, options: {} });
}

append(variable: string, value: string, scope?: vscode.EnvironmentVariableScope): void {
this._setIfDiffers(variable, { value, type: EnvironmentVariableMutatorType.Append, scope });
// TODO: Implement options in API
this._setIfDiffers(variable, { value, type: EnvironmentVariableMutatorType.Append, scope, options: {} });
}

prepend(variable: string, value: string, scope?: vscode.EnvironmentVariableScope): void {
this._setIfDiffers(variable, { value, type: EnvironmentVariableMutatorType.Prepend, scope });
// TODO: Implement options in API
this._setIfDiffers(variable, { value, type: EnvironmentVariableMutatorType.Prepend, scope, options: {} });
}

private _setIfDiffers(variable: string, mutator: vscode.EnvironmentVariableMutator): void {
Expand All @@ -920,6 +923,7 @@ class EnvironmentVariableCollection implements vscode.EnvironmentVariableCollect
get(variable: string, scope?: vscode.EnvironmentVariableScope): vscode.EnvironmentVariableMutator | undefined {
const key = this.getKey(variable, scope);
const value = this.map.get(key);
// TODO: Set options to defaults if needed
return value ? convertMutator(value) : undefined;
}

Expand Down Expand Up @@ -1030,6 +1034,7 @@ function asTerminalColor(color?: vscode.ThemeColor): ThemeColor | undefined {
function convertMutator(mutator: IEnvironmentVariableMutator): vscode.EnvironmentVariableMutator {
const newMutator = { ...mutator };
newMutator.scope = newMutator.scope ?? undefined;
newMutator.options = newMutator.options ?? undefined;
delete (newMutator as any).variable;
return newMutator as vscode.EnvironmentVariableMutator;
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ $Global:__LastHistoryId = -1
$Nonce = $env:VSCODE_NONCE
$env:VSCODE_NONCE = $null

Write-Host "REPLACE: " $env:VSCODE_ENV_REPLACE
Write-Host "PREPEND: " $env:VSCODE_ENV_PREPEND
Write-Host "APPEND: " $env:VSCODE_ENV_APPEND

if ($env:VSCODE_ENV_REPLACE) {
$Split = $env:VSCODE_ENV_REPLACE.Split(":")
foreach ($Item in $Split) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export const allApiProposals = Object.freeze({
dropMetadata: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.dropMetadata.d.ts',
editSessionIdentityProvider: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.editSessionIdentityProvider.d.ts',
editorInsets: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.editorInsets.d.ts',
envCollectionOptions: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.envCollectionOptions.d.ts',
envCollectionWorkspace: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.envCollectionWorkspace.d.ts',
envShellEvent: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.envShellEvent.d.ts',
extensionRuntime: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.extensionRuntime.d.ts',
Expand Down
54 changes: 54 additions & 0 deletions src/vscode-dts/vscode.proposed.envCollectionOptions.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

declare module 'vscode' {

// https://github.com/microsoft/vscode/issues/179476

export interface EnvironmentVariableMutatorOptions {
/**
* Apply to the environment just before the process is created.
*
* Defaults to true.
*/
applyAtProcessCreation?: boolean;

/**
* Apply to the environment in the shell integration script. Note that this _will not_ apply
* the mutator if shell integration is disabled or not working for some reason.
*
* Defaults to false.
*/
applyAtShellIntegration?: boolean;
}

/**
* A type of mutation and its value to be applied to an environment variable.
*/
export interface EnvironmentVariableMutator {
/**
* Options applied to the mutator.
*/
readonly options: EnvironmentVariableMutatorOptions;
}

export interface EnvironmentVariableCollection extends Iterable<[variable: string, mutator: EnvironmentVariableMutator]> {
// TODO: Uncomment when workspace/scopes is removed from the other proposal
// /**
// * @param options Options applied to the mutator.
// */
// replace(variable: string, value: string, options?: EnvironmentVariableMutatorOptions): void;

// /**
// * @param options Options applied to the mutator.
// */
// append(variable: string, value: string, options?: EnvironmentVariableMutatorOptions): void;

// /**
// * @param options Options applied to the mutator.
// */
// prepend(variable: string, value: string, options?: EnvironmentVariableMutatorOptions): void;
}
}

0 comments on commit 689c912

Please sign in to comment.