Skip to content

Commit 9f24fbf

Browse files
author
Kartik Raj
authored
Support pythonTerminalEnvVarActivation experiment in multiroot workspaces (#21047)
1 parent d905cf0 commit 9f24fbf

File tree

7 files changed

+195
-65
lines changed

7 files changed

+195
-65
lines changed

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@
2222
"quickPickSortByLabel",
2323
"envShellEvent",
2424
"testObserver",
25-
"quickPickItemTooltip"
25+
"quickPickItemTooltip",
26+
"envCollectionWorkspace"
2627
],
2728
"author": {
2829
"name": "Microsoft Corporation"
@@ -43,7 +44,7 @@
4344
"theme": "dark"
4445
},
4546
"engines": {
46-
"vscode": "^1.77.0-20230309"
47+
"vscode": "^1.78.0-20230421"
4748
},
4849
"keywords": [
4950
"python",

src/client/common/experiments/helpers.ts

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,10 @@
33

44
'use strict';
55

6-
import { workspace } from 'vscode';
7-
import { isTestExecution } from '../constants';
86
import { IExperimentService } from '../types';
97
import { TerminalEnvVarActivation } from './groups';
108

119
export function inTerminalEnvVarExperiment(experimentService: IExperimentService): boolean {
12-
if (workspace.workspaceFile && !isTestExecution()) {
13-
// Don't run experiment in multi-root workspaces for now, requires work on VSCode:
14-
// https://github.com/microsoft/vscode/issues/171173
15-
return false;
16-
}
1710
if (!experimentService.inExperimentSync(TerminalEnvVarActivation.experiment)) {
1811
return false;
1912
}

src/client/common/utils/localize.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,7 @@ export namespace Interpreters {
198198
'We noticed you\'re using a conda environment. If you are experiencing issues with this environment in the integrated terminal, we recommend that you let the Python extension change "terminal.integrated.inheritEnv" to false in your user settings. [Learn more](https://aka.ms/AA66i8f).',
199199
);
200200
export const activatingTerminals = l10n.t('Reactivating terminals...');
201+
export const activateTerminalDescription = l10n.t('Activated environment for');
201202
export const activatedCondaEnvLaunch = l10n.t(
202203
'We noticed VS Code was launched from an activated conda environment, would you like to select it?',
203204
);

src/client/interpreter/activation/terminalEnvVarCollectionService.ts

Lines changed: 51 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
// Licensed under the MIT License.
33

44
import { inject, injectable } from 'inversify';
5-
import { ProgressOptions, ProgressLocation } from 'vscode';
6-
import { IExtensionSingleActivationService } from '../../activation/types';
7-
import { IApplicationShell, IApplicationEnvironment } from '../../common/application/types';
5+
import { ProgressOptions, ProgressLocation, MarkdownString } from 'vscode';
6+
import { IExtensionActivationService } from '../../activation/types';
7+
import { IApplicationShell, IApplicationEnvironment, IWorkspaceService } from '../../common/application/types';
88
import { inTerminalEnvVarExperiment } from '../../common/experiments/helpers';
99
import { IPlatformService } from '../../common/platform/types';
1010
import { identifyShellFromShellPath } from '../../common/terminal/shellDetectors/baseShellDetector';
@@ -14,6 +14,7 @@ import {
1414
Resource,
1515
IDisposableRegistry,
1616
IConfigurationService,
17+
IPathUtils,
1718
} from '../../common/types';
1819
import { Deferred, createDeferred } from '../../common/utils/async';
1920
import { Interpreters } from '../../common/utils/localize';
@@ -23,14 +24,16 @@ import { defaultShells } from './service';
2324
import { IEnvironmentActivationService } from './types';
2425

2526
@injectable()
26-
export class TerminalEnvVarCollectionService implements IExtensionSingleActivationService {
27+
export class TerminalEnvVarCollectionService implements IExtensionActivationService {
2728
public readonly supportedWorkspaceTypes = {
2829
untrustedWorkspace: false,
2930
virtualWorkspace: false,
3031
};
3132

3233
private deferred: Deferred<void> | undefined;
3334

35+
private registeredOnce = false;
36+
3437
private previousEnvVars = _normCaseKeys(process.env);
3538

3639
constructor(
@@ -42,39 +45,51 @@ export class TerminalEnvVarCollectionService implements IExtensionSingleActivati
4245
@inject(IApplicationEnvironment) private applicationEnvironment: IApplicationEnvironment,
4346
@inject(IDisposableRegistry) private disposables: IDisposableRegistry,
4447
@inject(IEnvironmentActivationService) private environmentActivationService: IEnvironmentActivationService,
48+
@inject(IWorkspaceService) private workspaceService: IWorkspaceService,
4549
@inject(IConfigurationService) private readonly configurationService: IConfigurationService,
50+
@inject(IPathUtils) private readonly pathUtils: IPathUtils,
4651
) {}
4752

48-
public async activate(): Promise<void> {
53+
public async activate(resource: Resource): Promise<void> {
4954
if (!inTerminalEnvVarExperiment(this.experimentService)) {
5055
this.context.environmentVariableCollection.clear();
5156
return;
5257
}
53-
this.interpreterService.onDidChangeInterpreter(
54-
async (resource) => {
55-
this.showProgress();
56-
await this._applyCollection(resource);
57-
this.hideProgress();
58-
},
59-
this,
60-
this.disposables,
61-
);
62-
this.applicationEnvironment.onDidChangeShell(
63-
async (shell: string) => {
64-
this.showProgress();
65-
// Pass in the shell where known instead of relying on the application environment, because of bug
66-
// on VSCode: https://github.com/microsoft/vscode/issues/160694
67-
await this._applyCollection(undefined, shell);
68-
this.hideProgress();
69-
},
70-
this,
71-
this.disposables,
72-
);
73-
74-
this._applyCollection(undefined).ignoreErrors();
58+
if (!this.registeredOnce) {
59+
this.interpreterService.onDidChangeInterpreter(
60+
async (r) => {
61+
this.showProgress();
62+
await this._applyCollection(r).ignoreErrors();
63+
this.hideProgress();
64+
},
65+
this,
66+
this.disposables,
67+
);
68+
this.applicationEnvironment.onDidChangeShell(
69+
async (shell: string) => {
70+
this.showProgress();
71+
// Pass in the shell where known instead of relying on the application environment, because of bug
72+
// on VSCode: https://github.com/microsoft/vscode/issues/160694
73+
await this._applyCollection(undefined, shell).ignoreErrors();
74+
this.hideProgress();
75+
},
76+
this,
77+
this.disposables,
78+
);
79+
this.registeredOnce = true;
80+
}
81+
this._applyCollection(resource).ignoreErrors();
7582
}
7683

7784
public async _applyCollection(resource: Resource, shell = this.applicationEnvironment.shell): Promise<void> {
85+
let workspaceFolder = this.workspaceService.getWorkspaceFolder(resource);
86+
if (
87+
!workspaceFolder &&
88+
Array.isArray(this.workspaceService.workspaceFolders) &&
89+
this.workspaceService.workspaceFolders.length > 0
90+
) {
91+
[workspaceFolder] = this.workspaceService.workspaceFolders;
92+
}
7893
const settings = this.configurationService.getSettings(resource);
7994
if (!settings.terminal.activateEnvironment) {
8095
traceVerbose('Activating environments in terminal is disabled for', resource?.fsPath);
@@ -95,7 +110,7 @@ export class TerminalEnvVarCollectionService implements IExtensionSingleActivati
95110
await this._applyCollection(resource, defaultShell?.shell);
96111
return;
97112
}
98-
this.context.environmentVariableCollection.clear();
113+
this.context.environmentVariableCollection.clear({ workspaceFolder });
99114
this.previousEnvVars = _normCaseKeys(process.env);
100115
return;
101116
}
@@ -107,20 +122,25 @@ export class TerminalEnvVarCollectionService implements IExtensionSingleActivati
107122
if (prevValue !== value) {
108123
if (value !== undefined) {
109124
traceVerbose(`Setting environment variable ${key} in collection to ${value}`);
110-
this.context.environmentVariableCollection.replace(key, value);
125+
this.context.environmentVariableCollection.replace(key, value, { workspaceFolder });
111126
} else {
112127
traceVerbose(`Clearing environment variable ${key} from collection`);
113-
this.context.environmentVariableCollection.delete(key);
128+
this.context.environmentVariableCollection.delete(key, { workspaceFolder });
114129
}
115130
}
116131
});
117132
Object.keys(previousEnv).forEach((key) => {
118133
// If the previous env var is not in the current env, clear it from collection.
119134
if (!(key in env)) {
120135
traceVerbose(`Clearing environment variable ${key} from collection`);
121-
this.context.environmentVariableCollection.delete(key);
136+
this.context.environmentVariableCollection.delete(key, { workspaceFolder });
122137
}
123138
});
139+
const displayPath = this.pathUtils.getDisplayName(settings.pythonPath, workspaceFolder?.uri.fsPath);
140+
const description = new MarkdownString(`${Interpreters.activateTerminalDescription} \`${displayPath}\``);
141+
this.context.environmentVariableCollection.setDescription(description, {
142+
workspaceFolder,
143+
});
124144
}
125145

126146
@traceDecoratorVerbose('Display activating terminals')

src/client/interpreter/serviceRegistry.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,8 @@ export function registerTypes(serviceManager: IServiceManager): void {
109109
IEnvironmentActivationService,
110110
EnvironmentActivationService,
111111
);
112-
serviceManager.addSingleton<IExtensionSingleActivationService>(
113-
IExtensionSingleActivationService,
112+
serviceManager.addSingleton<IExtensionActivationService>(
113+
IExtensionActivationService,
114114
TerminalEnvVarCollectionService,
115115
);
116116
}

0 commit comments

Comments
 (0)