From cc88292c959b93ea1ffe3cdd0a8b238e440cc9c3 Mon Sep 17 00:00:00 2001 From: Kartik Raj Date: Thu, 14 Jul 2022 11:15:32 -0700 Subject: [PATCH 1/2] Trigger select environment prompt if an invalid interpreter is selected --- .../application/diagnostics/checks/pythonInterpreter.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/client/application/diagnostics/checks/pythonInterpreter.ts b/src/client/application/diagnostics/checks/pythonInterpreter.ts index bbae063e9227..b7c34aba1e3b 100644 --- a/src/client/application/diagnostics/checks/pythonInterpreter.ts +++ b/src/client/application/diagnostics/checks/pythonInterpreter.ts @@ -27,6 +27,8 @@ import { ICommandManager, IWorkspaceService } from '../../../common/application/ import { sendTelemetryEvent } from '../../../telemetry'; import { EventName } from '../../../telemetry/constants'; import { IExtensionSingleActivationService } from '../../../activation/types'; +import { cache } from '../../../common/utils/decorators'; +import { noop } from '../../../common/utils/misc'; const localize: nls.LocalizeFunc = nls.loadMessageBundle(); @@ -90,6 +92,12 @@ export class InvalidPythonInterpreterService extends BaseDiagnosticsService this.triggerEnvSelectionIfNecessary(resource), ), ); + const interpreterService = this.serviceContainer.get(IInterpreterService); + this.disposableRegistry.push( + interpreterService.onDidChangeInterpreterConfiguration((e) => + commandManager.executeCommand(Commands.TriggerEnvironmentSelection, e).then(noop, noop), + ), + ); } public async diagnose(resource: Resource): Promise { @@ -130,6 +138,7 @@ export class InvalidPythonInterpreterService extends BaseDiagnosticsService return false; } + @cache(1000, true) // This is to handle throttling of multiple events. protected async onHandle(diagnostics: IDiagnostic[]): Promise { if (diagnostics.length === 0) { return; From 90e270adad2036f7ef3f7fccf35a77b2e44b21cd Mon Sep 17 00:00:00 2001 From: Kartik Raj Date: Thu, 14 Jul 2022 13:52:24 -0700 Subject: [PATCH 2/2] Add test --- .../checks/pythonInterpreter.unit.test.ts | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/test/application/diagnostics/checks/pythonInterpreter.unit.test.ts b/src/test/application/diagnostics/checks/pythonInterpreter.unit.test.ts index 58aacb816390..118711391f2d 100644 --- a/src/test/application/diagnostics/checks/pythonInterpreter.unit.test.ts +++ b/src/test/application/diagnostics/checks/pythonInterpreter.unit.test.ts @@ -5,6 +5,7 @@ import { expect } from 'chai'; import * as typemoq from 'typemoq'; +import { EventEmitter, Uri } from 'vscode'; import { IExtensionSingleActivationService } from '../../../../client/activation/types'; import { BaseDiagnosticsService } from '../../../../client/application/diagnostics/base'; import { InvalidLaunchJsonDebuggerDiagnostic } from '../../../../client/application/diagnostics/checks/invalidLaunchJsonDebugger'; @@ -35,6 +36,7 @@ import { noop } from '../../../../client/common/utils/misc'; import { IInterpreterHelper, IInterpreterService } from '../../../../client/interpreter/contracts'; import { IServiceContainer } from '../../../../client/ioc/types'; import { EnvironmentType, PythonEnvironment } from '../../../../client/pythonEnvironments/info'; +import { sleep } from '../../../core'; suite('Application Diagnostics - Checks Python Interpreter', () => { let diagnosticService: IDiagnosticsService & IExtensionSingleActivationService; @@ -117,6 +119,27 @@ suite('Application Diagnostics - Checks Python Interpreter', () => { expect(result2).to.equal(true); }); + test('Changes to interpreter configuration triggers environment prompts', async () => { + commandManager + .setup((c) => c.registerCommand(Commands.TriggerEnvironmentSelection, typemoq.It.isAny())) + .returns(() => typemoq.Mock.ofType().object); + const interpreterEvent = new EventEmitter(); + interpreterService + .setup((i) => i.onDidChangeInterpreterConfiguration) + .returns(() => interpreterEvent.event); + await diagnosticService.activate(); + + commandManager + .setup((c) => c.executeCommand(Commands.TriggerEnvironmentSelection, undefined)) + .returns(() => Promise.resolve()) + .verifiable(typemoq.Times.once()); + + interpreterEvent.fire(undefined); + await sleep(1); + + commandManager.verifyAll(); + }); + test('Can handle InvalidPythonPathInterpreter diagnostics', async () => { for (const code of [ DiagnosticCodes.NoPythonInterpretersDiagnostic,