|
| 1 | +import { ConfigurationChangeEvent, Disposable, GlobalEnvironmentVariableCollection } from 'vscode'; |
| 2 | +import { DidChangeEnvironmentEventArgs } from '../../api'; |
| 3 | +import { ShellStartupActivationStrings } from '../../common/localize'; |
| 4 | +import { getWorkspaceFolder, getWorkspaceFolders, onDidChangeConfiguration } from '../../common/workspace.apis'; |
| 5 | +import { EnvironmentManagers } from '../../internal.api'; |
| 6 | +import { ShellEnvsProvider } from './shells/startupProvider'; |
| 7 | +import { getAutoActivationType } from './utils'; |
| 8 | + |
| 9 | +export interface ShellStartupActivationVariablesManager extends Disposable { |
| 10 | + initialize(): Promise<void>; |
| 11 | +} |
| 12 | + |
| 13 | +export class ShellStartupActivationVariablesManagerImpl implements ShellStartupActivationVariablesManager { |
| 14 | + private readonly disposables: Disposable[] = []; |
| 15 | + constructor( |
| 16 | + private readonly envCollection: GlobalEnvironmentVariableCollection, |
| 17 | + private readonly shellEnvsProviders: ShellEnvsProvider[], |
| 18 | + private readonly em: EnvironmentManagers, |
| 19 | + ) { |
| 20 | + this.envCollection.description = ShellStartupActivationStrings.envCollectionDescription; |
| 21 | + this.disposables.push( |
| 22 | + onDidChangeConfiguration(async (e: ConfigurationChangeEvent) => { |
| 23 | + await this.handleConfigurationChange(e); |
| 24 | + }), |
| 25 | + this.em.onDidChangeEnvironmentFiltered(async (e: DidChangeEnvironmentEventArgs) => { |
| 26 | + await this.handleEnvironmentChange(e); |
| 27 | + }), |
| 28 | + ); |
| 29 | + } |
| 30 | + |
| 31 | + private async handleConfigurationChange(e: ConfigurationChangeEvent) { |
| 32 | + if (e.affectsConfiguration('python-envs.terminal.autoActivationType')) { |
| 33 | + const autoActType = getAutoActivationType(); |
| 34 | + if (autoActType === 'shellStartup') { |
| 35 | + await this.initializeInternal(); |
| 36 | + } else { |
| 37 | + const workspaces = getWorkspaceFolders() ?? []; |
| 38 | + if (workspaces.length > 0) { |
| 39 | + workspaces.forEach((workspace) => { |
| 40 | + const collection = this.envCollection.getScoped({ workspaceFolder: workspace }); |
| 41 | + this.shellEnvsProviders.forEach((provider) => provider.removeEnvVariables(collection)); |
| 42 | + }); |
| 43 | + } else { |
| 44 | + this.shellEnvsProviders.forEach((provider) => provider.removeEnvVariables(this.envCollection)); |
| 45 | + } |
| 46 | + } |
| 47 | + } |
| 48 | + } |
| 49 | + |
| 50 | + private async handleEnvironmentChange(e: DidChangeEnvironmentEventArgs) { |
| 51 | + const autoActType = getAutoActivationType(); |
| 52 | + if (autoActType === 'shellStartup' && e.uri) { |
| 53 | + const wf = getWorkspaceFolder(e.uri); |
| 54 | + if (wf) { |
| 55 | + const envVars = this.envCollection.getScoped({ workspaceFolder: wf }); |
| 56 | + if (envVars) { |
| 57 | + this.shellEnvsProviders.forEach((provider) => { |
| 58 | + if (e.new) { |
| 59 | + provider.updateEnvVariables(envVars, e.new); |
| 60 | + } else { |
| 61 | + provider.removeEnvVariables(envVars); |
| 62 | + } |
| 63 | + }); |
| 64 | + } |
| 65 | + } |
| 66 | + } |
| 67 | + } |
| 68 | + |
| 69 | + private async initializeInternal(): Promise<void> { |
| 70 | + const workspaces = getWorkspaceFolders() ?? []; |
| 71 | + |
| 72 | + if (workspaces.length > 0) { |
| 73 | + const promises: Promise<void>[] = []; |
| 74 | + workspaces.forEach((workspace) => { |
| 75 | + const collection = this.envCollection.getScoped({ workspaceFolder: workspace }); |
| 76 | + promises.push( |
| 77 | + ...this.shellEnvsProviders.map(async (provider) => { |
| 78 | + const env = await this.em.getEnvironment(workspace.uri); |
| 79 | + if (env) { |
| 80 | + provider.updateEnvVariables(collection, env); |
| 81 | + } else { |
| 82 | + provider.removeEnvVariables(collection); |
| 83 | + } |
| 84 | + }), |
| 85 | + ); |
| 86 | + }); |
| 87 | + await Promise.all(promises); |
| 88 | + } else { |
| 89 | + const env = await this.em.getEnvironment(undefined); |
| 90 | + await Promise.all( |
| 91 | + this.shellEnvsProviders.map(async (provider) => { |
| 92 | + if (env) { |
| 93 | + provider.updateEnvVariables(this.envCollection, env); |
| 94 | + } else { |
| 95 | + provider.removeEnvVariables(this.envCollection); |
| 96 | + } |
| 97 | + }), |
| 98 | + ); |
| 99 | + } |
| 100 | + } |
| 101 | + |
| 102 | + public async initialize(): Promise<void> { |
| 103 | + const autoActType = getAutoActivationType(); |
| 104 | + if (autoActType === 'shellStartup') { |
| 105 | + await this.initializeInternal(); |
| 106 | + } |
| 107 | + } |
| 108 | + |
| 109 | + dispose() { |
| 110 | + this.disposables.forEach((disposable) => disposable.dispose()); |
| 111 | + } |
| 112 | +} |
0 commit comments