Skip to content

Commit 87c4584

Browse files
author
Kartik Raj
authored
Show a prompt asking user to upgrade Code runner to new version to keep using it (#11395)
* Show a prompt asking user to upgrade Code runner to new version to keep using it when in Deprecate PythonPath experiment * Code reviews
1 parent b5ee72d commit 87c4584

File tree

8 files changed

+466
-1
lines changed

8 files changed

+466
-1
lines changed

news/1 Enhancements/11327.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Show a prompt asking user to upgrade Code runner to new version to keep using it when in Deprecate PythonPath experiment.

package.nls.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@
151151
"InterpreterQuickPickList.enterPath.placeholder": "Enter path to a Python interpreter.",
152152
"InterpreterQuickPickList.browsePath.label": "Find...",
153153
"InterpreterQuickPickList.browsePath.detail": "Browse your file system to find a Python interpreter.",
154+
"diagnostics.upgradeCodeRunner": "Please update the Code Runner extension for it to be compatible with the Python extension.",
154155
"Common.bannerLabelYes": "Yes",
155156
"Common.bannerLabelNo": "No",
156157
"Common.doNotShowAgain": "Do not show again",
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
'use strict';
5+
6+
import { inject, named } from 'inversify';
7+
import { DiagnosticSeverity } from 'vscode';
8+
import { IWorkspaceService } from '../../../common/application/types';
9+
import { CODE_RUNNER_EXTENSION_ID } from '../../../common/constants';
10+
import { DeprecatePythonPath } from '../../../common/experimentGroups';
11+
import { IDisposableRegistry, IExperimentsManager, IExtensions, Resource } from '../../../common/types';
12+
import { Common, Diagnostics } from '../../../common/utils/localize';
13+
import { IServiceContainer } from '../../../ioc/types';
14+
import { BaseDiagnostic, BaseDiagnosticsService } from '../base';
15+
import { IDiagnosticsCommandFactory } from '../commands/types';
16+
import { DiagnosticCodes } from '../constants';
17+
import { DiagnosticCommandPromptHandlerServiceId, MessageCommandPrompt } from '../promptHandler';
18+
import { DiagnosticScope, IDiagnostic, IDiagnosticHandlerService } from '../types';
19+
20+
export class UpgradeCodeRunnerDiagnostic extends BaseDiagnostic {
21+
constructor(message: string, resource: Resource) {
22+
super(
23+
DiagnosticCodes.UpgradeCodeRunnerDiagnostic,
24+
message,
25+
DiagnosticSeverity.Information,
26+
DiagnosticScope.Global,
27+
resource
28+
);
29+
}
30+
}
31+
32+
export const UpgradeCodeRunnerDiagnosticServiceId = 'UpgradeCodeRunnerDiagnosticServiceId';
33+
34+
export class UpgradeCodeRunnerDiagnosticService extends BaseDiagnosticsService {
35+
public _diagnosticReturned: boolean = false;
36+
private workspaceService: IWorkspaceService;
37+
constructor(
38+
@inject(IServiceContainer) serviceContainer: IServiceContainer,
39+
@inject(IDiagnosticHandlerService)
40+
@named(DiagnosticCommandPromptHandlerServiceId)
41+
protected readonly messageService: IDiagnosticHandlerService<MessageCommandPrompt>,
42+
@inject(IDisposableRegistry) disposableRegistry: IDisposableRegistry,
43+
@inject(IExtensions) private readonly extensions: IExtensions
44+
) {
45+
super([DiagnosticCodes.UpgradeCodeRunnerDiagnostic], serviceContainer, disposableRegistry, true);
46+
this.workspaceService = this.serviceContainer.get<IWorkspaceService>(IWorkspaceService);
47+
}
48+
public async diagnose(resource: Resource): Promise<IDiagnostic[]> {
49+
if (this._diagnosticReturned) {
50+
return [];
51+
}
52+
const experiments = this.serviceContainer.get<IExperimentsManager>(IExperimentsManager);
53+
experiments.sendTelemetryIfInExperiment(DeprecatePythonPath.control);
54+
if (!experiments.inExperiment(DeprecatePythonPath.experiment)) {
55+
return [];
56+
}
57+
const extension = this.extensions.getExtension(CODE_RUNNER_EXTENSION_ID);
58+
if (!extension) {
59+
return [];
60+
}
61+
const flagValue: boolean | undefined = extension.packageJSON?.featureFlags?.usingNewPythonInterpreterPathApi;
62+
if (flagValue) {
63+
// Using new version of Code runner already, no need to upgrade
64+
return [];
65+
}
66+
const pythonExecutor = this.workspaceService
67+
.getConfiguration('code-runner', resource)
68+
.get<string>('executorMap.python');
69+
if (pythonExecutor?.includes('$pythonPath')) {
70+
this._diagnosticReturned = true;
71+
return [new UpgradeCodeRunnerDiagnostic(Diagnostics.upgradeCodeRunner(), resource)];
72+
}
73+
return [];
74+
}
75+
76+
protected async onHandle(diagnostics: IDiagnostic[]): Promise<void> {
77+
if (diagnostics.length === 0 || !(await this.canHandle(diagnostics[0]))) {
78+
return;
79+
}
80+
const diagnostic = diagnostics[0];
81+
if (await this.filterService.shouldIgnoreDiagnostic(diagnostic.code)) {
82+
return;
83+
}
84+
const commandFactory = this.serviceContainer.get<IDiagnosticsCommandFactory>(IDiagnosticsCommandFactory);
85+
const options = [
86+
{
87+
prompt: Common.doNotShowAgain(),
88+
command: commandFactory.createCommand(diagnostic, { type: 'ignore', options: DiagnosticScope.Global })
89+
}
90+
];
91+
92+
await this.messageService.handle(diagnostic, { commandPrompts: options });
93+
}
94+
}

src/client/application/diagnostics/constants.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,6 @@ export enum DiagnosticCodes {
1717
PythonPathDeprecatedDiagnostic = 'PythonPathDeprecatedDiagnostic',
1818
JustMyCodeDiagnostic = 'JustMyCodeDiagnostic',
1919
ConsoleTypeDiagnostic = 'ConsoleTypeDiagnostic',
20-
ConfigPythonPathDiagnostic = 'ConfigPythonPathDiagnostic'
20+
ConfigPythonPathDiagnostic = 'ConfigPythonPathDiagnostic',
21+
UpgradeCodeRunnerDiagnostic = 'UpgradeCodeRunnerDiagnostic'
2122
}

src/client/application/diagnostics/serviceRegistry.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import {
3333
PythonPathDeprecatedDiagnosticService,
3434
PythonPathDeprecatedDiagnosticServiceId
3535
} from './checks/pythonPathDeprecated';
36+
import { UpgradeCodeRunnerDiagnosticService, UpgradeCodeRunnerDiagnosticServiceId } from './checks/upgradeCodeRunner';
3637
import { DiagnosticsCommandFactory } from './commands/factory';
3738
import { IDiagnosticsCommandFactory } from './commands/types';
3839
import { DiagnosticFilterService } from './filter';
@@ -85,6 +86,12 @@ export function registerTypes(serviceManager: IServiceManager, languageServerTyp
8586
PythonPathDeprecatedDiagnosticService,
8687
PythonPathDeprecatedDiagnosticServiceId
8788
);
89+
90+
serviceManager.addSingleton<IDiagnosticsService>(
91+
IDiagnosticsService,
92+
UpgradeCodeRunnerDiagnosticService,
93+
UpgradeCodeRunnerDiagnosticServiceId
94+
);
8895
serviceManager.addSingleton<IDiagnosticsCommandFactory>(IDiagnosticsCommandFactory, DiagnosticsCommandFactory);
8996
serviceManager.addSingleton<IApplicationDiagnostics>(IApplicationDiagnostics, ApplicationDiagnostics);
9097

src/client/common/utils/localize.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ export namespace Diagnostics {
2626
'diagnostics.lsNotSupported',
2727
'Your operating system does not meet the minimum requirements of the Python Language Server. Reverting to the alternative autocompletion provider, Jedi.'
2828
);
29+
export const upgradeCodeRunner = localize(
30+
'diagnostics.upgradeCodeRunner',
31+
'Please update the Code Runner extension for it to be compatible with the Python extension.'
32+
);
2933
export const removePythonPathSettingsJson = localize(
3034
'diagnostics.removePythonPathSettingsJson',
3135
'The setting "python.pythonPath" defined in your workspace settings is now deprecated. Do you want us to delete it? This will only remove the "python.pythonPath" entry from your settings.json.'

0 commit comments

Comments
 (0)