Skip to content

Commit 90ad589

Browse files
update
1 parent 9b7b435 commit 90ad589

1 file changed

Lines changed: 66 additions & 4 deletions

File tree

lsp/src/codeLens.ts

Lines changed: 66 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
* @format
88
*/
99

10+
import {execFile} from 'child_process';
1011
import * as path from 'path';
1112
import * as vscode from 'vscode';
1213
import {ExtensionContext} from 'vscode';
@@ -32,6 +33,8 @@ type RunTestArgs = {
3233
};
3334

3435
const TASK_SOURCE = 'pyrefly';
36+
const OPEN_RUNNABLE_CODE_LENS_SETTING = 'Open Runnable CodeLens Setting';
37+
const DISABLE_RUNNABLE_CODE_LENS = 'Disable Runnable CodeLens';
3538

3639
async function interpreterForUri(
3740
uri: vscode.Uri,
@@ -43,6 +46,56 @@ async function interpreterForUri(
4346
return envPath.path.length > 0 ? envPath.path : undefined;
4447
}
4548

49+
function configurationTargetForUri(uri: vscode.Uri): vscode.ConfigurationTarget {
50+
return vscode.workspace.getWorkspaceFolder(uri) != null
51+
? vscode.ConfigurationTarget.WorkspaceFolder
52+
: vscode.ConfigurationTarget.Workspace;
53+
}
54+
55+
async function disableRunnableCodeLens(uri: vscode.Uri): Promise<void> {
56+
await vscode.workspace
57+
.getConfiguration('python.pyrefly', uri)
58+
.update(
59+
'runnableCodeLens',
60+
false,
61+
configurationTargetForUri(uri),
62+
);
63+
}
64+
65+
async function showRunnableCodeLensError(
66+
uri: vscode.Uri,
67+
message: string,
68+
): Promise<void> {
69+
const action = await vscode.window.showErrorMessage(
70+
message,
71+
OPEN_RUNNABLE_CODE_LENS_SETTING,
72+
DISABLE_RUNNABLE_CODE_LENS,
73+
);
74+
if (action === OPEN_RUNNABLE_CODE_LENS_SETTING) {
75+
await vscode.commands.executeCommand(
76+
'workbench.action.openSettings',
77+
'python.pyrefly.runnableCodeLens',
78+
);
79+
} else if (action === DISABLE_RUNNABLE_CODE_LENS) {
80+
await disableRunnableCodeLens(uri);
81+
}
82+
}
83+
84+
async function canImportModule(
85+
interpreter: string,
86+
moduleName: string,
87+
cwd: string | undefined,
88+
): Promise<boolean> {
89+
return await new Promise(resolve => {
90+
execFile(
91+
interpreter,
92+
['-c', `import ${moduleName}`],
93+
{cwd},
94+
error => resolve(error == null),
95+
);
96+
});
97+
}
98+
4699
function scopeForUri(uri: vscode.Uri): vscode.WorkspaceFolder | vscode.TaskScope {
47100
return vscode.workspace.getWorkspaceFolder(uri) ?? vscode.TaskScope.Workspace;
48101
}
@@ -120,8 +173,9 @@ async function runMainFile(
120173
const uri = vscode.Uri.parse(args.uri);
121174
const interpreter = await interpreterForUri(uri, pythonExtension);
122175
if (!interpreter) {
123-
void vscode.window.showErrorMessage(
124-
'Pyrefly could not determine a Python interpreter for this file.',
176+
void showRunnableCodeLensError(
177+
uri,
178+
'Pyrefly could not determine a Python interpreter for this file. Ensure the correct interpreter is selected in your IDE before using runnable CodeLens.',
125179
);
126180
return;
127181
}
@@ -154,8 +208,9 @@ async function runTestAtLocation(
154208

155209
const interpreter = await interpreterForUri(uri, pythonExtension);
156210
if (!interpreter) {
157-
void vscode.window.showErrorMessage(
158-
'Pyrefly could not determine a Python interpreter for this file.',
211+
void showRunnableCodeLensError(
212+
uri,
213+
'Pyrefly could not determine a Python interpreter for this file. Ensure the correct interpreter is selected in your IDE before using runnable CodeLens.',
159214
);
160215
return;
161216
}
@@ -192,6 +247,13 @@ async function runTestAtLocation(
192247
if (testName) {
193248
nodeId = `${nodeId}::${testName}`;
194249
}
250+
if (!(await canImportModule(interpreter, 'pytest', cwd))) {
251+
void showRunnableCodeLensError(
252+
uri,
253+
'Pyrefly could not import pytest from the selected interpreter. Select the correct interpreter or install pytest in that environment before using runnable CodeLens.',
254+
);
255+
return;
256+
}
195257
await executeProcessTask(
196258
uri,
197259
cwd,

0 commit comments

Comments
 (0)