Skip to content

Commit cd3dc38

Browse files
Fix shell startup activation after global interpreter changes
Co-authored-by: eleanorjboyd <26030610+eleanorjboyd@users.noreply.github.com>
1 parent 2f3c271 commit cd3dc38

2 files changed

Lines changed: 59 additions & 3 deletions

File tree

‎src/features/terminal/shellStartupActivationVariablesManager.ts‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,13 @@ export class ShellStartupActivationVariablesManagerImpl implements ShellStartupA
4848

4949
private async handleEnvironmentChange(e: DidChangeEnvironmentEventArgs) {
5050
const autoActType = getAutoActivationType();
51-
if (autoActType !== ACT_TYPE_SHELL || !e.uri) {
51+
if (autoActType !== ACT_TYPE_SHELL) {
52+
return;
53+
}
54+
if (!e.uri) {
55+
if (!getWorkspaceFolders()?.length) {
56+
await this.initializeInternal();
57+
}
5258
return;
5359
}
5460
const wf = getWorkspaceFolder(e.uri);

‎src/test/features/terminal/shellStartupActivationVariablesManager.unit.test.ts‎

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,18 @@ function makeEnvironment(id: string, managerId: string): PythonEnvironment {
2424
class RecordingEnvsProvider implements ShellEnvsProvider {
2525
public readonly shellType = 'pwsh';
2626
public readonly updated: PythonEnvironment[] = [];
27+
public readonly updatedCollections: unknown[] = [];
28+
public readonly removedCollections: unknown[] = [];
2729
public removeCalls = 0;
2830

29-
updateEnvVariables(_collection: unknown, env: PythonEnvironment): void {
31+
updateEnvVariables(collection: unknown, env: PythonEnvironment): void {
3032
this.updated.push(env);
33+
this.updatedCollections.push(collection);
3134
}
3235

33-
removeEnvVariables(): void {
36+
removeEnvVariables(collection: unknown): void {
3437
this.removeCalls += 1;
38+
this.removedCollections.push(collection);
3539
}
3640

3741
getEnvVariables(): Map<string, string | undefined> | undefined {
@@ -62,6 +66,7 @@ suite('ShellStartupActivationVariablesManager', () => {
6266

6367
sinon.stub(terminalUtils, 'getAutoActivationType').returns(terminalUtils.ACT_TYPE_SHELL);
6468
sinon.stub(workspaceApis, 'getWorkspaceFolder').returns(workspaceFolder);
69+
sinon.stub(workspaceApis, 'getWorkspaceFolders').returns([]);
6570
sinon.stub(workspaceApis, 'onDidChangeConfiguration').returns(new Disposable(() => undefined));
6671

6772
getEnvironmentStub = sinon.stub().resolves(folderEnvironment);
@@ -126,6 +131,51 @@ suite('ShellStartupActivationVariablesManager', () => {
126131
assert.strictEqual(provider.removeCalls, 1);
127132
});
128133

134+
test('refreshes global startup variables after a global selection changes', async () => {
135+
const newEnvironment = makeEnvironment('global-venv-b', 'ms-python.python:venv');
136+
await changeListener!({ uri: undefined, new: folderEnvironment, old: undefined });
137+
getEnvironmentStub.resolves(newEnvironment);
138+
139+
await changeListener!({ uri: undefined, new: newEnvironment, old: folderEnvironment });
140+
141+
sinon.assert.calledTwice(getEnvironmentStub);
142+
sinon.assert.alwaysCalledWithExactly(getEnvironmentStub, undefined);
143+
assert.deepStrictEqual(provider.updated, [folderEnvironment, newEnvironment]);
144+
assert.deepStrictEqual(provider.updatedCollections, [envCollection, envCollection]);
145+
});
146+
147+
test('removes stale global startup variables when no environment remains selected', async () => {
148+
getEnvironmentStub.resolves(undefined);
149+
150+
await changeListener!({ uri: undefined, new: undefined, old: folderEnvironment });
151+
152+
sinon.assert.calledOnceWithExactly(getEnvironmentStub, undefined);
153+
assert.deepStrictEqual(provider.removedCollections, [envCollection]);
154+
assert.strictEqual(provider.updated.length, 0);
155+
});
156+
157+
test('does not overwrite folder startup variables on a global selection change', async () => {
158+
(workspaceApis.getWorkspaceFolders as sinon.SinonStub).returns([workspaceFolder]);
159+
160+
await changeListener!({ uri: undefined, new: scriptEnvironment, old: undefined });
161+
162+
sinon.assert.notCalled(getEnvironmentStub);
163+
assert.strictEqual(provider.updated.length, 0);
164+
assert.strictEqual(provider.removeCalls, 0);
165+
});
166+
167+
for (const mode of ['command', 'off']) {
168+
test(`ignores global environment changes when activation mode is ${mode}`, async () => {
169+
(terminalUtils.getAutoActivationType as sinon.SinonStub).returns(mode);
170+
171+
await changeListener!({ uri: undefined, new: scriptEnvironment, old: undefined });
172+
173+
sinon.assert.notCalled(getEnvironmentStub);
174+
assert.strictEqual(provider.updated.length, 0);
175+
assert.strictEqual(provider.removeCalls, 0);
176+
});
177+
}
178+
129179
test('ignores environment changes when shell startup activation is off', async () => {
130180
(terminalUtils.getAutoActivationType as sinon.SinonStub).returns('command');
131181

0 commit comments

Comments
 (0)