Skip to content

Commit d8d2383

Browse files
Load SDK from Python venv (#5)
1 parent 1db9f6d commit d8d2383

File tree

15 files changed

+311
-1374
lines changed

15 files changed

+311
-1374
lines changed

extension/commands/run.ts

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,10 @@ import * as vscode from 'vscode';
99
import { DisposableContext } from '../utils/disposableContext';
1010
import * as path from 'path';
1111
import * as config from '../utils/config';
12-
import { MAXSDK } from '../sdk/sdk';
13-
import { MAXSDKManager } from '../sdk/sdkManager';
1412
import { MojoDebugConfiguration } from '../debug/debug';
1513
import md5 from 'md5';
1614
import { Optional } from '../types';
15+
import { PythonEnvironmentManager, SDK } from '../pyenv';
1716

1817
type FileArgs = {
1918
runArgs: string[];
@@ -24,13 +23,16 @@ type FileArgs = {
2423
* This class provides a manager for executing and debugging mojo files.
2524
*/
2625
class ExecutionManager extends DisposableContext {
27-
readonly sdkManager: MAXSDKManager;
26+
readonly envManager: PythonEnvironmentManager;
2827
private context: vscode.ExtensionContext;
2928

30-
constructor(sdkManager: MAXSDKManager, context: vscode.ExtensionContext) {
29+
constructor(
30+
sdkManager: PythonEnvironmentManager,
31+
context: vscode.ExtensionContext,
32+
) {
3133
super();
3234

33-
this.sdkManager = sdkManager;
35+
this.envManager = sdkManager;
3436
this.context = context;
3537
this.activateRunCommands();
3638
}
@@ -150,7 +152,7 @@ class ExecutionManager extends DisposableContext {
150152
}
151153

152154
// Find the config for processing this file.
153-
const sdk = await this.sdkManager.findSDK(/*hideRepeatedErrors=*/ false);
155+
const sdk = await this.envManager.getActiveSDK();
154156

155157
if (!sdk) {
156158
return;
@@ -161,7 +163,7 @@ class ExecutionManager extends DisposableContext {
161163
terminal.show();
162164
terminal.sendText(
163165
quote([
164-
sdk.config.mojoDriverPath,
166+
sdk.mojoPath,
165167
'run',
166168
...this.getBuildArgs(doc.fileName),
167169
doc.fileName,
@@ -212,8 +214,8 @@ class ExecutionManager extends DisposableContext {
212214
/**
213215
* Get a terminal to use for the given file.
214216
*/
215-
getTerminalForFile(doc: vscode.TextDocument, sdk: MAXSDK): vscode.Terminal {
216-
const fullId = `${doc.fileName} · ${sdk.config.modularHomePath}`;
217+
getTerminalForFile(doc: vscode.TextDocument, sdk: SDK): vscode.Terminal {
218+
const fullId = `${doc.fileName} · ${sdk.homePath}`;
217219
// We have to keep the full terminal name short so that VS Code renders it nicely,
218220
// and we have to keep it unique among other files.
219221
const terminalName = `Mojo: ${path.basename(doc.fileName)} · ${md5(fullId).substring(0, 5)}`;
@@ -285,8 +287,8 @@ class ExecutionManager extends DisposableContext {
285287
* commands.
286288
*/
287289
export function activateRunCommands(
288-
sdkManager: MAXSDKManager,
290+
envManager: PythonEnvironmentManager,
289291
context: vscode.ExtensionContext,
290292
): vscode.Disposable {
291-
return new ExecutionManager(sdkManager, context);
293+
return new ExecutionManager(envManager, context);
292294
}

extension/debug/debug.ts

Lines changed: 58 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@ import { DisposableContext } from '../utils/disposableContext';
1111
import { getAllOpenMojoFiles, WorkspaceAwareFile } from '../utils/files';
1212
import { activatePickProcessToAttachCommand } from './attachQuickPick';
1313
import { initializeInlineLocalVariablesProvider } from './inlineVariables';
14-
import { MAXSDK } from '../sdk/sdk';
1514
import { MojoExtension } from '../extension';
16-
import { MAXSDKManager } from '../sdk/sdkManager';
1715
import { quote } from 'shell-quote';
1816
import * as util from 'util';
1917
import { execFile as execFileBase } from 'child_process';
2018
import { Optional } from '../types';
19+
import { PythonEnvironmentManager, SDK, SDKKind } from '../pyenv';
20+
import { Logger } from '../logging';
2121
const execFile = util.promisify(execFileBase);
2222

2323
/**
@@ -76,12 +76,15 @@ const DEBUG_TYPE: string = 'mojo-lldb';
7676
*/
7777
async function findSDKForDebugConfiguration(
7878
config: MojoDebugConfiguration,
79-
sdkManager: MAXSDKManager,
80-
): Promise<Optional<MAXSDK>> {
79+
envManager: PythonEnvironmentManager,
80+
): Promise<Optional<SDK>> {
8181
if (config.modularHomePath !== undefined) {
82-
return sdkManager.createAdHocSDKAndShowError(config.modularHomePath);
82+
return envManager.createSDKFromHomePath(
83+
SDKKind.Custom,
84+
config.modularHomePath,
85+
);
8386
}
84-
return sdkManager.findSDK(/*hideRepeatedErrors=*/ false);
87+
return envManager.getActiveSDK();
8588
}
8689
/**
8790
* This class defines a factory used to find the lldb-vscode binary to use
@@ -90,10 +93,12 @@ async function findSDKForDebugConfiguration(
9093
class MojoDebugAdapterDescriptorFactory
9194
implements vscode.DebugAdapterDescriptorFactory
9295
{
93-
private sdkManager: MAXSDKManager;
96+
private envManager: PythonEnvironmentManager;
97+
private logger: Logger;
9498

95-
constructor(sdkManager: MAXSDKManager) {
96-
this.sdkManager = sdkManager;
99+
constructor(envManager: PythonEnvironmentManager, logger: Logger) {
100+
this.envManager = envManager;
101+
this.logger = logger;
97102
}
98103

99104
async createDebugAdapterDescriptor(
@@ -102,54 +107,47 @@ class MojoDebugAdapterDescriptorFactory
102107
): Promise<Optional<vscode.DebugAdapterDescriptor>> {
103108
const sdk = await findSDKForDebugConfiguration(
104109
session.configuration,
105-
this.sdkManager,
110+
this.envManager,
106111
);
107112

108113
// We don't need to show error messages here because
109114
// `findSDKConfigForDebugSession` does that.
110115
if (!sdk) {
111-
this.sdkManager.logger.error(
112-
"Couldn't find an SDK for the debug session",
113-
);
116+
this.logger.error("Couldn't find an SDK for the debug session");
114117
return undefined;
115118
}
116-
this.sdkManager.logger.info(
117-
`Using the SDK ${sdk.config.version.toString()} for the debug session`,
118-
);
119-
if (sdk.config.modularHomePath.endsWith('.derived')) {
119+
this.logger.info(`Using the SDK ${sdk.version} for the debug session`);
120+
if (sdk.homePath.endsWith('.derived')) {
120121
// Debug adapters from dev sdks tend to be corrupted because dependencies
121122
// might need to be rebuilt, so we run a simple verification.
122123
try {
123-
await execFile(sdk.config.mojoLLDBVSCodePath, ['--help']);
124+
await execFile(sdk.dapPath, ['--help']);
124125
} catch (ex: any) {
125126
const { stderr, stdout } = ex;
126-
this.sdkManager.logger.main.outputChannel.appendLine(
127+
this.logger.main.outputChannel.appendLine(
127128
'\n\n\n===== LLDB Debug Adapter verification =====',
128129
);
129-
this.sdkManager.logger.error(
130-
'Unable to execute the LLDB Debug Adapter.',
131-
ex,
132-
);
130+
this.logger.error('Unable to execute the LLDB Debug Adapter.', ex);
133131
if (stdout) {
134-
this.sdkManager.logger.info('stdout: ' + stdout);
132+
this.logger.info('stdout: ' + stdout);
135133
}
136134
if (stderr) {
137-
this.sdkManager.logger.info('stderr: ' + stderr);
135+
this.logger.info('stderr: ' + stderr);
138136
}
139-
this.sdkManager.logger.main.outputChannel.show();
137+
this.logger.main.outputChannel.show();
140138

141-
this.sdkManager.showBazelwRunInstallPrompt(
142-
'The LLDB Debug Adapter seems to be corrupted.',
143-
sdk.config.modularHomePath,
144-
);
139+
// this.envManager.showBazelwRunInstallPrompt(
140+
// 'The LLDB Debug Adapter seems to be corrupted.',
141+
// sdk.homePath,
142+
// );
145143
}
146144
}
147145

148-
return new vscode.DebugAdapterExecutable(sdk.config.mojoLLDBVSCodePath, [
146+
return new vscode.DebugAdapterExecutable(sdk.dapPath, [
149147
'--repl-mode',
150148
'variable',
151149
'--pre-init-command',
152-
`?!plugin load '${sdk.config.mojoLLDBPluginPath}'`,
150+
`?!plugin load '${sdk.lldbPluginPath}'`,
153151
]);
154152
}
155153
}
@@ -178,10 +176,12 @@ class MojoCudaGdbDebugAdapterDescriptorFactory
178176
class MojoDebugConfigurationResolver
179177
implements vscode.DebugConfigurationProvider
180178
{
181-
private sdkManager: MAXSDKManager;
179+
private envManager: PythonEnvironmentManager;
180+
private logger: Logger;
182181

183-
constructor(sdkManager: MAXSDKManager) {
184-
this.sdkManager = sdkManager;
182+
constructor(envManager: PythonEnvironmentManager, logger: Logger) {
183+
this.envManager = envManager;
184+
this.logger = logger;
185185
}
186186

187187
async resolveDebugConfigurationWithSubstitutedVariables?(
@@ -191,7 +191,7 @@ class MojoDebugConfigurationResolver
191191
): Promise<undefined | vscode.DebugConfiguration> {
192192
const sdk = await findSDKForDebugConfiguration(
193193
debugConfiguration,
194-
this.sdkManager,
194+
this.envManager,
195195
);
196196
// We don't need to show error messages here because
197197
// `findSDKConfigForDebugSession` does that.
@@ -211,7 +211,7 @@ class MojoDebugConfigurationResolver
211211
const message = `Mojo Debug error: the file '${
212212
debugConfiguration.mojoFile
213213
}' doesn't have the .🔥 or .mojo extension.`;
214-
this.sdkManager.logger.error(message);
214+
this.logger.error(message);
215215
vscode.window.showErrorMessage(message);
216216
return undefined;
217217
}
@@ -224,7 +224,7 @@ class MojoDebugConfigurationResolver
224224
debugConfiguration.mojoFile,
225225
...(debugConfiguration.args || []),
226226
];
227-
debugConfiguration.program = sdk.config.mojoDriverPath;
227+
debugConfiguration.program = sdk.mojoPath;
228228
}
229229

230230
// We give preference to the init commands specified by the user.
@@ -277,7 +277,7 @@ class MojoDebugConfigurationResolver
277277

278278
// Pull in the additional visualizers within the lldb-visualizers dir.
279279
if (await sdk.lldbHasPythonScriptingSupport()) {
280-
const visualizersDir = sdk.config.mojoLLDBVisualizersPath;
280+
const visualizersDir = sdk.visualizersPath;
281281
const visualizers = await vscode.workspace.fs.readDirectory(
282282
vscode.Uri.file(visualizersDir),
283283
);
@@ -291,7 +291,7 @@ class MojoDebugConfigurationResolver
291291
`LLDB_VSCODE_RIT_TIMEOUT_IN_MS=${initializationTimeoutSec * 1000}`, // runInTerminal initialization timeout.
292292
];
293293

294-
env.push(`MODULAR_HOME=${sdk.config.modularHomePath}`);
294+
env.push(`MODULAR_HOME=${sdk.homePath}`);
295295

296296
debugConfiguration.env = [...env, ...(debugConfiguration.env || [])];
297297
return debugConfiguration as vscode.DebugConfiguration;
@@ -324,18 +324,20 @@ class MojoDebugConfigurationResolver
324324
class MojoCudaGdbDebugConfigurationResolver
325325
implements vscode.DebugConfigurationProvider
326326
{
327-
private sdkManager: MAXSDKManager;
327+
private envManager: PythonEnvironmentManager;
328+
private logger: Logger;
328329

329-
constructor(sdkManager: MAXSDKManager) {
330-
this.sdkManager = sdkManager;
330+
constructor(envManager: PythonEnvironmentManager, logger: Logger) {
331+
this.envManager = envManager;
332+
this.logger = logger;
331333
}
332334

333335
async resolveDebugConfigurationWithSubstitutedVariables?(
334336
_folder: Optional<vscode.WorkspaceFolder>,
335337
debugConfigIn: MojoCudaGdbDebugConfiguration,
336338
_token?: vscode.CancellationToken,
337339
): Promise<undefined | vscode.DebugConfiguration> {
338-
const maybeErrorMessage = await checkNsightInstall(this.sdkManager.logger);
340+
const maybeErrorMessage = await checkNsightInstall(this.logger);
339341
if (maybeErrorMessage) {
340342
return undefined;
341343
}
@@ -346,7 +348,7 @@ class MojoCudaGdbDebugConfigurationResolver
346348

347349
const sdk = await findSDKForDebugConfiguration(
348350
debugConfigIn as vscode.DebugConfiguration,
349-
this.sdkManager,
351+
this.envManager,
350352
);
351353
// We don't need to show error messages here because
352354
// `findSDKConfigForDebugSession` does that.
@@ -355,7 +357,7 @@ class MojoCudaGdbDebugConfigurationResolver
355357
}
356358
// If we have a mojoFile config, translate it to program plus args.
357359
if (debugConfigIn.mojoFile) {
358-
debugConfig.program = sdk.config.mojoDriverPath;
360+
debugConfig.program = sdk.mojoPath;
359361
args = [
360362
'run',
361363
'--no-optimization',
@@ -376,7 +378,7 @@ class MojoCudaGdbDebugConfigurationResolver
376378
// cuda-gdb takes environment as a list of objects like:
377379
// [{"name": "HOME", "value": "/home/ubuntu"}]
378380
let env = [];
379-
env.push(`MODULAR_HOME=${sdk.config.modularHomePath}`);
381+
env.push(`MODULAR_HOME=${sdk.homePath}`);
380382
env = [...env, ...(debugConfigIn.env || [])];
381383
debugConfig.environment = env.map((envStr: string) => {
382384
const split = envStr.split('=');
@@ -423,17 +425,20 @@ class MojoDebugDynamicConfigurationProvider
423425
* mojo debugging.
424426
*/
425427
export class MojoDebugManager extends DisposableContext {
426-
private sdkManager: MAXSDKManager;
428+
private envManager: PythonEnvironmentManager;
427429

428-
constructor(extension: MojoExtension, sdkManager: MAXSDKManager) {
430+
constructor(extension: MojoExtension, envManager: PythonEnvironmentManager) {
429431
super();
430-
this.sdkManager = sdkManager;
432+
this.envManager = envManager;
431433

432434
// Register the lldb-vscode debug adapter.
433435
this.pushSubscription(
434436
vscode.debug.registerDebugAdapterDescriptorFactory(
435437
DEBUG_TYPE,
436-
new MojoDebugAdapterDescriptorFactory(this.sdkManager),
438+
new MojoDebugAdapterDescriptorFactory(
439+
this.envManager,
440+
extension.logger,
441+
),
437442
),
438443
);
439444

@@ -457,7 +462,7 @@ export class MojoDebugManager extends DisposableContext {
457462
this.pushSubscription(
458463
vscode.debug.registerDebugConfigurationProvider(
459464
DEBUG_TYPE,
460-
new MojoDebugConfigurationResolver(sdkManager),
465+
new MojoDebugConfigurationResolver(envManager, extension.logger),
461466
),
462467
);
463468

@@ -498,7 +503,7 @@ export class MojoDebugManager extends DisposableContext {
498503
this.pushSubscription(
499504
vscode.debug.registerDebugConfigurationProvider(
500505
'mojo-cuda-gdb',
501-
new MojoCudaGdbDebugConfigurationResolver(sdkManager),
506+
new MojoCudaGdbDebugConfigurationResolver(envManager, extension.logger),
502507
),
503508
);
504509
}

0 commit comments

Comments
 (0)