Skip to content

Commit 1a96c22

Browse files
authored
feat: add pyenv support (#409)
1 parent 836fa96 commit 1a96c22

File tree

9 files changed

+645
-14
lines changed

9 files changed

+645
-14
lines changed

src/common/localize.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,12 @@ export namespace CondaStrings {
152152
);
153153
}
154154

155+
export namespace PyenvStrings {
156+
export const pyenvManager = l10n.t('Manages Pyenv Python versions');
157+
export const pyenvDiscovering = l10n.t('Discovering Pyenv Python versions');
158+
export const pyenvRefreshing = l10n.t('Refreshing Pyenv Python versions');
159+
}
160+
155161
export namespace ProjectCreatorString {
156162
export const addExistingProjects = l10n.t('Add Existing Projects');
157163
export const autoFindProjects = l10n.t('Auto Find Projects');

src/extension.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ import { EnvironmentManagers, ProjectCreators, PythonProjectManager } from './in
6666
import { registerSystemPythonFeatures } from './managers/builtin/main';
6767
import { createNativePythonFinder, NativePythonFinder } from './managers/common/nativePythonFinder';
6868
import { registerCondaFeatures } from './managers/conda/main';
69+
import { registerPyenvFeatures } from './managers/pyenv/main';
6970

7071
export async function activate(context: ExtensionContext): Promise<PythonEnvironmentApi> {
7172
const start = new StopWatch();
@@ -294,6 +295,7 @@ export async function activate(context: ExtensionContext): Promise<PythonEnviron
294295
await Promise.all([
295296
registerSystemPythonFeatures(nativeFinder, context.subscriptions, outputChannel),
296297
registerCondaFeatures(nativeFinder, context.subscriptions, outputChannel),
298+
registerPyenvFeatures(nativeFinder, context.subscriptions),
297299
shellStartupVarsMgr.initialize(),
298300
]);
299301

src/managers/builtin/venvUtils.ts

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ import {
3232
NativePythonEnvironmentKind,
3333
NativePythonFinder,
3434
} from '../common/nativePythonFinder';
35-
import { shortVersion, sortEnvironments } from '../common/utils';
35+
import { pathForGitBash, shortVersion, sortEnvironments } from '../common/utils';
3636
import { isUvInstalled, runPython, runUV } from './helpers';
3737
import { getProjectInstallable, getWorkspacePackagesToInstall, PipPackages } from './pipUtils';
3838
import { resolveSystemPythonEnvironmentPath } from './utils';
@@ -113,10 +113,6 @@ function getName(binPath: string): string {
113113
return path.basename(dir1);
114114
}
115115

116-
function pathForGitBash(binPath: string): string {
117-
return isWindows() ? binPath.replace(/\\/g, '/').replace(/^([a-zA-Z]):/, '/$1') : binPath;
118-
}
119-
120116
async function getPythonInfo(env: NativeEnvInfo): Promise<PythonEnvironmentInfo> {
121117
if (env.executable && env.version && env.prefix) {
122118
const venvName = env.name ?? getName(env.executable);

src/managers/common/utils.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { PythonEnvironment } from '../../api';
2+
import { isWindows } from '../../common/utils/platformUtils';
23
import { Installable } from './types';
34

45
export function noop() {
@@ -82,3 +83,7 @@ export function mergePackages(common: Installable[], installed: string[]): Insta
8283
.concat(notInCommon.map((pkg) => ({ name: pkg, displayName: pkg })))
8384
.sort((a, b) => a.name.localeCompare(b.name));
8485
}
86+
87+
export function pathForGitBash(binPath: string): string {
88+
return isWindows() ? binPath.replace(/\\/g, '/').replace(/^([a-zA-Z]):/, '/$1') : binPath;
89+
}

src/managers/conda/condaEnvManager.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,14 +58,13 @@ export class CondaEnvManager implements EnvironmentManager, Disposable {
5858
this.name = 'conda';
5959
this.displayName = 'Conda';
6060
this.preferredPackageManagerId = 'ms-python.python:conda';
61-
this.description = undefined;
6261
this.tooltip = new MarkdownString(CondaStrings.condaManager, true);
6362
}
6463

6564
name: string;
6665
displayName: string;
67-
preferredPackageManagerId: string = 'ms-python.python:conda';
68-
description: string | undefined;
66+
preferredPackageManagerId: string;
67+
description?: string;
6968
tooltip: string | MarkdownString;
7069
iconPath?: IconPath;
7170

src/managers/conda/condaUtils.ts

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -53,21 +53,22 @@ import {
5353
} from '../common/nativePythonFinder';
5454
import { selectFromCommonPackagesToInstall } from '../common/pickers';
5555
import { Installable } from '../common/types';
56-
import { shortVersion, sortEnvironments } from '../common/utils';
56+
import { pathForGitBash, shortVersion, sortEnvironments } from '../common/utils';
5757

5858
export const CONDA_PATH_KEY = `${ENVS_EXTENSION_ID}:conda:CONDA_PATH`;
5959
export const CONDA_PREFIXES_KEY = `${ENVS_EXTENSION_ID}:conda:CONDA_PREFIXES`;
6060
export const CONDA_WORKSPACE_KEY = `${ENVS_EXTENSION_ID}:conda:WORKSPACE_SELECTED`;
6161
export const CONDA_GLOBAL_KEY = `${ENVS_EXTENSION_ID}:conda:GLOBAL_SELECTED`;
6262

63+
let condaPath: string | undefined;
6364
export async function clearCondaCache(): Promise<void> {
6465
const state = await getWorkspacePersistentState();
6566
await state.clear([CONDA_PATH_KEY, CONDA_WORKSPACE_KEY, CONDA_GLOBAL_KEY]);
6667
const global = await getGlobalPersistentState();
6768
await global.clear([CONDA_PREFIXES_KEY]);
69+
condaPath = undefined;
6870
}
6971

70-
let condaPath: string | undefined;
7172
async function setConda(conda: string): Promise<void> {
7273
condaPath = conda;
7374
const state = await getWorkspacePersistentState();
@@ -283,10 +284,6 @@ function isPrefixOf(roots: string[], e: string): boolean {
283284
return false;
284285
}
285286

286-
function pathForGitBash(binPath: string): string {
287-
return isWindows() ? binPath.replace(/\\/g, '/').replace(/^([a-zA-Z]):/, '/$1') : binPath;
288-
}
289-
290287
function getNamedCondaPythonInfo(
291288
name: string,
292289
prefix: string,

src/managers/pyenv/main.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { Disposable } from 'vscode';
2+
import { PythonEnvironmentApi } from '../../api';
3+
import { traceInfo } from '../../common/logging';
4+
import { getPythonApi } from '../../features/pythonApi';
5+
import { NativePythonFinder } from '../common/nativePythonFinder';
6+
import { PyEnvManager } from './pyenvManager';
7+
import { getPyenv } from './pyenvUtils';
8+
9+
export async function registerPyenvFeatures(
10+
nativeFinder: NativePythonFinder,
11+
disposables: Disposable[],
12+
): Promise<void> {
13+
const api: PythonEnvironmentApi = await getPythonApi();
14+
15+
try {
16+
await getPyenv(nativeFinder);
17+
18+
const mgr = new PyEnvManager(nativeFinder, api);
19+
disposables.push(mgr, api.registerEnvironmentManager(mgr));
20+
} catch (ex) {
21+
traceInfo('Pyenv not found, turning off pyenv features.', ex);
22+
}
23+
}

0 commit comments

Comments
 (0)