From d69d6059df6b7f3d76f35ea427ebfcc09155aa00 Mon Sep 17 00:00:00 2001 From: Don Jayamanne Date: Wed, 10 Jul 2024 12:53:57 +1000 Subject: [PATCH] Gather additional data to determine failures in identifying conda envs (#23779) --- .../composite/envsCollectionService.ts | 69 ++++++++++++++++++- src/client/telemetry/index.ts | 47 +++++++++++++ 2 files changed, 114 insertions(+), 2 deletions(-) diff --git a/src/client/pythonEnvironments/base/locators/composite/envsCollectionService.ts b/src/client/pythonEnvironments/base/locators/composite/envsCollectionService.ts index 1c62bd6adee2..70d4e9674d02 100644 --- a/src/client/pythonEnvironments/base/locators/composite/envsCollectionService.ts +++ b/src/client/pythonEnvironments/base/locators/composite/envsCollectionService.ts @@ -3,6 +3,7 @@ import { Event, EventEmitter, workspace } from 'vscode'; import '../../../../common/extensions'; +import * as fsPath from 'path'; import { createDeferred, Deferred } from '../../../../common/utils/async'; import { StopWatch } from '../../../../common/utils/stopWatch'; import { traceError, traceInfo, traceVerbose } from '../../../../logging'; @@ -28,6 +29,7 @@ import { createNativeGlobalPythonFinder, NativeEnvInfo } from '../common/nativeP import { pathExists } from '../../../../common/platform/fs-paths'; import { noop } from '../../../../common/utils/misc'; import { parseVersion } from '../../info/pythonVersion'; +import { Conda } from '../../../common/environmentManagers/conda'; /** * A service which maintains the collection of known environments. @@ -304,6 +306,12 @@ export class EnvsCollectionService extends PythonEnvsWatcher this.nativeFinder.categoryToKind(e.kind) === PythonEnvKind.Conda) + .forEach((e) => { + if (e.prefix && envsDirs.some((d) => e.prefix && e.prefix.startsWith(d))) { + missingEnvironments.nativeCondaEnvsInEnvDir += 1; + } + }); + } catch (ex) { + canSpawnConda = false; + } + const prefixesSeenAlready = new Set(); await Promise.all( envs.map(async (env) => { try { @@ -332,9 +365,16 @@ export class EnvsCollectionService extends PythonEnvsWatcher env.executable.sysPrefix.startsWith(d)) + ) { + missingEnvironments.condaEnvsInEnvDir += 1; + } missingEnvironments.missingNativeCondaEnvs += 1; break; case PythonEnvKind.Custom: @@ -419,7 +465,7 @@ export class EnvsCollectionService extends PythonEnvsWatcher getEnvPath(e.executable.filename, e.location).pathType === 'envFolderPath', ).length; const activeStateEnvs = envs.filter((e) => e.kind === PythonEnvKind.ActiveState).length; - const condaEnvs = envs.filter((e) => e.kind === PythonEnvKind.Conda).length; + const condaEnvs = envs.filter((e) => e.kind === PythonEnvKind.Conda); const customEnvs = envs.filter((e) => e.kind === PythonEnvKind.Custom).length; const hatchEnvs = envs.filter((e) => e.kind === PythonEnvKind.Hatch).length; const microsoftStoreEnvs = envs.filter((e) => e.kind === PythonEnvKind.MicrosoftStore).length; @@ -441,6 +487,22 @@ export class EnvsCollectionService extends PythonEnvsWatcher !e.executable.sysPrefix).length; + + await Promise.all( + condaEnvs.map(async (e) => { + if (e.executable.sysPrefix) { + const metadataFolder = fsPath.join(e.executable.sysPrefix, 'conda-meta'); + if (!(await pathExists(metadataFolder))) { + missingEnvironments.invalidCondaEnvs += 1; + } + } + }), + ); + missingEnvironments.invalidCondaEnvs = envs + .filter((e) => e.kind === PythonEnvKind.Conda) + .filter((e) => e.executable.sysPrefix && e.executable.sysPrefix).length; + const nativeEnvironmentsWithoutPython = nativeEnvs.filter((e) => e.executable === undefined).length; const nativeCondaEnvs = nativeEnvs.filter( (e) => this.nativeFinder.categoryToKind(e.kind) === PythonEnvKind.Conda, @@ -493,9 +555,12 @@ export class EnvsCollectionService extends PythonEnvsWatcher