Skip to content

Commit 7904245

Browse files
committed
Add execution support
1 parent 80c9263 commit 7904245

File tree

5 files changed

+111
-2
lines changed

5 files changed

+111
-2
lines changed

src/client/envExt/api.internal.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Copyright (c) Microsoft Corporation. All rights reserved.
22
// Licensed under the MIT License.
33

4+
import { Terminal, Uri } from 'vscode';
45
import { getExtension } from '../common/vscodeApis/extensionsApi';
56
import {
67
GetEnvironmentScope,
@@ -59,3 +60,41 @@ export async function refreshEnvironments(scope: RefreshEnvironmentsScope): Prom
5960
const envExtApi = await getEnvExtApi();
6061
return envExtApi.refreshEnvironments(scope);
6162
}
63+
64+
export async function runInTerminal(
65+
resource: Uri | undefined,
66+
args?: string[],
67+
cwd?: string | Uri,
68+
show?: boolean,
69+
): Promise<Terminal> {
70+
const envExtApi = await getEnvExtApi();
71+
const env = await getEnvironment(resource);
72+
const project = resource ? envExtApi.getPythonProject(resource) : undefined;
73+
if (env && project && resource) {
74+
return envExtApi.runInTerminal(env, {
75+
cwd: cwd ?? project.uri,
76+
args,
77+
show,
78+
});
79+
}
80+
throw new Error('Python environment not found');
81+
}
82+
83+
export async function runInDedicatedTerminal(
84+
resource: Uri | undefined,
85+
args?: string[],
86+
cwd?: string | Uri,
87+
show?: boolean,
88+
): Promise<Terminal> {
89+
const envExtApi = await getEnvExtApi();
90+
const env = await getEnvironment(resource);
91+
const project = resource ? envExtApi.getPythonProject(resource) : undefined;
92+
if (env && project && resource) {
93+
return envExtApi.runInDedicatedTerminal(resource, env, {
94+
cwd: cwd ?? project.uri,
95+
args,
96+
show,
97+
});
98+
}
99+
throw new Error('Python environment not found');
100+
}

src/client/envExt/api.legacy.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import { Architecture } from '../common/utils/platform';
99
import { parseVersion } from '../pythonEnvironments/base/info/pythonVersion';
1010
import { PythonEnvType } from '../pythonEnvironments/base/info';
1111
import { traceError, traceInfo } from '../logging';
12+
import { reportActiveInterpreterChanged } from '../environmentApi';
13+
import { getWorkspaceFolder } from '../common/vscodeApis/workspaceApis';
1214

1315
function toEnvironmentType(pythonEnv: PythonEnvironment): EnvironmentType {
1416
if (pythonEnv.envId.managerId.toLowerCase().endsWith('system')) {
@@ -96,8 +98,20 @@ function toLegacyType(env: PythonEnvironment): PythonEnvironmentLegacy {
9698
};
9799
}
98100

101+
const previousEnvMap = new Map<string, PythonEnvironment | undefined>();
99102
export async function getActiveInterpreterLegacy(resource?: Uri): Promise<PythonEnvironmentLegacy | undefined> {
103+
const api = await getEnvExtApi();
104+
const uri = resource ? api.getPythonProject(resource)?.uri : undefined;
105+
100106
const pythonEnv = await getEnvironment(resource);
107+
const oldEnv = previousEnvMap.get(uri?.fsPath || '');
108+
const newEnv = pythonEnv ? toLegacyType(pythonEnv) : undefined;
109+
if (newEnv && oldEnv?.envId.id !== pythonEnv?.envId.id) {
110+
reportActiveInterpreterChanged({
111+
resource: getWorkspaceFolder(resource),
112+
path: newEnv.path,
113+
});
114+
}
101115
return pythonEnv ? toLegacyType(pythonEnv) : undefined;
102116
}
103117

src/client/interpreter/interpreterService.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,11 @@ export class InterpreterService implements Disposable, IInterpreterService {
291291
private async ensureEnvironmentContainsPython(pythonPath: string, workspaceFolder: WorkspaceFolder | undefined) {
292292
if (useEnvExtension()) {
293293
await ensureEnvironmentContainsPythonLegacy(pythonPath);
294+
this.didChangeInterpreterEmitter.fire(workspaceFolder?.uri);
295+
reportActiveInterpreterChanged({
296+
path: pythonPath,
297+
resource: workspaceFolder,
298+
});
294299
return;
295300
}
296301

src/client/terminals/codeExecution/codeExecutionManager.ts

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
'use strict';
55

66
import { inject, injectable } from 'inversify';
7-
import { Disposable, EventEmitter, Uri } from 'vscode';
7+
import { Disposable, EventEmitter, Terminal, Uri } from 'vscode';
88

99
import { ICommandManager, IDocumentManager } from '../../common/application/types';
1010
import { Commands } from '../../common/constants';
@@ -22,6 +22,7 @@ import {
2222
triggerCreateEnvironmentCheckNonBlocking,
2323
} from '../../pythonEnvironments/creation/createEnvironmentTrigger';
2424
import { ReplType } from '../../repl/types';
25+
import { runInDedicatedTerminal, runInTerminal, useEnvExtension } from '../../envExt/api.internal';
2526

2627
@injectable()
2728
export class CodeExecutionManager implements ICodeExecutionManager {
@@ -40,6 +41,16 @@ export class CodeExecutionManager implements ICodeExecutionManager {
4041
this.disposableRegistry.push(
4142
this.commandManager.registerCommand(cmd as any, async (file: Resource) => {
4243
traceVerbose(`Attempting to run Python file`, file?.fsPath);
44+
45+
if (useEnvExtension()) {
46+
try {
47+
await this.executeUsingExtension(file, cmd === Commands.Exec_In_Separate_Terminal);
48+
} catch (ex) {
49+
traceError('Failed to execute file in terminal', ex);
50+
}
51+
return;
52+
}
53+
4354
const interpreterService = this.serviceContainer.get<IInterpreterService>(IInterpreterService);
4455
const interpreter = await interpreterService.getActiveInterpreter(file);
4556
if (!interpreter) {
@@ -101,6 +112,42 @@ export class CodeExecutionManager implements ICodeExecutionManager {
101112
),
102113
);
103114
}
115+
116+
private async executeUsingExtension(file: Resource, dedicated: boolean): Promise<void> {
117+
const codeExecutionHelper = this.serviceContainer.get<ICodeExecutionHelper>(ICodeExecutionHelper);
118+
file = file instanceof Uri ? file : undefined;
119+
let fileToExecute = file ? file : await codeExecutionHelper.getFileToExecute();
120+
if (!fileToExecute) {
121+
return;
122+
}
123+
const fileAfterSave = await codeExecutionHelper.saveFileIfDirty(fileToExecute);
124+
if (fileAfterSave) {
125+
fileToExecute = fileAfterSave;
126+
}
127+
128+
const show = this.shouldTerminalFocusOnStart(fileToExecute);
129+
let terminal: Terminal | undefined;
130+
if (dedicated) {
131+
terminal = await runInDedicatedTerminal(
132+
fileToExecute,
133+
[fileToExecute.fsPath.fileToCommandArgumentForPythonExt()],
134+
undefined,
135+
show,
136+
);
137+
} else {
138+
terminal = await runInTerminal(
139+
fileToExecute,
140+
[fileToExecute.fsPath.fileToCommandArgumentForPythonExt()],
141+
undefined,
142+
show,
143+
);
144+
}
145+
146+
if (terminal) {
147+
terminal.show();
148+
}
149+
}
150+
104151
private async executeFileInTerminal(
105152
file: Resource,
106153
trigger: 'command' | 'icon',

src/client/testing/testController/pytest/pytestExecutionAdapter.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,9 +181,13 @@ export class PytestTestExecutionAdapter implements ITestExecutionAdapter {
181181
} else if (useEnvExtension()) {
182182
const pythonEnv = await getEnvironment(uri);
183183
if (pythonEnv) {
184+
const scriptPath = path.join(fullPluginPath, 'vscode_pytest', 'run_pytest_script.py');
185+
const runArgs = [scriptPath, ...testArgs];
186+
traceInfo(`Running pytest with arguments: ${runArgs.join(' ')} for workspace ${uri.fsPath} \r\n`);
187+
184188
const proc = await runInBackground(pythonEnv, {
185189
cwd,
186-
args: testArgs,
190+
args: runArgs,
187191
env: (mutableEnv as unknown) as { [key: string]: string },
188192
});
189193
runInstance?.token.onCancellationRequested(() => {

0 commit comments

Comments
 (0)