|
1 | 1 | import * as path from 'path'; |
2 | 2 | import { EventEmitter, LogOutputChannel, MarkdownString, ProgressLocation, ThemeIcon, Uri, window } from 'vscode'; |
3 | 3 | import { |
| 4 | + CreateEnvironmentOptions, |
| 5 | + CreateEnvironmentScope, |
4 | 6 | DidChangeEnvironmentEventArgs, |
5 | 7 | DidChangeEnvironmentsEventArgs, |
6 | 8 | EnvironmentChangeKind, |
@@ -28,6 +30,7 @@ import { |
28 | 30 | setSystemEnvForWorkspaces, |
29 | 31 | } from './cache'; |
30 | 32 | import { refreshPythons, resolveSystemPythonEnvironmentPath } from './utils'; |
| 33 | +import { installPythonWithUv, promptInstallPythonViaUv, selectPythonVersionToInstall } from './uvPythonInstaller'; |
31 | 34 |
|
32 | 35 | export class SysPythonManager implements EnvironmentManager { |
33 | 36 | private collection: PythonEnvironment[] = []; |
@@ -70,6 +73,27 @@ export class SysPythonManager implements EnvironmentManager { |
70 | 73 |
|
71 | 74 | try { |
72 | 75 | await this.internalRefresh(false, SysManagerStrings.sysManagerDiscovering); |
| 76 | + |
| 77 | + // If no Python environments were found, offer to install via uv |
| 78 | + if (this.collection.length === 0) { |
| 79 | + const pythonPath = await promptInstallPythonViaUv('activation', this.log); |
| 80 | + if (pythonPath) { |
| 81 | + const resolved = await resolveSystemPythonEnvironmentPath( |
| 82 | + pythonPath, |
| 83 | + this.nativeFinder, |
| 84 | + this.api, |
| 85 | + this, |
| 86 | + ); |
| 87 | + if (resolved) { |
| 88 | + this.collection.push(resolved); |
| 89 | + this.globalEnv = resolved; |
| 90 | + await setSystemEnvForGlobal(resolved.environmentPath.fsPath); |
| 91 | + this._onDidChangeEnvironments.fire([ |
| 92 | + { environment: resolved, kind: EnvironmentChangeKind.add }, |
| 93 | + ]); |
| 94 | + } |
| 95 | + } |
| 96 | + } |
73 | 97 | } finally { |
74 | 98 | this._initialized.resolve(); |
75 | 99 | } |
@@ -220,6 +244,39 @@ export class SysPythonManager implements EnvironmentManager { |
220 | 244 | return resolved; |
221 | 245 | } |
222 | 246 |
|
| 247 | + /** |
| 248 | + * Installs a global Python using uv. |
| 249 | + * This method shows a QuickPick to select the Python version, then installs it. |
| 250 | + */ |
| 251 | + async create( |
| 252 | + _scope: CreateEnvironmentScope, |
| 253 | + _options?: CreateEnvironmentOptions, |
| 254 | + ): Promise<PythonEnvironment | undefined> { |
| 255 | + // Show QuickPick to select Python version |
| 256 | + const selectedVersion = await selectPythonVersionToInstall(); |
| 257 | + if (!selectedVersion) { |
| 258 | + // User cancelled |
| 259 | + return undefined; |
| 260 | + } |
| 261 | + |
| 262 | + const pythonPath = await installPythonWithUv(this.log, selectedVersion); |
| 263 | + |
| 264 | + if (pythonPath) { |
| 265 | + // Resolve the installed Python using NativePythonFinder instead of full refresh |
| 266 | + const resolved = await resolveSystemPythonEnvironmentPath(pythonPath, this.nativeFinder, this.api, this); |
| 267 | + if (resolved) { |
| 268 | + // Add to collection, update global env, and fire change event |
| 269 | + this.collection.push(resolved); |
| 270 | + this.globalEnv = resolved; |
| 271 | + await setSystemEnvForGlobal(resolved.environmentPath.fsPath); |
| 272 | + this._onDidChangeEnvironments.fire([{ environment: resolved, kind: EnvironmentChangeKind.add }]); |
| 273 | + return resolved; |
| 274 | + } |
| 275 | + } |
| 276 | + |
| 277 | + return undefined; |
| 278 | + } |
| 279 | + |
223 | 280 | async clearCache(): Promise<void> { |
224 | 281 | await clearSystemEnvCache(); |
225 | 282 | } |
|
0 commit comments