mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-03-31 01:00:29 -04:00
157 lines
5.5 KiB
TypeScript
157 lines
5.5 KiB
TypeScript
/*---------------------------------------------------------------------------------------------
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
|
*--------------------------------------------------------------------------------------------*/
|
|
|
|
import { IEnvironmentVariableCollection, EnvironmentVariableMutatorType, IMergedEnvironmentVariableCollection, IMergedEnvironmentVariableCollectionDiff, IExtensionOwnedEnvironmentVariableMutator } from 'vs/workbench/contrib/terminal/common/environmentVariable';
|
|
import { IProcessEnvironment, isWindows } from 'vs/base/common/platform';
|
|
|
|
export class MergedEnvironmentVariableCollection implements IMergedEnvironmentVariableCollection {
|
|
readonly map: Map<string, IExtensionOwnedEnvironmentVariableMutator[]> = new Map();
|
|
|
|
constructor(collections: Map<string, IEnvironmentVariableCollection>) {
|
|
collections.forEach((collection, extensionIdentifier) => {
|
|
const it = collection.map.entries();
|
|
let next = it.next();
|
|
while (!next.done) {
|
|
const variable = next.value[0];
|
|
let entry = this.map.get(variable);
|
|
if (!entry) {
|
|
entry = [];
|
|
this.map.set(variable, entry);
|
|
}
|
|
|
|
// If the first item in the entry is replace ignore any other entries as they would
|
|
// just get replaced by this one.
|
|
if (entry.length > 0 && entry[0].type === EnvironmentVariableMutatorType.Replace) {
|
|
next = it.next();
|
|
continue;
|
|
}
|
|
|
|
// Mutators get applied in the reverse order than they are created
|
|
const mutator = next.value[1];
|
|
entry.unshift({
|
|
extensionIdentifier,
|
|
value: mutator.value,
|
|
type: mutator.type
|
|
});
|
|
|
|
next = it.next();
|
|
}
|
|
});
|
|
}
|
|
|
|
applyToProcessEnvironment(env: IProcessEnvironment): void {
|
|
let lowerToActualVariableNames: { [lowerKey: string]: string | undefined } | undefined;
|
|
if (isWindows) {
|
|
lowerToActualVariableNames = {};
|
|
Object.keys(env).forEach(e => lowerToActualVariableNames![e.toLowerCase()] = e);
|
|
}
|
|
this.map.forEach((mutators, variable) => {
|
|
const actualVariable = isWindows ? lowerToActualVariableNames![variable.toLowerCase()] || variable : variable;
|
|
mutators.forEach(mutator => {
|
|
switch (mutator.type) {
|
|
case EnvironmentVariableMutatorType.Append:
|
|
env[actualVariable] = (env[actualVariable] || '') + mutator.value;
|
|
break;
|
|
case EnvironmentVariableMutatorType.Prepend:
|
|
env[actualVariable] = mutator.value + (env[actualVariable] || '');
|
|
break;
|
|
case EnvironmentVariableMutatorType.Replace:
|
|
env[actualVariable] = mutator.value;
|
|
break;
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
diff(other: IMergedEnvironmentVariableCollection): IMergedEnvironmentVariableCollectionDiff | undefined {
|
|
const added: Map<string, IExtensionOwnedEnvironmentVariableMutator[]> = new Map();
|
|
const changed: Map<string, IExtensionOwnedEnvironmentVariableMutator[]> = new Map();
|
|
const removed: Map<string, IExtensionOwnedEnvironmentVariableMutator[]> = new Map();
|
|
|
|
// Find added
|
|
other.map.forEach((otherMutators, variable) => {
|
|
const currentMutators = this.map.get(variable);
|
|
const result = getMissingMutatorsFromArray(otherMutators, currentMutators);
|
|
if (result) {
|
|
added.set(variable, result);
|
|
}
|
|
});
|
|
|
|
// Find removed
|
|
this.map.forEach((currentMutators, variable) => {
|
|
const otherMutators = other.map.get(variable);
|
|
const result = getMissingMutatorsFromArray(currentMutators, otherMutators);
|
|
if (result) {
|
|
removed.set(variable, result);
|
|
}
|
|
});
|
|
|
|
// Find changed
|
|
this.map.forEach((currentMutators, variable) => {
|
|
const otherMutators = other.map.get(variable);
|
|
const result = getChangedMutatorsFromArray(currentMutators, otherMutators);
|
|
if (result) {
|
|
changed.set(variable, result);
|
|
}
|
|
});
|
|
|
|
if (added.size === 0 && changed.size === 0 && removed.size === 0) {
|
|
return undefined;
|
|
}
|
|
|
|
return { added, changed, removed };
|
|
}
|
|
}
|
|
|
|
function getMissingMutatorsFromArray(
|
|
current: IExtensionOwnedEnvironmentVariableMutator[],
|
|
other: IExtensionOwnedEnvironmentVariableMutator[] | undefined
|
|
): IExtensionOwnedEnvironmentVariableMutator[] | undefined {
|
|
// If it doesn't exist, all are removed
|
|
if (!other) {
|
|
return current;
|
|
}
|
|
|
|
// Create a map to help
|
|
const otherMutatorExtensions = new Set<string>();
|
|
other.forEach(m => otherMutatorExtensions.add(m.extensionIdentifier));
|
|
|
|
// Find entries removed from other
|
|
const result: IExtensionOwnedEnvironmentVariableMutator[] = [];
|
|
current.forEach(mutator => {
|
|
if (!otherMutatorExtensions.has(mutator.extensionIdentifier)) {
|
|
result.push(mutator);
|
|
}
|
|
});
|
|
|
|
return result.length === 0 ? undefined : result;
|
|
}
|
|
|
|
function getChangedMutatorsFromArray(
|
|
current: IExtensionOwnedEnvironmentVariableMutator[],
|
|
other: IExtensionOwnedEnvironmentVariableMutator[] | undefined
|
|
): IExtensionOwnedEnvironmentVariableMutator[] | undefined {
|
|
// If it doesn't exist, none are changed (they are removed)
|
|
if (!other) {
|
|
return undefined;
|
|
}
|
|
|
|
// Create a map to help
|
|
const otherMutatorExtensions = new Map<string, IExtensionOwnedEnvironmentVariableMutator>();
|
|
other.forEach(m => otherMutatorExtensions.set(m.extensionIdentifier, m));
|
|
|
|
// Find entries that exist in both but are not equal
|
|
const result: IExtensionOwnedEnvironmentVariableMutator[] = [];
|
|
current.forEach(mutator => {
|
|
const otherMutator = otherMutatorExtensions.get(mutator.extensionIdentifier);
|
|
if (otherMutator && (mutator.type !== otherMutator.type || mutator.value !== otherMutator.value)) {
|
|
// Return the new result, not the old one
|
|
result.push(otherMutator);
|
|
}
|
|
});
|
|
|
|
return result.length === 0 ? undefined : result;
|
|
}
|