Skip to content

Commit aa29d83

Browse files
committed
Restrict conda binary from PATH or Settings
1 parent e772738 commit aa29d83

File tree

3 files changed

+47
-4
lines changed

3 files changed

+47
-4
lines changed

src/client/common/utils/platform.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,3 +71,11 @@ export function getUserHomeDir(): string | undefined {
7171
export function isWindows(): boolean {
7272
return getOSType() === OSType.Windows;
7373
}
74+
75+
export function getPathEnvVariable(): string[] {
76+
const value = getEnvironmentVariable('PATH') || getEnvironmentVariable('Path');
77+
if (value) {
78+
return value.split(isWindows() ? ';' : ':');
79+
}
80+
return [];
81+
}

src/client/pythonEnvironments/common/environmentManagers/conda.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import { OUTPUT_MARKER_SCRIPT } from '../../../common/process/internal/scripts';
2424
import { splitLines } from '../../../common/stringUtils';
2525
import { SpawnOptions } from '../../../common/process/types';
2626
import { sleep } from '../../../common/utils/async';
27+
import { getConfiguration } from '../../../common/vscodeApis/workspaceApis';
2728

2829
export const AnacondaCompanyName = 'Anaconda, Inc.';
2930
export const CONDAPATH_SETTING_KEY = 'condaPath';
@@ -633,3 +634,8 @@ export async function getCondaEnvDirs(): Promise<string[] | undefined> {
633634
const conda = await Conda.getConda();
634635
return conda?.getEnvDirs();
635636
}
637+
638+
export function getCondaPathSetting(): string | undefined {
639+
const config = getConfiguration('python');
640+
return config.get<string>(CONDAPATH_SETTING_KEY, '');
641+
}

src/client/pythonEnvironments/nativeAPI.ts

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,14 @@ import {
2020
NativePythonFinder,
2121
} from './base/locators/common/nativePythonFinder';
2222
import { createDeferred, Deferred } from '../common/utils/async';
23-
import { Architecture, getUserHomeDir } from '../common/utils/platform';
23+
import { Architecture, getPathEnvVariable, getUserHomeDir } from '../common/utils/platform';
2424
import { parseVersion } from './base/info/pythonVersion';
2525
import { cache } from '../common/utils/decorators';
2626
import { traceError, traceInfo, traceLog, traceWarn } from '../logging';
2727
import { StopWatch } from '../common/utils/stopWatch';
2828
import { FileChangeType } from '../common/platform/fileSystemWatcher';
2929
import { categoryToKind, NativePythonEnvironmentKind } from './base/locators/common/nativePythonUtils';
30-
import { getCondaEnvDirs, setCondaBinary } from './common/environmentManagers/conda';
30+
import { getCondaEnvDirs, getCondaPathSetting, setCondaBinary } from './common/environmentManagers/conda';
3131
import { setPyEnvBinary } from './common/environmentManagers/pyenv';
3232
import {
3333
createPythonWatcher,
@@ -166,6 +166,12 @@ function isSubDir(pathToCheck: string | undefined, parents: string[]): boolean {
166166
});
167167
}
168168

169+
function foundOnPath(fsPath: string): boolean {
170+
const paths = getPathEnvVariable().map((p) => path.normalize(p).toLowerCase());
171+
const normalized = path.normalize(fsPath).toLowerCase();
172+
return paths.some((p) => normalized.includes(p));
173+
}
174+
169175
function getName(nativeEnv: NativeEnvInfo, kind: PythonEnvKind, condaEnvDirs: string[]): string {
170176
if (nativeEnv.name) {
171177
return nativeEnv.name;
@@ -387,13 +393,36 @@ class NativePythonEnvironments implements IDiscoveryAPI, Disposable {
387393
return undefined;
388394
}
389395

396+
private condaPathAlreadySet: string | undefined;
397+
390398
// eslint-disable-next-line class-methods-use-this
391399
private processEnvManager(native: NativeEnvManagerInfo) {
392400
const tool = native.tool.toLowerCase();
393401
switch (tool) {
394402
case 'conda':
395-
traceLog(`Conda environment manager found at: ${native.executable}`);
396-
setCondaBinary(native.executable);
403+
{
404+
traceLog(`Conda environment manager found at: ${native.executable}`);
405+
const settingPath = getCondaPathSetting();
406+
if (!this.condaPathAlreadySet) {
407+
if (settingPath === '') {
408+
if (foundOnPath(native.executable)) {
409+
setCondaBinary(native.executable);
410+
this.condaPathAlreadySet = native.executable;
411+
traceInfo(`Using conda: ${native.executable}`);
412+
} else {
413+
traceInfo(`Conda not found on PATH, skipping: ${native.executable}`);
414+
traceInfo(
415+
'You can set the path to conda using the setting: `python.condaPath` if you want to use a different conda binary',
416+
);
417+
}
418+
} else {
419+
traceInfo(`Using conda from setting: ${settingPath}`);
420+
this.condaPathAlreadySet = settingPath;
421+
}
422+
} else {
423+
traceInfo(`Conda already set to: ${this.condaPathAlreadySet}`);
424+
}
425+
}
397426
break;
398427
case 'pyenv':
399428
traceLog(`Pyenv environment manager found at: ${native.executable}`);

0 commit comments

Comments
 (0)