From fbb33ecb6144ec9d607274fe75356582d398ac27 Mon Sep 17 00:00:00 2001 From: Kartik Raj Date: Fri, 16 Jul 2021 13:00:23 -0700 Subject: [PATCH 01/19] Move conda.ts --- .../common/process/pythonEnvironment.ts | 2 +- .../common/process/pythonExecutionFactory.ts | 2 +- src/client/interpreter/contracts.ts | 2 +- .../base/locators/composite/resolverUtils.ts | 2 +- .../pythonEnvironments/common/commonUtils.ts | 2 +- .../common/environmentIdentifier.ts | 2 +- .../environmentManagers}/conda.ts | 24 +++++++++---------- .../locators/services/condaEnvFileService.ts | 2 +- .../locators/services/condaEnvService.ts | 2 +- .../locators/services/condaLocator.ts | 2 +- .../locators/services/condaLocatorService.ts | 2 +- .../locators/services/condaService.ts | 2 +- .../services/windowsRegistryService.ts | 2 +- src/client/pythonEnvironments/legacyIOC.ts | 2 +- .../installer/condaInstaller.unit.test.ts | 2 +- .../composite/resolverUtils.unit.test.ts | 2 +- .../locators/condaEnvFileService.unit.test.ts | 2 +- .../locators/condaEnvService.unit.test.ts | 2 +- .../locators/condaHelper.unit.test.ts | 2 +- .../locators/condaLocator.unit.test.ts | 2 +- 20 files changed, 31 insertions(+), 31 deletions(-) rename src/client/pythonEnvironments/{discovery/locators/services => common/environmentManagers}/conda.ts (95%) diff --git a/src/client/common/process/pythonEnvironment.ts b/src/client/common/process/pythonEnvironment.ts index a039c3eca12e..a100f1c55351 100644 --- a/src/client/common/process/pythonEnvironment.ts +++ b/src/client/common/process/pythonEnvironment.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -import { CondaEnvironmentInfo } from '../../pythonEnvironments/discovery/locators/services/conda'; +import { CondaEnvironmentInfo } from '../../pythonEnvironments/common/environmentManagers/conda'; import { buildPythonExecInfo, PythonExecInfo } from '../../pythonEnvironments/exec'; import { InterpreterInformation } from '../../pythonEnvironments/info'; import { getExecutablePath } from '../../pythonEnvironments/info/executable'; diff --git a/src/client/common/process/pythonExecutionFactory.ts b/src/client/common/process/pythonExecutionFactory.ts index f78a736ed1f5..a3c74891ef59 100644 --- a/src/client/common/process/pythonExecutionFactory.ts +++ b/src/client/common/process/pythonExecutionFactory.ts @@ -7,7 +7,7 @@ import { Uri } from 'vscode'; import { IEnvironmentActivationService } from '../../interpreter/activation/types'; import { IComponentAdapter, ICondaLocatorService, ICondaService } from '../../interpreter/contracts'; import { IServiceContainer } from '../../ioc/types'; -import { CondaEnvironmentInfo } from '../../pythonEnvironments/discovery/locators/services/conda'; +import { CondaEnvironmentInfo } from '../../pythonEnvironments/common/environmentManagers/conda'; import { inDiscoveryExperiment } from '../experiments/helpers'; import { sendTelemetryEvent } from '../../telemetry'; import { EventName } from '../../telemetry/constants'; diff --git a/src/client/interpreter/contracts.ts b/src/client/interpreter/contracts.ts index dd21e0d20deb..09571a0a21db 100644 --- a/src/client/interpreter/contracts.ts +++ b/src/client/interpreter/contracts.ts @@ -3,7 +3,7 @@ import { CodeLensProvider, ConfigurationTarget, Disposable, Event, TextDocument, import { IExtensionSingleActivationService } from '../activation/types'; import { Resource } from '../common/types'; import { PythonEnvSource } from '../pythonEnvironments/base/info'; -import { CondaEnvironmentInfo, CondaInfo } from '../pythonEnvironments/discovery/locators/services/conda'; +import { CondaEnvironmentInfo, CondaInfo } from '../pythonEnvironments/common/environmentManagers/conda'; import { EnvironmentType, PythonEnvironment } from '../pythonEnvironments/info'; export const INTERPRETER_LOCATOR_SERVICE = 'IInterpreterLocatorService'; diff --git a/src/client/pythonEnvironments/base/locators/composite/resolverUtils.ts b/src/client/pythonEnvironments/base/locators/composite/resolverUtils.ts index c7b11b3f7b58..e9d059e62150 100644 --- a/src/client/pythonEnvironments/base/locators/composite/resolverUtils.ts +++ b/src/client/pythonEnvironments/base/locators/composite/resolverUtils.ts @@ -13,7 +13,7 @@ import { getPythonVersionFromPath, } from '../../../common/commonUtils'; import { getFileInfo, getWorkspaceFolders, isParentPath } from '../../../common/externalDependencies'; -import { AnacondaCompanyName, Conda } from '../../../discovery/locators/services/conda'; +import { AnacondaCompanyName, Conda } from '../../../common/environmentManagers/conda'; import { parsePyenvVersion } from '../../../discovery/locators/services/pyenvLocator'; import { Architecture, getOSType, OSType } from '../../../../common/utils/platform'; import { getPythonVersionFromPath as parsePythonVersionFromPath, parseVersion } from '../../info/pythonVersion'; diff --git a/src/client/pythonEnvironments/common/commonUtils.ts b/src/client/pythonEnvironments/common/commonUtils.ts index 22c81f825a90..ccb00e2c7d33 100644 --- a/src/client/pythonEnvironments/common/commonUtils.ts +++ b/src/client/pythonEnvironments/common/commonUtils.ts @@ -9,7 +9,7 @@ import { logError } from '../../logging'; import { PythonVersion, UNKNOWN_PYTHON_VERSION } from '../base/info'; import { comparePythonVersionSpecificity } from '../base/info/env'; import { parseVersion } from '../base/info/pythonVersion'; -import { getPythonVersionFromConda } from '../discovery/locators/services/conda'; +import { getPythonVersionFromConda } from './environmentManagers/conda'; import { getPythonVersionFromPyvenvCfg } from '../discovery/locators/services/virtualEnvironmentIdentifier'; import * as posix from './posixUtils'; import * as windows from './windowsUtils'; diff --git a/src/client/pythonEnvironments/common/environmentIdentifier.ts b/src/client/pythonEnvironments/common/environmentIdentifier.ts index 03756ee09c7e..a26efe9e3c5c 100644 --- a/src/client/pythonEnvironments/common/environmentIdentifier.ts +++ b/src/client/pythonEnvironments/common/environmentIdentifier.ts @@ -3,7 +3,7 @@ import { PythonEnvKind } from '../base/info'; import { getPrioritizedEnvKinds } from '../base/info/envKind'; -import { isCondaEnvironment } from '../discovery/locators/services/conda'; +import { isCondaEnvironment } from './environmentManagers/conda'; import { isPipenvEnvironment } from '../discovery/locators/services/pipEnvHelper'; import { isPoetryEnvironment } from '../discovery/locators/services/poetry'; import { isPyenvEnvironment } from '../discovery/locators/services/pyenvLocator'; diff --git a/src/client/pythonEnvironments/discovery/locators/services/conda.ts b/src/client/pythonEnvironments/common/environmentManagers/conda.ts similarity index 95% rename from src/client/pythonEnvironments/discovery/locators/services/conda.ts rename to src/client/pythonEnvironments/common/environmentManagers/conda.ts index f058f8cb6674..1eb577ee1b1f 100644 --- a/src/client/pythonEnvironments/discovery/locators/services/conda.ts +++ b/src/client/pythonEnvironments/common/environmentManagers/conda.ts @@ -1,17 +1,17 @@ import * as fsapi from 'fs-extra'; import * as path from 'path'; -import { traceVerbose } from '../../../../common/logger'; -import { getEnvironmentVariable, getOSType, getUserHomeDir, OSType } from '../../../../common/utils/platform'; -import { exec, pathExists, readFile } from '../../../common/externalDependencies'; - -import { PythonVersion, UNKNOWN_PYTHON_VERSION } from '../../../base/info'; -import { parseVersion } from '../../../base/info/pythonVersion'; - -import { getRegistryInterpreters } from '../../../common/windowsUtils'; -import { EnvironmentType, PythonEnvironment } from '../../../info'; -import { IDisposable } from '../../../../common/types'; -import { cache } from '../../../../common/utils/decorators'; -import { isTestExecution } from '../../../../common/constants'; +import { traceVerbose } from '../../../common/logger'; +import { getEnvironmentVariable, getOSType, getUserHomeDir, OSType } from '../../../common/utils/platform'; +import { exec, pathExists, readFile } from '../externalDependencies'; + +import { PythonVersion, UNKNOWN_PYTHON_VERSION } from '../../base/info'; +import { parseVersion } from '../../base/info/pythonVersion'; + +import { getRegistryInterpreters } from '../windowsUtils'; +import { EnvironmentType, PythonEnvironment } from '../../info'; +import { IDisposable } from '../../../common/types'; +import { cache } from '../../../common/utils/decorators'; +import { isTestExecution } from '../../../common/constants'; export const AnacondaCompanyName = 'Anaconda, Inc.'; diff --git a/src/client/pythonEnvironments/discovery/locators/services/condaEnvFileService.ts b/src/client/pythonEnvironments/discovery/locators/services/condaEnvFileService.ts index 3d0678f169c0..83825d58af71 100644 --- a/src/client/pythonEnvironments/discovery/locators/services/condaEnvFileService.ts +++ b/src/client/pythonEnvironments/discovery/locators/services/condaEnvFileService.ts @@ -17,7 +17,7 @@ import { ICondaLocatorService, IInterpreterHelper } from '../../../../interprete import { IServiceContainer } from '../../../../ioc/types'; import { EnvironmentType, PythonEnvironment } from '../../../info'; import { CacheableLocatorService } from './cacheableLocatorService'; -import { AnacondaCompanyName } from './conda'; +import { AnacondaCompanyName } from '../../../common/environmentManagers/conda'; /** * Locate conda env interpreters based on the "conda environments file". diff --git a/src/client/pythonEnvironments/discovery/locators/services/condaEnvService.ts b/src/client/pythonEnvironments/discovery/locators/services/condaEnvService.ts index eb1f128c3fa9..d9de871996c2 100644 --- a/src/client/pythonEnvironments/discovery/locators/services/condaEnvService.ts +++ b/src/client/pythonEnvironments/discovery/locators/services/condaEnvService.ts @@ -9,7 +9,7 @@ import { ICondaLocatorService, IInterpreterHelper } from '../../../../interprete import { IServiceContainer } from '../../../../ioc/types'; import { PythonEnvironment } from '../../../info'; import { CacheableLocatorService } from './cacheableLocatorService'; -import { parseCondaInfo } from './conda'; +import { parseCondaInfo } from '../../../common/environmentManagers/conda'; /** * Locates conda env interpreters based on the conda service's info. diff --git a/src/client/pythonEnvironments/discovery/locators/services/condaLocator.ts b/src/client/pythonEnvironments/discovery/locators/services/condaLocator.ts index bbaba7f618dd..7d5b11b87740 100644 --- a/src/client/pythonEnvironments/discovery/locators/services/condaLocator.ts +++ b/src/client/pythonEnvironments/discovery/locators/services/condaLocator.ts @@ -4,7 +4,7 @@ import '../../../../common/extensions'; import { PythonEnvKind } from '../../../base/info'; import { BasicEnvInfo, IPythonEnvsIterator, Locator } from '../../../base/locator'; import { getInterpreterPathFromDir } from '../../../common/commonUtils'; -import { Conda } from './conda'; +import { Conda } from '../../../common/environmentManagers/conda'; import { traceError, traceVerbose } from '../../../../common/logger'; export class CondaEnvironmentLocator extends Locator { diff --git a/src/client/pythonEnvironments/discovery/locators/services/condaLocatorService.ts b/src/client/pythonEnvironments/discovery/locators/services/condaLocatorService.ts index 83c6c8e18731..0283e0fffb70 100644 --- a/src/client/pythonEnvironments/discovery/locators/services/condaLocatorService.ts +++ b/src/client/pythonEnvironments/discovery/locators/services/condaLocatorService.ts @@ -26,7 +26,7 @@ import { import { IServiceContainer } from '../../../../ioc/types'; import { compareSemVerLikeVersions } from '../../../base/info/pythonVersion'; import { EnvironmentType, PythonEnvironment } from '../../../info'; -import { CondaEnvironmentInfo, CondaInfo } from './conda'; +import { CondaEnvironmentInfo, CondaInfo } from '../../../common/environmentManagers/conda'; import { parseCondaEnvFileContents } from './condaHelper'; const untildify: (value: string) => string = require('untildify'); diff --git a/src/client/pythonEnvironments/discovery/locators/services/condaService.ts b/src/client/pythonEnvironments/discovery/locators/services/condaService.ts index 097ecddcecd6..82551230809c 100644 --- a/src/client/pythonEnvironments/discovery/locators/services/condaService.ts +++ b/src/client/pythonEnvironments/discovery/locators/services/condaService.ts @@ -11,7 +11,7 @@ import { IExperimentService, IConfigurationService, IDisposableRegistry } from ' import { cache } from '../../../../common/utils/decorators'; import { ICondaService, ICondaLocatorService } from '../../../../interpreter/contracts'; import { IServiceContainer } from '../../../../ioc/types'; -import { Conda, CondaInfo } from './conda'; +import { Conda, CondaInfo } from '../../../common/environmentManagers/conda'; /** * A wrapper around a conda installation. diff --git a/src/client/pythonEnvironments/discovery/locators/services/windowsRegistryService.ts b/src/client/pythonEnvironments/discovery/locators/services/windowsRegistryService.ts index fbfa112772f0..8f9c622a4fae 100644 --- a/src/client/pythonEnvironments/discovery/locators/services/windowsRegistryService.ts +++ b/src/client/pythonEnvironments/discovery/locators/services/windowsRegistryService.ts @@ -9,7 +9,7 @@ import { IServiceContainer } from '../../../../ioc/types'; import { EnvironmentType, PythonEnvironment } from '../../../info'; import { parsePythonVersion } from '../../../info/pythonVersion'; import { CacheableLocatorService } from './cacheableLocatorService'; -import { AnacondaCompanyName } from './conda'; +import { AnacondaCompanyName } from '../../../common/environmentManagers/conda'; import { isWindowsStoreInterpreter, isRestrictedWindowsStoreInterpreterPath } from './windowsStoreInterpreter'; const flatten = require('lodash/flatten'); diff --git a/src/client/pythonEnvironments/legacyIOC.ts b/src/client/pythonEnvironments/legacyIOC.ts index 828de589c238..8406d42957e7 100644 --- a/src/client/pythonEnvironments/legacyIOC.ts +++ b/src/client/pythonEnvironments/legacyIOC.ts @@ -42,7 +42,7 @@ import { inExperiment, isParentPath } from './common/externalDependencies'; import { PythonInterpreterLocatorService } from './discovery/locators'; import { InterpreterLocatorHelper } from './discovery/locators/helpers'; import { InterpreterLocatorProgressService } from './discovery/locators/progressService'; -import { CondaEnvironmentInfo, isCondaEnvironment } from './discovery/locators/services/conda'; +import { CondaEnvironmentInfo, isCondaEnvironment } from './common/environmentManagers/conda'; import { CondaEnvFileService } from './discovery/locators/services/condaEnvFileService'; import { CondaEnvService } from './discovery/locators/services/condaEnvService'; import { CondaService } from './discovery/locators/services/condaService'; diff --git a/src/test/common/installer/condaInstaller.unit.test.ts b/src/test/common/installer/condaInstaller.unit.test.ts index 3fe9c83dbdae..f322031f81e1 100644 --- a/src/test/common/installer/condaInstaller.unit.test.ts +++ b/src/test/common/installer/condaInstaller.unit.test.ts @@ -20,7 +20,7 @@ import { import { ICondaService, ICondaLocatorService } from '../../../client/interpreter/contracts'; import { ServiceContainer } from '../../../client/ioc/container'; import { IServiceContainer } from '../../../client/ioc/types'; -import { CondaEnvironmentInfo } from '../../../client/pythonEnvironments/discovery/locators/services/conda'; +import { CondaEnvironmentInfo } from '../../../client/pythonEnvironments/common/environmentManagers/conda'; import { CondaService } from '../../../client/pythonEnvironments/discovery/locators/services/condaService'; suite('Common - Conda Installer', () => { diff --git a/src/test/pythonEnvironments/base/locators/composite/resolverUtils.unit.test.ts b/src/test/pythonEnvironments/base/locators/composite/resolverUtils.unit.test.ts index 0abd1fa1a102..3ea5bb684265 100644 --- a/src/test/pythonEnvironments/base/locators/composite/resolverUtils.unit.test.ts +++ b/src/test/pythonEnvironments/base/locators/composite/resolverUtils.unit.test.ts @@ -23,7 +23,7 @@ import { Architecture } from '../../../../../client/common/utils/platform'; import { AnacondaCompanyName, CondaInfo, -} from '../../../../../client/pythonEnvironments/discovery/locators/services/conda'; +} from '../../../../../client/pythonEnvironments/common/environmentManagers/conda'; import { resolveBasicEnv } from '../../../../../client/pythonEnvironments/base/locators/composite/resolverUtils'; suite('Resolver Utils', () => { diff --git a/src/test/pythonEnvironments/discovery/locators/condaEnvFileService.unit.test.ts b/src/test/pythonEnvironments/discovery/locators/condaEnvFileService.unit.test.ts index 66b4f45ed829..edda32cf2c2f 100644 --- a/src/test/pythonEnvironments/discovery/locators/condaEnvFileService.unit.test.ts +++ b/src/test/pythonEnvironments/discovery/locators/condaEnvFileService.unit.test.ts @@ -10,7 +10,7 @@ import { IInterpreterLocatorService, } from '../../../../client/interpreter/contracts'; import { IServiceContainer } from '../../../../client/ioc/types'; -import { AnacondaCompanyName } from '../../../../client/pythonEnvironments/discovery/locators/services/conda'; +import { AnacondaCompanyName } from '../../../../client/pythonEnvironments/common/environmentManagers/conda'; import { CondaEnvFileService } from '../../../../client/pythonEnvironments/discovery/locators/services/condaEnvFileService'; import { EnvironmentType } from '../../../../client/pythonEnvironments/info'; import { MockState } from '../../../interpreters/mocks'; diff --git a/src/test/pythonEnvironments/discovery/locators/condaEnvService.unit.test.ts b/src/test/pythonEnvironments/discovery/locators/condaEnvService.unit.test.ts index 4ef17d920e91..4e530bed2aab 100644 --- a/src/test/pythonEnvironments/discovery/locators/condaEnvService.unit.test.ts +++ b/src/test/pythonEnvironments/discovery/locators/condaEnvService.unit.test.ts @@ -10,7 +10,7 @@ import { AnacondaCompanyName, CondaInfo, parseCondaInfo, -} from '../../../../client/pythonEnvironments/discovery/locators/services/conda'; +} from '../../../../client/pythonEnvironments/common/environmentManagers/conda'; import { CondaEnvService } from '../../../../client/pythonEnvironments/discovery/locators/services/condaEnvService'; import { EnvironmentType } from '../../../../client/pythonEnvironments/info'; import { MockState } from '../../../interpreters/mocks'; diff --git a/src/test/pythonEnvironments/discovery/locators/condaHelper.unit.test.ts b/src/test/pythonEnvironments/discovery/locators/condaHelper.unit.test.ts index 4862192e369d..a3a1f5167480 100644 --- a/src/test/pythonEnvironments/discovery/locators/condaHelper.unit.test.ts +++ b/src/test/pythonEnvironments/discovery/locators/condaHelper.unit.test.ts @@ -9,7 +9,7 @@ import { PythonEnvKind } from '../../../../client/pythonEnvironments/base/info'; import { getEnvs } from '../../../../client/pythonEnvironments/base/locatorUtils'; import * as externalDependencies from '../../../../client/pythonEnvironments/common/externalDependencies'; import * as windowsUtils from '../../../../client/pythonEnvironments/common/windowsUtils'; -import { Conda, CondaInfo } from '../../../../client/pythonEnvironments/discovery/locators/services/conda'; +import { Conda, CondaInfo } from '../../../../client/pythonEnvironments/common/environmentManagers/conda'; import { parseCondaEnvFileContents } from '../../../../client/pythonEnvironments/discovery/locators/services/condaHelper'; import { CondaEnvironmentLocator } from '../../../../client/pythonEnvironments/discovery/locators/services/condaLocator'; import { createBasicEnv } from '../../base/common'; diff --git a/src/test/pythonEnvironments/discovery/locators/condaLocator.unit.test.ts b/src/test/pythonEnvironments/discovery/locators/condaLocator.unit.test.ts index 9f720a865490..6de60391a186 100644 --- a/src/test/pythonEnvironments/discovery/locators/condaLocator.unit.test.ts +++ b/src/test/pythonEnvironments/discovery/locators/condaLocator.unit.test.ts @@ -6,7 +6,7 @@ import * as path from 'path'; import * as sinon from 'sinon'; import { PythonReleaseLevel, PythonVersion } from '../../../../client/pythonEnvironments/base/info'; import * as externalDeps from '../../../../client/pythonEnvironments/common/externalDependencies'; -import { getPythonVersionFromConda } from '../../../../client/pythonEnvironments/discovery/locators/services/conda'; +import { getPythonVersionFromConda } from '../../../../client/pythonEnvironments/common/environmentManagers/conda'; import { TEST_DATA_ROOT } from '../../common/commonTestConstants'; import { assertVersionsEqual } from './envTestUtils'; From f67201e7ddf315db8ef14c8f07c102336b6d1a41 Mon Sep 17 00:00:00 2001 From: Kartik Raj Date: Fri, 16 Jul 2021 13:14:30 -0700 Subject: [PATCH 02/19] Move poetry.ts Rename Fix poetry --- .../common/installer/poetryInstaller.ts | 2 +- .../common/environmentIdentifier.ts | 2 +- .../environmentManagers}/poetry.ts | 29 ++++++++----------- .../locators/services/poetryLocator.ts | 2 +- .../locators/lowLevel/poetry.unit.test.ts | 11 +------ .../locators/poetryLocator.unit.test.ts | 5 ---- 6 files changed, 16 insertions(+), 35 deletions(-) rename src/client/pythonEnvironments/{discovery/locators/services => common/environmentManagers}/poetry.ts (93%) diff --git a/src/client/common/installer/poetryInstaller.ts b/src/client/common/installer/poetryInstaller.ts index 33f65a21124c..8ae795b43fe2 100644 --- a/src/client/common/installer/poetryInstaller.ts +++ b/src/client/common/installer/poetryInstaller.ts @@ -8,7 +8,7 @@ import * as path from 'path'; import { Uri } from 'vscode'; import { IInterpreterService } from '../../interpreter/contracts'; import { IServiceContainer } from '../../ioc/types'; -import { isPoetryEnvironmentRelatedToFolder } from '../../pythonEnvironments/discovery/locators/services/poetry'; +import { isPoetryEnvironmentRelatedToFolder } from '../../pythonEnvironments/common/environmentManagers/poetry'; import { EnvironmentType, ModuleInstallerType } from '../../pythonEnvironments/info'; import { IWorkspaceService } from '../application/types'; import { inDiscoveryExperiment } from '../experiments/helpers'; diff --git a/src/client/pythonEnvironments/common/environmentIdentifier.ts b/src/client/pythonEnvironments/common/environmentIdentifier.ts index a26efe9e3c5c..0b39af95d8c2 100644 --- a/src/client/pythonEnvironments/common/environmentIdentifier.ts +++ b/src/client/pythonEnvironments/common/environmentIdentifier.ts @@ -5,7 +5,7 @@ import { PythonEnvKind } from '../base/info'; import { getPrioritizedEnvKinds } from '../base/info/envKind'; import { isCondaEnvironment } from './environmentManagers/conda'; import { isPipenvEnvironment } from '../discovery/locators/services/pipEnvHelper'; -import { isPoetryEnvironment } from '../discovery/locators/services/poetry'; +import { isPoetryEnvironment } from './environmentManagers/poetry'; import { isPyenvEnvironment } from '../discovery/locators/services/pyenvLocator'; import { isVenvEnvironment, diff --git a/src/client/pythonEnvironments/discovery/locators/services/poetry.ts b/src/client/pythonEnvironments/common/environmentManagers/poetry.ts similarity index 93% rename from src/client/pythonEnvironments/discovery/locators/services/poetry.ts rename to src/client/pythonEnvironments/common/environmentManagers/poetry.ts index 08d4fcd975d0..c197ce442bb8 100644 --- a/src/client/pythonEnvironments/discovery/locators/services/poetry.ts +++ b/src/client/pythonEnvironments/common/environmentManagers/poetry.ts @@ -4,19 +4,14 @@ 'use strict'; import * as path from 'path'; -import { traceError, traceVerbose } from '../../../../common/logger'; -import { getOSType, getUserHomeDir, OSType } from '../../../../common/utils/platform'; -import { - getPythonSetting, - isParentPath, - pathExistsSync, - readFileSync, - shellExecute, -} from '../../../common/externalDependencies'; -import { getEnvironmentDirFromPath } from '../../../common/commonUtils'; -import { isVirtualenvEnvironment } from './virtualEnvironmentIdentifier'; -import { StopWatch } from '../../../../common/utils/stopWatch'; -import { cache } from '../../../../common/utils/decorators'; +import { traceError, traceVerbose } from '../../../common/logger'; +import { getOSType, getUserHomeDir, OSType } from '../../../common/utils/platform'; +import { getPythonSetting, isParentPath, pathExistsSync, readFileSync, shellExecute } from '../externalDependencies'; +import { getEnvironmentDirFromPath } from '../commonUtils'; +import { isVirtualenvEnvironment } from '../../discovery/locators/services/virtualEnvironmentIdentifier'; +import { StopWatch } from '../../../common/utils/stopWatch'; +import { cache } from '../../../common/utils/decorators'; +import { isTestExecution } from '../../../common/constants'; /** * Global virtual env dir for a project is named as: @@ -96,7 +91,7 @@ export class Poetry { * Locating poetry binary can be expensive, since it potentially involves spawning or * trying to spawn processes; so we only do it once per session. */ - public static _poetryPromise: Map> = new Map< + private static poetryPromise: Map> = new Map< string, Promise >(); @@ -126,10 +121,10 @@ export class Poetry { return undefined; } traceVerbose(`Getting poetry for cwd ${cwd}`); - if (Poetry._poetryPromise.get(cwd) === undefined) { - Poetry._poetryPromise.set(cwd, Poetry.locate(cwd)); + if (Poetry.poetryPromise.get(cwd) === undefined || isTestExecution()) { + Poetry.poetryPromise.set(cwd, Poetry.locate(cwd)); } - return Poetry._poetryPromise.get(cwd); + return Poetry.poetryPromise.get(cwd); } private static async locate(cwd: string): Promise { diff --git a/src/client/pythonEnvironments/discovery/locators/services/poetryLocator.ts b/src/client/pythonEnvironments/discovery/locators/services/poetryLocator.ts index 3627357a9301..76f2f6d12b71 100644 --- a/src/client/pythonEnvironments/discovery/locators/services/poetryLocator.ts +++ b/src/client/pythonEnvironments/discovery/locators/services/poetryLocator.ts @@ -11,7 +11,7 @@ import { BasicEnvInfo, IPythonEnvsIterator } from '../../../base/locator'; import { FSWatchingLocator } from '../../../base/locators/lowLevel/fsWatchingLocator'; import { getInterpreterPathFromDir } from '../../../common/commonUtils'; import { pathExists } from '../../../common/externalDependencies'; -import { isPoetryEnvironment, localPoetryEnvDirName, Poetry } from './poetry'; +import { isPoetryEnvironment, localPoetryEnvDirName, Poetry } from '../../../common/environmentManagers/poetry'; import '../../../../common/extensions'; import { asyncFilter } from '../../../../common/utils/arrayUtils'; diff --git a/src/test/pythonEnvironments/discovery/locators/lowLevel/poetry.unit.test.ts b/src/test/pythonEnvironments/discovery/locators/lowLevel/poetry.unit.test.ts index 76d13d4ec908..49833dc80b01 100644 --- a/src/test/pythonEnvironments/discovery/locators/lowLevel/poetry.unit.test.ts +++ b/src/test/pythonEnvironments/discovery/locators/lowLevel/poetry.unit.test.ts @@ -10,7 +10,7 @@ import * as externalDependencies from '../../../../../client/pythonEnvironments/ import { isPoetryEnvironment, Poetry, -} from '../../../../../client/pythonEnvironments/discovery/locators/services/poetry'; +} from '../../../../../client/pythonEnvironments/common/environmentManagers/poetry'; import { TEST_LAYOUT_ROOT } from '../../../common/commonTestConstants'; const testPoetryDir = path.join(TEST_LAYOUT_ROOT, 'poetry'); @@ -22,10 +22,6 @@ suite('isPoetryEnvironment Tests', () => { let shellExecute: sinon.SinonStub; let getPythonSetting: sinon.SinonStub; - suiteTeardown(() => { - Poetry._poetryPromise = new Map(); - }); - suite('Global poetry environment', async () => { test('Return true if environment folder name matches global env pattern and environment is of virtual env type', async () => { const result = await isPoetryEnvironment( @@ -87,17 +83,12 @@ suite('Poetry binary is located correctly', async () => { let shellExecute: sinon.SinonStub; let getPythonSetting: sinon.SinonStub; - suiteSetup(() => { - Poetry._poetryPromise = new Map(); - }); - setup(() => { getPythonSetting = sinon.stub(externalDependencies, 'getPythonSetting'); shellExecute = sinon.stub(externalDependencies, 'shellExecute'); }); teardown(() => { - Poetry._poetryPromise = new Map(); sinon.restore(); }); diff --git a/src/test/pythonEnvironments/discovery/locators/poetryLocator.unit.test.ts b/src/test/pythonEnvironments/discovery/locators/poetryLocator.unit.test.ts index 70bcce072e53..7953e08ec256 100644 --- a/src/test/pythonEnvironments/discovery/locators/poetryLocator.unit.test.ts +++ b/src/test/pythonEnvironments/discovery/locators/poetryLocator.unit.test.ts @@ -11,7 +11,6 @@ import { PoetryLocator } from '../../../../client/pythonEnvironments/discovery/l import { TEST_LAYOUT_ROOT } from '../../common/commonTestConstants'; import { assertBasicEnvsEqual } from './envTestUtils'; import { ExecutionResult, ShellOptions } from '../../../../client/common/process/types'; -import { Poetry } from '../../../../client/pythonEnvironments/discovery/locators/services/poetry'; import { createBasicEnv } from '../../base/common'; suite('Poetry Locator', () => { @@ -21,10 +20,6 @@ suite('Poetry Locator', () => { const testPoetryDir = path.join(TEST_LAYOUT_ROOT, 'poetry'); let locator: PoetryLocator; - suiteTeardown(() => { - Poetry._poetryPromise = new Map(); - }); - suiteSetup(() => { getPythonSetting = sinon.stub(externalDependencies, 'getPythonSetting'); getPythonSetting.returns('poetry'); From 3756db8ddc5e149357cf8102cd6056d5202ffa94 Mon Sep 17 00:00:00 2001 From: Kartik Raj Date: Fri, 16 Jul 2021 13:27:47 -0700 Subject: [PATCH 03/19] Rename pipEnvHelper.ts to pipenv.ts --- .../common/installer/pipEnvInstaller.ts | 2 +- .../pipEnvActivationProvider.ts | 2 +- .../lowLevel/workspaceVirtualEnvLocator.ts | 2 +- .../common/environmentIdentifier.ts | 2 +- .../services/customVirtualEnvLocator.ts | 2 +- .../globalVirtualEnvronmentLocator.ts | 2 +- .../services/{pipEnvHelper.ts => pipenv.ts} | 306 +++++++++--------- .../installer/pipEnvInstaller.unit.test.ts | 2 +- .../locators/pipEnvHelper.functional.test.ts | 2 +- .../locators/pipEnvHelper.unit.test.ts | 2 +- 10 files changed, 162 insertions(+), 162 deletions(-) rename src/client/pythonEnvironments/discovery/locators/services/{pipEnvHelper.ts => pipenv.ts} (97%) diff --git a/src/client/common/installer/pipEnvInstaller.ts b/src/client/common/installer/pipEnvInstaller.ts index 32dc883c6d41..07f968d2fa5c 100644 --- a/src/client/common/installer/pipEnvInstaller.ts +++ b/src/client/common/installer/pipEnvInstaller.ts @@ -4,7 +4,7 @@ import { inject, injectable } from 'inversify'; import { IInterpreterLocatorService, IInterpreterService, PIPENV_SERVICE } from '../../interpreter/contracts'; import { IServiceContainer } from '../../ioc/types'; -import { isPipenvEnvironmentRelatedToFolder } from '../../pythonEnvironments/discovery/locators/services/pipEnvHelper'; +import { isPipenvEnvironmentRelatedToFolder } from '../../pythonEnvironments/discovery/locators/services/pipenv'; import { EnvironmentType, ModuleInstallerType } from '../../pythonEnvironments/info'; import { IWorkspaceService } from '../application/types'; import { inDiscoveryExperiment } from '../experiments/helpers'; diff --git a/src/client/common/terminal/environmentActivationProviders/pipEnvActivationProvider.ts b/src/client/common/terminal/environmentActivationProviders/pipEnvActivationProvider.ts index 49e60e109a03..9861c9ee9a40 100644 --- a/src/client/common/terminal/environmentActivationProviders/pipEnvActivationProvider.ts +++ b/src/client/common/terminal/environmentActivationProviders/pipEnvActivationProvider.ts @@ -7,7 +7,7 @@ import { inject, injectable, named } from 'inversify'; import { Uri } from 'vscode'; import '../../extensions'; import { IInterpreterService } from '../../../interpreter/contracts'; -import { isPipenvEnvironmentRelatedToFolder } from '../../../pythonEnvironments/discovery/locators/services/pipEnvHelper'; +import { isPipenvEnvironmentRelatedToFolder } from '../../../pythonEnvironments/discovery/locators/services/pipenv'; import { EnvironmentType } from '../../../pythonEnvironments/info'; import { IWorkspaceService } from '../../application/types'; import { inDiscoveryExperiment } from '../../experiments/helpers'; diff --git a/src/client/pythonEnvironments/base/locators/lowLevel/workspaceVirtualEnvLocator.ts b/src/client/pythonEnvironments/base/locators/lowLevel/workspaceVirtualEnvLocator.ts index 5403f281eec1..3ddd9d850219 100644 --- a/src/client/pythonEnvironments/base/locators/lowLevel/workspaceVirtualEnvLocator.ts +++ b/src/client/pythonEnvironments/base/locators/lowLevel/workspaceVirtualEnvLocator.ts @@ -6,7 +6,7 @@ import { traceVerbose } from '../../../../common/logger'; import { chain, iterable } from '../../../../common/utils/async'; import { findInterpretersInDir, looksLikeBasicVirtualPython } from '../../../common/commonUtils'; import { pathExists } from '../../../common/externalDependencies'; -import { isPipenvEnvironment } from '../../../discovery/locators/services/pipEnvHelper'; +import { isPipenvEnvironment } from '../../../discovery/locators/services/pipenv'; import { isVenvEnvironment, isVirtualenvEnvironment, diff --git a/src/client/pythonEnvironments/common/environmentIdentifier.ts b/src/client/pythonEnvironments/common/environmentIdentifier.ts index 0b39af95d8c2..6af32732792e 100644 --- a/src/client/pythonEnvironments/common/environmentIdentifier.ts +++ b/src/client/pythonEnvironments/common/environmentIdentifier.ts @@ -4,7 +4,7 @@ import { PythonEnvKind } from '../base/info'; import { getPrioritizedEnvKinds } from '../base/info/envKind'; import { isCondaEnvironment } from './environmentManagers/conda'; -import { isPipenvEnvironment } from '../discovery/locators/services/pipEnvHelper'; +import { isPipenvEnvironment } from '../discovery/locators/services/pipenv'; import { isPoetryEnvironment } from './environmentManagers/poetry'; import { isPyenvEnvironment } from '../discovery/locators/services/pyenvLocator'; import { diff --git a/src/client/pythonEnvironments/discovery/locators/services/customVirtualEnvLocator.ts b/src/client/pythonEnvironments/discovery/locators/services/customVirtualEnvLocator.ts index fcac7f87c404..ff75c719e604 100644 --- a/src/client/pythonEnvironments/discovery/locators/services/customVirtualEnvLocator.ts +++ b/src/client/pythonEnvironments/discovery/locators/services/customVirtualEnvLocator.ts @@ -16,7 +16,7 @@ import { pathExists, untildify, } from '../../../common/externalDependencies'; -import { isPipenvEnvironment } from './pipEnvHelper'; +import { isPipenvEnvironment } from './pipenv'; import { isVenvEnvironment, isVirtualenvEnvironment, diff --git a/src/client/pythonEnvironments/discovery/locators/services/globalVirtualEnvronmentLocator.ts b/src/client/pythonEnvironments/discovery/locators/services/globalVirtualEnvronmentLocator.ts index 9541cfcaf106..1e583b52160d 100644 --- a/src/client/pythonEnvironments/discovery/locators/services/globalVirtualEnvronmentLocator.ts +++ b/src/client/pythonEnvironments/discovery/locators/services/globalVirtualEnvronmentLocator.ts @@ -11,7 +11,7 @@ import { BasicEnvInfo, IPythonEnvsIterator } from '../../../base/locator'; import { FSWatchingLocator } from '../../../base/locators/lowLevel/fsWatchingLocator'; import { findInterpretersInDir, looksLikeBasicVirtualPython } from '../../../common/commonUtils'; import { pathExists, untildify } from '../../../common/externalDependencies'; -import { isPipenvEnvironment } from './pipEnvHelper'; +import { isPipenvEnvironment } from './pipenv'; import { isVenvEnvironment, isVirtualenvEnvironment, diff --git a/src/client/pythonEnvironments/discovery/locators/services/pipEnvHelper.ts b/src/client/pythonEnvironments/discovery/locators/services/pipenv.ts similarity index 97% rename from src/client/pythonEnvironments/discovery/locators/services/pipEnvHelper.ts rename to src/client/pythonEnvironments/discovery/locators/services/pipenv.ts index 91ac1c2dcc3a..e1cc3f9d15f7 100644 --- a/src/client/pythonEnvironments/discovery/locators/services/pipEnvHelper.ts +++ b/src/client/pythonEnvironments/discovery/locators/services/pipenv.ts @@ -1,153 +1,153 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -import * as path from 'path'; -import { traceError } from '../../../../common/logger'; -import { getEnvironmentVariable } from '../../../../common/utils/platform'; -import { arePathsSame, pathExists, readFile } from '../../../common/externalDependencies'; - -function getSearchHeight() { - // PIPENV_MAX_DEPTH tells pipenv the maximum number of directories to recursively search for - // a Pipfile, defaults to 3: https://pipenv.pypa.io/en/latest/advanced/#pipenv.environments.PIPENV_MAX_DEPTH - const maxDepthStr = getEnvironmentVariable('PIPENV_MAX_DEPTH'); - if (maxDepthStr === undefined) { - return 3; - } - const maxDepth = parseInt(maxDepthStr, 10); - // eslint-disable-next-line no-restricted-globals - if (isNaN(maxDepth)) { - traceError(`PIPENV_MAX_DEPTH is incorrectly set. Converting value '${maxDepthStr}' to number results in NaN`); - return 1; - } - return maxDepth; -} - -/** - * Returns the path to Pipfile associated with the provided directory. - * @param searchDir the directory to look into - * @param lookIntoParentDirectories set to true if we should also search for Pipfile in parent directory - */ -export async function _getAssociatedPipfile( - searchDir: string, - options: { lookIntoParentDirectories: boolean }, -): Promise { - const pipFileName = getEnvironmentVariable('PIPENV_PIPFILE') || 'Pipfile'; - let heightToSearch = options.lookIntoParentDirectories ? getSearchHeight() : 1; - while (heightToSearch > 0 && !arePathsSame(searchDir, path.dirname(searchDir))) { - const pipFile = path.join(searchDir, pipFileName); - if (await pathExists(pipFile)) { - return pipFile; - } - searchDir = path.dirname(searchDir); - heightToSearch -= 1; - } - return undefined; -} - -/** - * If interpreter path belongs to a pipenv environment which is located inside a project, return associated Pipfile, - * otherwise return `undefined`. - * @param interpreterPath Absolute path to any python interpreter. - */ -async function getPipfileIfLocal(interpreterPath: string): Promise { - // Local pipenv environments are created by setting PIPENV_VENV_IN_PROJECT to 1, which always names the environment - // folder '.venv': https://pipenv.pypa.io/en/latest/advanced/#pipenv.environments.PIPENV_VENV_IN_PROJECT - // This is the layout we wish to verify. - // project - // |__ Pipfile <--- check if Pipfile exists here - // |__ .venv <--- check if name of the folder is '.venv' - // |__ Scripts/bin - // |__ python <--- interpreterPath - const venvFolder = path.dirname(path.dirname(interpreterPath)); - if (path.basename(venvFolder) !== '.venv') { - return undefined; - } - const directoryWhereVenvResides = path.dirname(venvFolder); - return _getAssociatedPipfile(directoryWhereVenvResides, { lookIntoParentDirectories: false }); -} - -/** - * Returns the project directory for pipenv environments given the environment folder - * @param envFolder Path to the environment folder - */ -async function getProjectDir(envFolder: string): Promise { - // Global pipenv environments have a .project file with the absolute path to the project - // See https://github.com/pypa/pipenv/blob/v2018.6.25/CHANGELOG.rst#features--improvements - // This is the layout we expect - // - // |__ .project <--- check if .project exists here - // |__ Scripts/bin - // |__ python <--- interpreterPath - // We get the project by reading the .project file - const dotProjectFile = path.join(envFolder, '.project'); - if (!(await pathExists(dotProjectFile))) { - return undefined; - } - const projectDir = await readFile(dotProjectFile); - if (!(await pathExists(projectDir))) { - traceError( - `The .project file inside environment folder: ${envFolder} doesn't contain a valid path to the project`, - ); - return undefined; - } - return projectDir; -} - -/** - * If interpreter path belongs to a global pipenv environment, return associated Pipfile, otherwise return `undefined`. - * @param interpreterPath Absolute path to any python interpreter. - */ -async function getPipfileIfGlobal(interpreterPath: string): Promise { - const envFolder = path.dirname(path.dirname(interpreterPath)); - const projectDir = await getProjectDir(envFolder); - if (projectDir === undefined) { - return undefined; - } - - // This is the layout we expect to see. - // project - // |__ Pipfile <--- check if Pipfile exists here and return it - // The name of the project (directory where Pipfile resides) is used as a prefix in the environment folder - const envFolderName = path.basename(envFolder); - if (!envFolderName.startsWith(`${path.basename(projectDir)}-`)) { - return undefined; - } - - return _getAssociatedPipfile(projectDir, { lookIntoParentDirectories: false }); -} - -/** - * Checks if the given interpreter path belongs to a pipenv environment, by locating the Pipfile which was used to - * create the environment. - * @param interpreterPath: Absolute path to any python interpreter. - */ -export async function isPipenvEnvironment(interpreterPath: string): Promise { - if (await getPipfileIfLocal(interpreterPath)) { - return true; - } - if (await getPipfileIfGlobal(interpreterPath)) { - return true; - } - return false; -} - -/** - * Returns true if interpreter path belongs to a global pipenv environment which is associated with a particular folder, - * false otherwise. - * @param interpreterPath Absolute path to any python interpreter. - */ -export async function isPipenvEnvironmentRelatedToFolder(interpreterPath: string, folder: string): Promise { - const pipFileAssociatedWithEnvironment = await getPipfileIfGlobal(interpreterPath); - if (!pipFileAssociatedWithEnvironment) { - return false; - } - - // PIPENV_NO_INHERIT is used to tell pipenv not to look for Pipfile in parent directories - // https://pipenv.pypa.io/en/latest/advanced/#pipenv.environments.PIPENV_NO_INHERIT - const lookIntoParentDirectories = getEnvironmentVariable('PIPENV_NO_INHERIT') === undefined; - const pipFileAssociatedWithFolder = await _getAssociatedPipfile(folder, { lookIntoParentDirectories }); - if (!pipFileAssociatedWithFolder) { - return false; - } - return arePathsSame(pipFileAssociatedWithEnvironment, pipFileAssociatedWithFolder); -} +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +import * as path from 'path'; +import { traceError } from '../../../../common/logger'; +import { getEnvironmentVariable } from '../../../../common/utils/platform'; +import { arePathsSame, pathExists, readFile } from '../../../common/externalDependencies'; + +function getSearchHeight() { + // PIPENV_MAX_DEPTH tells pipenv the maximum number of directories to recursively search for + // a Pipfile, defaults to 3: https://pipenv.pypa.io/en/latest/advanced/#pipenv.environments.PIPENV_MAX_DEPTH + const maxDepthStr = getEnvironmentVariable('PIPENV_MAX_DEPTH'); + if (maxDepthStr === undefined) { + return 3; + } + const maxDepth = parseInt(maxDepthStr, 10); + // eslint-disable-next-line no-restricted-globals + if (isNaN(maxDepth)) { + traceError(`PIPENV_MAX_DEPTH is incorrectly set. Converting value '${maxDepthStr}' to number results in NaN`); + return 1; + } + return maxDepth; +} + +/** + * Returns the path to Pipfile associated with the provided directory. + * @param searchDir the directory to look into + * @param lookIntoParentDirectories set to true if we should also search for Pipfile in parent directory + */ +export async function _getAssociatedPipfile( + searchDir: string, + options: { lookIntoParentDirectories: boolean }, +): Promise { + const pipFileName = getEnvironmentVariable('PIPENV_PIPFILE') || 'Pipfile'; + let heightToSearch = options.lookIntoParentDirectories ? getSearchHeight() : 1; + while (heightToSearch > 0 && !arePathsSame(searchDir, path.dirname(searchDir))) { + const pipFile = path.join(searchDir, pipFileName); + if (await pathExists(pipFile)) { + return pipFile; + } + searchDir = path.dirname(searchDir); + heightToSearch -= 1; + } + return undefined; +} + +/** + * If interpreter path belongs to a pipenv environment which is located inside a project, return associated Pipfile, + * otherwise return `undefined`. + * @param interpreterPath Absolute path to any python interpreter. + */ +async function getPipfileIfLocal(interpreterPath: string): Promise { + // Local pipenv environments are created by setting PIPENV_VENV_IN_PROJECT to 1, which always names the environment + // folder '.venv': https://pipenv.pypa.io/en/latest/advanced/#pipenv.environments.PIPENV_VENV_IN_PROJECT + // This is the layout we wish to verify. + // project + // |__ Pipfile <--- check if Pipfile exists here + // |__ .venv <--- check if name of the folder is '.venv' + // |__ Scripts/bin + // |__ python <--- interpreterPath + const venvFolder = path.dirname(path.dirname(interpreterPath)); + if (path.basename(venvFolder) !== '.venv') { + return undefined; + } + const directoryWhereVenvResides = path.dirname(venvFolder); + return _getAssociatedPipfile(directoryWhereVenvResides, { lookIntoParentDirectories: false }); +} + +/** + * Returns the project directory for pipenv environments given the environment folder + * @param envFolder Path to the environment folder + */ +async function getProjectDir(envFolder: string): Promise { + // Global pipenv environments have a .project file with the absolute path to the project + // See https://github.com/pypa/pipenv/blob/v2018.6.25/CHANGELOG.rst#features--improvements + // This is the layout we expect + // + // |__ .project <--- check if .project exists here + // |__ Scripts/bin + // |__ python <--- interpreterPath + // We get the project by reading the .project file + const dotProjectFile = path.join(envFolder, '.project'); + if (!(await pathExists(dotProjectFile))) { + return undefined; + } + const projectDir = await readFile(dotProjectFile); + if (!(await pathExists(projectDir))) { + traceError( + `The .project file inside environment folder: ${envFolder} doesn't contain a valid path to the project`, + ); + return undefined; + } + return projectDir; +} + +/** + * If interpreter path belongs to a global pipenv environment, return associated Pipfile, otherwise return `undefined`. + * @param interpreterPath Absolute path to any python interpreter. + */ +async function getPipfileIfGlobal(interpreterPath: string): Promise { + const envFolder = path.dirname(path.dirname(interpreterPath)); + const projectDir = await getProjectDir(envFolder); + if (projectDir === undefined) { + return undefined; + } + + // This is the layout we expect to see. + // project + // |__ Pipfile <--- check if Pipfile exists here and return it + // The name of the project (directory where Pipfile resides) is used as a prefix in the environment folder + const envFolderName = path.basename(envFolder); + if (!envFolderName.startsWith(`${path.basename(projectDir)}-`)) { + return undefined; + } + + return _getAssociatedPipfile(projectDir, { lookIntoParentDirectories: false }); +} + +/** + * Checks if the given interpreter path belongs to a pipenv environment, by locating the Pipfile which was used to + * create the environment. + * @param interpreterPath: Absolute path to any python interpreter. + */ +export async function isPipenvEnvironment(interpreterPath: string): Promise { + if (await getPipfileIfLocal(interpreterPath)) { + return true; + } + if (await getPipfileIfGlobal(interpreterPath)) { + return true; + } + return false; +} + +/** + * Returns true if interpreter path belongs to a global pipenv environment which is associated with a particular folder, + * false otherwise. + * @param interpreterPath Absolute path to any python interpreter. + */ +export async function isPipenvEnvironmentRelatedToFolder(interpreterPath: string, folder: string): Promise { + const pipFileAssociatedWithEnvironment = await getPipfileIfGlobal(interpreterPath); + if (!pipFileAssociatedWithEnvironment) { + return false; + } + + // PIPENV_NO_INHERIT is used to tell pipenv not to look for Pipfile in parent directories + // https://pipenv.pypa.io/en/latest/advanced/#pipenv.environments.PIPENV_NO_INHERIT + const lookIntoParentDirectories = getEnvironmentVariable('PIPENV_NO_INHERIT') === undefined; + const pipFileAssociatedWithFolder = await _getAssociatedPipfile(folder, { lookIntoParentDirectories }); + if (!pipFileAssociatedWithFolder) { + return false; + } + return arePathsSame(pipFileAssociatedWithEnvironment, pipFileAssociatedWithFolder); +} diff --git a/src/test/common/installer/pipEnvInstaller.unit.test.ts b/src/test/common/installer/pipEnvInstaller.unit.test.ts index 7c35688f5148..b741a5c589e4 100644 --- a/src/test/common/installer/pipEnvInstaller.unit.test.ts +++ b/src/test/common/installer/pipEnvInstaller.unit.test.ts @@ -13,7 +13,7 @@ import { PipEnvInstaller } from '../../../client/common/installer/pipEnvInstalle import { IExperimentService } from '../../../client/common/types'; import { IInterpreterLocatorService, IInterpreterService, PIPENV_SERVICE } from '../../../client/interpreter/contracts'; import { IServiceContainer } from '../../../client/ioc/types'; -import * as pipEnvHelper from '../../../client/pythonEnvironments/discovery/locators/services/pipEnvHelper'; +import * as pipEnvHelper from '../../../client/pythonEnvironments/discovery/locators/services/pipenv'; import { EnvironmentType, PythonEnvironment } from '../../../client/pythonEnvironments/info'; suite('PipEnv installer', async () => { diff --git a/src/test/pythonEnvironments/discovery/locators/pipEnvHelper.functional.test.ts b/src/test/pythonEnvironments/discovery/locators/pipEnvHelper.functional.test.ts index ed5e8e657977..ab5de4b3adde 100644 --- a/src/test/pythonEnvironments/discovery/locators/pipEnvHelper.functional.test.ts +++ b/src/test/pythonEnvironments/discovery/locators/pipEnvHelper.functional.test.ts @@ -3,7 +3,7 @@ import * as path from 'path'; import * as sinon from 'sinon'; import * as platformApis from '../../../../client/common/utils/platform'; import * as externalDependencies from '../../../../client/pythonEnvironments/common/externalDependencies'; -import { isPipenvEnvironmentRelatedToFolder } from '../../../../client/pythonEnvironments/discovery/locators/services/pipEnvHelper'; +import { isPipenvEnvironmentRelatedToFolder } from '../../../../client/pythonEnvironments/discovery/locators/services/pipenv'; import { TEST_LAYOUT_ROOT } from '../../common/commonTestConstants'; suite('Pipenv utils', () => { diff --git a/src/test/pythonEnvironments/discovery/locators/pipEnvHelper.unit.test.ts b/src/test/pythonEnvironments/discovery/locators/pipEnvHelper.unit.test.ts index 1b75e598fc47..83ee3e00ba81 100644 --- a/src/test/pythonEnvironments/discovery/locators/pipEnvHelper.unit.test.ts +++ b/src/test/pythonEnvironments/discovery/locators/pipEnvHelper.unit.test.ts @@ -7,7 +7,7 @@ import { _getAssociatedPipfile, isPipenvEnvironment, isPipenvEnvironmentRelatedToFolder, -} from '../../../../client/pythonEnvironments/discovery/locators/services/pipEnvHelper'; +} from '../../../../client/pythonEnvironments/discovery/locators/services/pipenv'; const path = platformApis.getOSType() === platformApis.OSType.Windows ? pathModule.win32 : pathModule.posix; From 60d2d83b944c0fe76cb58fd4abb5c89547273d55 Mon Sep 17 00:00:00 2001 From: Kartik Raj Date: Fri, 16 Jul 2021 13:28:48 -0700 Subject: [PATCH 04/19] Move pipenv.ts --- src/client/common/installer/pipEnvInstaller.ts | 2 +- .../pipEnvActivationProvider.ts | 2 +- .../base/locators/lowLevel/workspaceVirtualEnvLocator.ts | 2 +- .../pythonEnvironments/common/environmentIdentifier.ts | 2 +- .../services => common/environmentManagers}/pipenv.ts | 6 +++--- .../discovery/locators/services/customVirtualEnvLocator.ts | 2 +- .../locators/services/globalVirtualEnvronmentLocator.ts | 2 +- src/test/common/installer/pipEnvInstaller.unit.test.ts | 2 +- .../discovery/locators/pipEnvHelper.functional.test.ts | 2 +- .../discovery/locators/pipEnvHelper.unit.test.ts | 2 +- 10 files changed, 12 insertions(+), 12 deletions(-) rename src/client/pythonEnvironments/{discovery/locators/services => common/environmentManagers}/pipenv.ts (96%) diff --git a/src/client/common/installer/pipEnvInstaller.ts b/src/client/common/installer/pipEnvInstaller.ts index 07f968d2fa5c..432171769b17 100644 --- a/src/client/common/installer/pipEnvInstaller.ts +++ b/src/client/common/installer/pipEnvInstaller.ts @@ -4,7 +4,7 @@ import { inject, injectable } from 'inversify'; import { IInterpreterLocatorService, IInterpreterService, PIPENV_SERVICE } from '../../interpreter/contracts'; import { IServiceContainer } from '../../ioc/types'; -import { isPipenvEnvironmentRelatedToFolder } from '../../pythonEnvironments/discovery/locators/services/pipenv'; +import { isPipenvEnvironmentRelatedToFolder } from '../../pythonEnvironments/common/environmentManagers/pipenv'; import { EnvironmentType, ModuleInstallerType } from '../../pythonEnvironments/info'; import { IWorkspaceService } from '../application/types'; import { inDiscoveryExperiment } from '../experiments/helpers'; diff --git a/src/client/common/terminal/environmentActivationProviders/pipEnvActivationProvider.ts b/src/client/common/terminal/environmentActivationProviders/pipEnvActivationProvider.ts index 9861c9ee9a40..de0e76fd6d42 100644 --- a/src/client/common/terminal/environmentActivationProviders/pipEnvActivationProvider.ts +++ b/src/client/common/terminal/environmentActivationProviders/pipEnvActivationProvider.ts @@ -7,7 +7,7 @@ import { inject, injectable, named } from 'inversify'; import { Uri } from 'vscode'; import '../../extensions'; import { IInterpreterService } from '../../../interpreter/contracts'; -import { isPipenvEnvironmentRelatedToFolder } from '../../../pythonEnvironments/discovery/locators/services/pipenv'; +import { isPipenvEnvironmentRelatedToFolder } from '../../../pythonEnvironments/common/environmentManagers/pipenv'; import { EnvironmentType } from '../../../pythonEnvironments/info'; import { IWorkspaceService } from '../../application/types'; import { inDiscoveryExperiment } from '../../experiments/helpers'; diff --git a/src/client/pythonEnvironments/base/locators/lowLevel/workspaceVirtualEnvLocator.ts b/src/client/pythonEnvironments/base/locators/lowLevel/workspaceVirtualEnvLocator.ts index 3ddd9d850219..fbfa8ad12032 100644 --- a/src/client/pythonEnvironments/base/locators/lowLevel/workspaceVirtualEnvLocator.ts +++ b/src/client/pythonEnvironments/base/locators/lowLevel/workspaceVirtualEnvLocator.ts @@ -6,7 +6,7 @@ import { traceVerbose } from '../../../../common/logger'; import { chain, iterable } from '../../../../common/utils/async'; import { findInterpretersInDir, looksLikeBasicVirtualPython } from '../../../common/commonUtils'; import { pathExists } from '../../../common/externalDependencies'; -import { isPipenvEnvironment } from '../../../discovery/locators/services/pipenv'; +import { isPipenvEnvironment } from '../../../common/environmentManagers/pipenv'; import { isVenvEnvironment, isVirtualenvEnvironment, diff --git a/src/client/pythonEnvironments/common/environmentIdentifier.ts b/src/client/pythonEnvironments/common/environmentIdentifier.ts index 6af32732792e..37fd18f3587b 100644 --- a/src/client/pythonEnvironments/common/environmentIdentifier.ts +++ b/src/client/pythonEnvironments/common/environmentIdentifier.ts @@ -4,7 +4,7 @@ import { PythonEnvKind } from '../base/info'; import { getPrioritizedEnvKinds } from '../base/info/envKind'; import { isCondaEnvironment } from './environmentManagers/conda'; -import { isPipenvEnvironment } from '../discovery/locators/services/pipenv'; +import { isPipenvEnvironment } from './environmentManagers/pipenv'; import { isPoetryEnvironment } from './environmentManagers/poetry'; import { isPyenvEnvironment } from '../discovery/locators/services/pyenvLocator'; import { diff --git a/src/client/pythonEnvironments/discovery/locators/services/pipenv.ts b/src/client/pythonEnvironments/common/environmentManagers/pipenv.ts similarity index 96% rename from src/client/pythonEnvironments/discovery/locators/services/pipenv.ts rename to src/client/pythonEnvironments/common/environmentManagers/pipenv.ts index e1cc3f9d15f7..b17f99d6efa0 100644 --- a/src/client/pythonEnvironments/discovery/locators/services/pipenv.ts +++ b/src/client/pythonEnvironments/common/environmentManagers/pipenv.ts @@ -2,9 +2,9 @@ // Licensed under the MIT License. import * as path from 'path'; -import { traceError } from '../../../../common/logger'; -import { getEnvironmentVariable } from '../../../../common/utils/platform'; -import { arePathsSame, pathExists, readFile } from '../../../common/externalDependencies'; +import { traceError } from '../../../common/logger'; +import { getEnvironmentVariable } from '../../../common/utils/platform'; +import { arePathsSame, pathExists, readFile } from '../externalDependencies'; function getSearchHeight() { // PIPENV_MAX_DEPTH tells pipenv the maximum number of directories to recursively search for diff --git a/src/client/pythonEnvironments/discovery/locators/services/customVirtualEnvLocator.ts b/src/client/pythonEnvironments/discovery/locators/services/customVirtualEnvLocator.ts index ff75c719e604..9cf459f60640 100644 --- a/src/client/pythonEnvironments/discovery/locators/services/customVirtualEnvLocator.ts +++ b/src/client/pythonEnvironments/discovery/locators/services/customVirtualEnvLocator.ts @@ -16,7 +16,7 @@ import { pathExists, untildify, } from '../../../common/externalDependencies'; -import { isPipenvEnvironment } from './pipenv'; +import { isPipenvEnvironment } from '../../../common/environmentManagers/pipenv'; import { isVenvEnvironment, isVirtualenvEnvironment, diff --git a/src/client/pythonEnvironments/discovery/locators/services/globalVirtualEnvronmentLocator.ts b/src/client/pythonEnvironments/discovery/locators/services/globalVirtualEnvronmentLocator.ts index 1e583b52160d..b3d6f2946d3e 100644 --- a/src/client/pythonEnvironments/discovery/locators/services/globalVirtualEnvronmentLocator.ts +++ b/src/client/pythonEnvironments/discovery/locators/services/globalVirtualEnvronmentLocator.ts @@ -11,7 +11,7 @@ import { BasicEnvInfo, IPythonEnvsIterator } from '../../../base/locator'; import { FSWatchingLocator } from '../../../base/locators/lowLevel/fsWatchingLocator'; import { findInterpretersInDir, looksLikeBasicVirtualPython } from '../../../common/commonUtils'; import { pathExists, untildify } from '../../../common/externalDependencies'; -import { isPipenvEnvironment } from './pipenv'; +import { isPipenvEnvironment } from '../../../common/environmentManagers/pipenv'; import { isVenvEnvironment, isVirtualenvEnvironment, diff --git a/src/test/common/installer/pipEnvInstaller.unit.test.ts b/src/test/common/installer/pipEnvInstaller.unit.test.ts index b741a5c589e4..c1858e2a2ee1 100644 --- a/src/test/common/installer/pipEnvInstaller.unit.test.ts +++ b/src/test/common/installer/pipEnvInstaller.unit.test.ts @@ -13,7 +13,7 @@ import { PipEnvInstaller } from '../../../client/common/installer/pipEnvInstalle import { IExperimentService } from '../../../client/common/types'; import { IInterpreterLocatorService, IInterpreterService, PIPENV_SERVICE } from '../../../client/interpreter/contracts'; import { IServiceContainer } from '../../../client/ioc/types'; -import * as pipEnvHelper from '../../../client/pythonEnvironments/discovery/locators/services/pipenv'; +import * as pipEnvHelper from '../../../client/pythonEnvironments/common/environmentManagers/pipenv'; import { EnvironmentType, PythonEnvironment } from '../../../client/pythonEnvironments/info'; suite('PipEnv installer', async () => { diff --git a/src/test/pythonEnvironments/discovery/locators/pipEnvHelper.functional.test.ts b/src/test/pythonEnvironments/discovery/locators/pipEnvHelper.functional.test.ts index ab5de4b3adde..8b20291d5376 100644 --- a/src/test/pythonEnvironments/discovery/locators/pipEnvHelper.functional.test.ts +++ b/src/test/pythonEnvironments/discovery/locators/pipEnvHelper.functional.test.ts @@ -3,7 +3,7 @@ import * as path from 'path'; import * as sinon from 'sinon'; import * as platformApis from '../../../../client/common/utils/platform'; import * as externalDependencies from '../../../../client/pythonEnvironments/common/externalDependencies'; -import { isPipenvEnvironmentRelatedToFolder } from '../../../../client/pythonEnvironments/discovery/locators/services/pipenv'; +import { isPipenvEnvironmentRelatedToFolder } from '../../../../client/pythonEnvironments/common/environmentManagers/pipenv'; import { TEST_LAYOUT_ROOT } from '../../common/commonTestConstants'; suite('Pipenv utils', () => { diff --git a/src/test/pythonEnvironments/discovery/locators/pipEnvHelper.unit.test.ts b/src/test/pythonEnvironments/discovery/locators/pipEnvHelper.unit.test.ts index 83ee3e00ba81..45291625be13 100644 --- a/src/test/pythonEnvironments/discovery/locators/pipEnvHelper.unit.test.ts +++ b/src/test/pythonEnvironments/discovery/locators/pipEnvHelper.unit.test.ts @@ -7,7 +7,7 @@ import { _getAssociatedPipfile, isPipenvEnvironment, isPipenvEnvironmentRelatedToFolder, -} from '../../../../client/pythonEnvironments/discovery/locators/services/pipenv'; +} from '../../../../client/pythonEnvironments/common/environmentManagers/pipenv'; const path = platformApis.getOSType() === platformApis.OSType.Windows ? pathModule.win32 : pathModule.posix; From 309a2fb3813d6b9ac4569c57f192de71246f1049 Mon Sep 17 00:00:00 2001 From: Kartik Raj Date: Fri, 16 Jul 2021 13:54:16 -0700 Subject: [PATCH 05/19] Refactor pyenv domain knowledge out of the locator --- .../base/locators/composite/resolverUtils.ts | 2 +- .../lowLevel/windowsKnownPathsLocator.ts | 2 +- .../common/environmentIdentifier.ts | 2 +- .../services/posixKnownPathsLocator.ts | 2 +- .../discovery/locators/services/pyenv.ts | 237 +++++++++++++++++ .../locators/services/pyenvLocator.ts | 239 +----------------- .../locators/pyenvLocator.unit.test.ts | 2 +- 7 files changed, 244 insertions(+), 242 deletions(-) create mode 100644 src/client/pythonEnvironments/discovery/locators/services/pyenv.ts diff --git a/src/client/pythonEnvironments/base/locators/composite/resolverUtils.ts b/src/client/pythonEnvironments/base/locators/composite/resolverUtils.ts index e9d059e62150..211af3ff74d7 100644 --- a/src/client/pythonEnvironments/base/locators/composite/resolverUtils.ts +++ b/src/client/pythonEnvironments/base/locators/composite/resolverUtils.ts @@ -14,7 +14,7 @@ import { } from '../../../common/commonUtils'; import { getFileInfo, getWorkspaceFolders, isParentPath } from '../../../common/externalDependencies'; import { AnacondaCompanyName, Conda } from '../../../common/environmentManagers/conda'; -import { parsePyenvVersion } from '../../../discovery/locators/services/pyenvLocator'; +import { parsePyenvVersion } from '../../../discovery/locators/services/pyenv'; import { Architecture, getOSType, OSType } from '../../../../common/utils/platform'; import { getPythonVersionFromPath as parsePythonVersionFromPath, parseVersion } from '../../info/pythonVersion'; import { getRegistryInterpreters, getRegistryInterpretersSync } from '../../../common/windowsUtils'; diff --git a/src/client/pythonEnvironments/base/locators/lowLevel/windowsKnownPathsLocator.ts b/src/client/pythonEnvironments/base/locators/lowLevel/windowsKnownPathsLocator.ts index d7764e361d24..9fa9de1d70d4 100644 --- a/src/client/pythonEnvironments/base/locators/lowLevel/windowsKnownPathsLocator.ts +++ b/src/client/pythonEnvironments/base/locators/lowLevel/windowsKnownPathsLocator.ts @@ -8,7 +8,7 @@ import { Event } from 'vscode'; import { getSearchPathEntries } from '../../../../common/utils/exec'; import { Disposables, IDisposable } from '../../../../common/utils/resourceLifecycle'; import { iterPythonExecutablesInDir, looksLikeBasicGlobalPython } from '../../../common/commonUtils'; -import { isPyenvShimDir } from '../../../discovery/locators/services/pyenvLocator'; +import { isPyenvShimDir } from '../../../discovery/locators/services/pyenv'; import { isWindowsStoreDir } from '../../../discovery/locators/services/windowsStoreLocator'; import { PythonEnvKind, PythonEnvSource } from '../../info'; import { BasicEnvInfo, ILocator, IPythonEnvsIterator, PythonLocatorQuery } from '../../locator'; diff --git a/src/client/pythonEnvironments/common/environmentIdentifier.ts b/src/client/pythonEnvironments/common/environmentIdentifier.ts index 37fd18f3587b..0d1dd68c01d8 100644 --- a/src/client/pythonEnvironments/common/environmentIdentifier.ts +++ b/src/client/pythonEnvironments/common/environmentIdentifier.ts @@ -6,7 +6,7 @@ import { getPrioritizedEnvKinds } from '../base/info/envKind'; import { isCondaEnvironment } from './environmentManagers/conda'; import { isPipenvEnvironment } from './environmentManagers/pipenv'; import { isPoetryEnvironment } from './environmentManagers/poetry'; -import { isPyenvEnvironment } from '../discovery/locators/services/pyenvLocator'; +import { isPyenvEnvironment } from '../discovery/locators/services/pyenv'; import { isVenvEnvironment, isVirtualenvEnvironment as isVirtualEnvEnvironment, diff --git a/src/client/pythonEnvironments/discovery/locators/services/posixKnownPathsLocator.ts b/src/client/pythonEnvironments/discovery/locators/services/posixKnownPathsLocator.ts index 2f37de628a3b..5b084254032f 100644 --- a/src/client/pythonEnvironments/discovery/locators/services/posixKnownPathsLocator.ts +++ b/src/client/pythonEnvironments/discovery/locators/services/posixKnownPathsLocator.ts @@ -5,7 +5,7 @@ import { traceError } from '../../../../common/logger'; import { PythonEnvKind, PythonEnvSource } from '../../../base/info'; import { BasicEnvInfo, IPythonEnvsIterator, Locator } from '../../../base/locator'; import { commonPosixBinPaths, getPythonBinFromPosixPaths } from '../../../common/posixUtils'; -import { isPyenvShimDir } from './pyenvLocator'; +import { isPyenvShimDir } from './pyenv'; export class PosixKnownPathsLocator extends Locator { private kind: PythonEnvKind = PythonEnvKind.OtherGlobal; diff --git a/src/client/pythonEnvironments/discovery/locators/services/pyenv.ts b/src/client/pythonEnvironments/discovery/locators/services/pyenv.ts new file mode 100644 index 000000000000..681d1f6d6a85 --- /dev/null +++ b/src/client/pythonEnvironments/discovery/locators/services/pyenv.ts @@ -0,0 +1,237 @@ +import * as path from 'path'; +import { getEnvironmentVariable, getOSType, getUserHomeDir, OSType } from '../../../../common/utils/platform'; +import { arePathsSame, pathExists } from '../../../common/externalDependencies'; + +export function getPyenvDir(): string { + // Check if the pyenv environment variables exist: PYENV on Windows, PYENV_ROOT on Unix. + // They contain the path to pyenv's installation folder. + // If they don't exist, use the default path: ~/.pyenv/pyenv-win on Windows, ~/.pyenv on Unix. + // If the interpreter path starts with the path to the pyenv folder, then it is a pyenv environment. + // See https://github.com/pyenv/pyenv#locating-the-python-installation for general usage, + // And https://github.com/pyenv-win/pyenv-win for Windows specifics. + let pyenvDir = getEnvironmentVariable('PYENV_ROOT') ?? getEnvironmentVariable('PYENV'); + + if (!pyenvDir) { + const homeDir = getUserHomeDir() || ''; + pyenvDir = + getOSType() === OSType.Windows ? path.join(homeDir, '.pyenv', 'pyenv-win') : path.join(homeDir, '.pyenv'); + } + + return pyenvDir; +} +/** + * Checks if a given directory path is same as `pyenv` shims path. This checks + * `~/.pyenv/shims` on posix and `~/.pyenv/pyenv-win/shims` on windows. + * @param {string} dirPath: Absolute path to any directory + * @returns {boolean}: Returns true if the patch is same as `pyenv` shims directory. + */ + +export function isPyenvShimDir(dirPath: string): boolean { + const shimPath = path.join(getPyenvDir(), 'shims'); + return arePathsSame(shimPath, dirPath) || arePathsSame(`${shimPath}${path.sep}`, dirPath); +} +/** + * Checks if the given interpreter belongs to a pyenv based environment. + * @param {string} interpreterPath: Absolute path to the python interpreter. + * @returns {boolean}: Returns true if the interpreter belongs to a pyenv environment. + */ + +export async function isPyenvEnvironment(interpreterPath: string): Promise { + let pathToCheck = interpreterPath; + let pyenvDir = getPyenvDir(); + + if (!(await pathExists(pyenvDir))) { + return false; + } + + if (!pyenvDir.endsWith(path.sep)) { + pyenvDir += path.sep; + } + + if (getOSType() === OSType.Windows) { + pyenvDir = pyenvDir.toUpperCase(); + pathToCheck = pathToCheck.toUpperCase(); + } + + return pathToCheck.startsWith(pyenvDir); +} + +export interface IPyenvVersionStrings { + pythonVer?: string; + distro?: string; + distroVer?: string; +} +/** + * This function provides parsers for some of the common and known distributions + * supported by pyenv. To get the list of supported pyenv distributions, run + * `pyenv install --list` + * + * The parsers below were written based on the list obtained from pyenv version 1.2.21 + */ +function getKnownPyenvVersionParsers(): Map Promise> { + /** + * This function parses versions that are plain python versions. + * @param str string to parse + * + * Parses : + * 2.7.18 + * 3.9.0 + */ + function pythonOnly(str: string): Promise { + return Promise.resolve({ + pythonVer: str, + distro: undefined, + distroVer: undefined, + }); + } + + /** + * This function parses versions that are distro versions. + * @param str string to parse + * + * Examples: + * miniconda3-4.7.12 + * anaconda3-2020.07 + */ + function distroOnly(str: string): Promise { + const parts = str.split('-'); + if (parts.length === 3) { + return Promise.resolve({ + pythonVer: undefined, + distroVer: `${parts[1]}-${parts[2]}`, + distro: parts[0], + }); + } + + if (parts.length === 2) { + return Promise.resolve({ + pythonVer: undefined, + distroVer: parts[1], + distro: parts[0], + }); + } + + return Promise.resolve({ + pythonVer: undefined, + distroVer: undefined, + distro: str, + }); + } + + /** + * This function parser pypy environments supported by the pyenv install command + * @param str string to parse + * + * Examples: + * pypy-c-jit-latest + * pypy-c-nojit-latest + * pypy-dev + * pypy-stm-2.3 + * pypy-stm-2.5.1 + * pypy-1.5-src + * pypy-1.5 + * pypy3.5-5.7.1-beta-src + * pypy3.5-5.7.1-beta + * pypy3.5-5.8.0-src + * pypy3.5-5.8.0 + */ + function pypyParser(str: string): Promise { + const pattern = /[0-9\.]+/; + + const parts = str.split('-'); + const pythonVer = parts[0].search(pattern) > 0 ? parts[0].substr('pypy'.length) : undefined; + if (parts.length === 2) { + return Promise.resolve({ + pythonVer, + distroVer: parts[1], + distro: 'pypy', + }); + } + + if ( + parts.length === 3 && + (parts[2].startsWith('src') || + parts[2].startsWith('beta') || + parts[2].startsWith('alpha') || + parts[2].startsWith('win64')) + ) { + const part1 = parts[1].startsWith('v') ? parts[1].substr(1) : parts[1]; + return Promise.resolve({ + pythonVer, + distroVer: `${part1}-${parts[2]}`, + distro: 'pypy', + }); + } + + if (parts.length === 3 && parts[1] === 'stm') { + return Promise.resolve({ + pythonVer, + distroVer: parts[2], + distro: `${parts[0]}-${parts[1]}`, + }); + } + + if (parts.length === 4 && parts[1] === 'c') { + return Promise.resolve({ + pythonVer, + distroVer: parts[3], + distro: `pypy-${parts[1]}-${parts[2]}`, + }); + } + + if (parts.length === 4 && parts[3].startsWith('src')) { + return Promise.resolve({ + pythonVer, + distroVer: `${parts[1]}-${parts[2]}-${parts[3]}`, + distro: 'pypy', + }); + } + + return Promise.resolve({ + pythonVer, + distroVer: undefined, + distro: 'pypy', + }); + } + + const parsers: Map Promise> = new Map(); + parsers.set('activepython', distroOnly); + parsers.set('anaconda', distroOnly); + parsers.set('graalpython', distroOnly); + parsers.set('ironpython', distroOnly); + parsers.set('jython', distroOnly); + parsers.set('micropython', distroOnly); + parsers.set('miniconda', distroOnly); + parsers.set('miniforge', distroOnly); + parsers.set('pypy', pypyParser); + parsers.set('pyston', distroOnly); + parsers.set('stackless', distroOnly); + parsers.set('3', pythonOnly); + parsers.set('2', pythonOnly); + + return parsers; +} +/** + * This function parses the name of the commonly installed versions of pyenv based environments. + * @param str string to parse. + * + * Remarks: Depending on the environment, the name itself can contain distribution info like + * name and version. Sometimes it may also have python version as a part of the name. This function + * extracts the various strings. + */ + +export function parsePyenvVersion(str: string): Promise { + const allParsers = getKnownPyenvVersionParsers(); + const knownPrefixes = Array.from(allParsers.keys()); + + const parsers = knownPrefixes + .filter((k) => str.startsWith(k)) + .map((p) => allParsers.get(p)) + .filter((p) => p !== undefined); + + if (parsers.length > 0 && parsers[0]) { + return parsers[0](str); + } + + return Promise.resolve(undefined); +} diff --git a/src/client/pythonEnvironments/discovery/locators/services/pyenvLocator.ts b/src/client/pythonEnvironments/discovery/locators/services/pyenvLocator.ts index 188a067859f2..0a082d7a7cfb 100644 --- a/src/client/pythonEnvironments/discovery/locators/services/pyenvLocator.ts +++ b/src/client/pythonEnvironments/discovery/locators/services/pyenvLocator.ts @@ -3,252 +3,17 @@ import * as path from 'path'; import { traceError } from '../../../../common/logger'; -import { getEnvironmentVariable, getOSType, getUserHomeDir, OSType } from '../../../../common/utils/platform'; import { PythonEnvKind } from '../../../base/info'; import { BasicEnvInfo, IPythonEnvsIterator } from '../../../base/locator'; import { FSWatchingLocator } from '../../../base/locators/lowLevel/fsWatchingLocator'; import { getInterpreterPathFromDir } from '../../../common/commonUtils'; -import { arePathsSame, getSubDirs, pathExists } from '../../../common/externalDependencies'; - -function getPyenvDir(): string { - // Check if the pyenv environment variables exist: PYENV on Windows, PYENV_ROOT on Unix. - // They contain the path to pyenv's installation folder. - // If they don't exist, use the default path: ~/.pyenv/pyenv-win on Windows, ~/.pyenv on Unix. - // If the interpreter path starts with the path to the pyenv folder, then it is a pyenv environment. - // See https://github.com/pyenv/pyenv#locating-the-python-installation for general usage, - // And https://github.com/pyenv-win/pyenv-win for Windows specifics. - let pyenvDir = getEnvironmentVariable('PYENV_ROOT') ?? getEnvironmentVariable('PYENV'); - - if (!pyenvDir) { - const homeDir = getUserHomeDir() || ''; - pyenvDir = - getOSType() === OSType.Windows ? path.join(homeDir, '.pyenv', 'pyenv-win') : path.join(homeDir, '.pyenv'); - } - - return pyenvDir; -} +import { getSubDirs } from '../../../common/externalDependencies'; +import { getPyenvDir } from './pyenv'; function getPyenvVersionsDir(): string { return path.join(getPyenvDir(), 'versions'); } -/** - * Checks if a given directory path is same as `pyenv` shims path. This checks - * `~/.pyenv/shims` on posix and `~/.pyenv/pyenv-win/shims` on windows. - * @param {string} dirPath: Absolute path to any directory - * @returns {boolean}: Returns true if the patch is same as `pyenv` shims directory. - */ -export function isPyenvShimDir(dirPath: string): boolean { - const shimPath = path.join(getPyenvDir(), 'shims'); - return arePathsSame(shimPath, dirPath) || arePathsSame(`${shimPath}${path.sep}`, dirPath); -} - -/** - * Checks if the given interpreter belongs to a pyenv based environment. - * @param {string} interpreterPath: Absolute path to the python interpreter. - * @returns {boolean}: Returns true if the interpreter belongs to a pyenv environment. - */ -export async function isPyenvEnvironment(interpreterPath: string): Promise { - let pathToCheck = interpreterPath; - let pyenvDir = getPyenvDir(); - - if (!(await pathExists(pyenvDir))) { - return false; - } - - if (!pyenvDir.endsWith(path.sep)) { - pyenvDir += path.sep; - } - - if (getOSType() === OSType.Windows) { - pyenvDir = pyenvDir.toUpperCase(); - pathToCheck = pathToCheck.toUpperCase(); - } - - return pathToCheck.startsWith(pyenvDir); -} - -export interface IPyenvVersionStrings { - pythonVer?: string; - distro?: string; - distroVer?: string; -} - -/** - * This function provides parsers for some of the common and known distributions - * supported by pyenv. To get the list of supported pyenv distributions, run - * `pyenv install --list` - * - * The parsers below were written based on the list obtained from pyenv version 1.2.21 - */ -function getKnownPyenvVersionParsers(): Map Promise> { - /** - * This function parses versions that are plain python versions. - * @param str string to parse - * - * Parses : - * 2.7.18 - * 3.9.0 - */ - function pythonOnly(str: string): Promise { - return Promise.resolve({ - pythonVer: str, - distro: undefined, - distroVer: undefined, - }); - } - - /** - * This function parses versions that are distro versions. - * @param str string to parse - * - * Examples: - * miniconda3-4.7.12 - * anaconda3-2020.07 - */ - function distroOnly(str: string): Promise { - const parts = str.split('-'); - if (parts.length === 3) { - return Promise.resolve({ - pythonVer: undefined, - distroVer: `${parts[1]}-${parts[2]}`, - distro: parts[0], - }); - } - - if (parts.length === 2) { - return Promise.resolve({ - pythonVer: undefined, - distroVer: parts[1], - distro: parts[0], - }); - } - - return Promise.resolve({ - pythonVer: undefined, - distroVer: undefined, - distro: str, - }); - } - - /** - * This function parser pypy environments supported by the pyenv install command - * @param str string to parse - * - * Examples: - * pypy-c-jit-latest - * pypy-c-nojit-latest - * pypy-dev - * pypy-stm-2.3 - * pypy-stm-2.5.1 - * pypy-1.5-src - * pypy-1.5 - * pypy3.5-5.7.1-beta-src - * pypy3.5-5.7.1-beta - * pypy3.5-5.8.0-src - * pypy3.5-5.8.0 - */ - function pypyParser(str: string): Promise { - const pattern = /[0-9\.]+/; - - const parts = str.split('-'); - const pythonVer = parts[0].search(pattern) > 0 ? parts[0].substr('pypy'.length) : undefined; - if (parts.length === 2) { - return Promise.resolve({ - pythonVer, - distroVer: parts[1], - distro: 'pypy', - }); - } - - if ( - parts.length === 3 && - (parts[2].startsWith('src') || - parts[2].startsWith('beta') || - parts[2].startsWith('alpha') || - parts[2].startsWith('win64')) - ) { - const part1 = parts[1].startsWith('v') ? parts[1].substr(1) : parts[1]; - return Promise.resolve({ - pythonVer, - distroVer: `${part1}-${parts[2]}`, - distro: 'pypy', - }); - } - - if (parts.length === 3 && parts[1] === 'stm') { - return Promise.resolve({ - pythonVer, - distroVer: parts[2], - distro: `${parts[0]}-${parts[1]}`, - }); - } - - if (parts.length === 4 && parts[1] === 'c') { - return Promise.resolve({ - pythonVer, - distroVer: parts[3], - distro: `pypy-${parts[1]}-${parts[2]}`, - }); - } - - if (parts.length === 4 && parts[3].startsWith('src')) { - return Promise.resolve({ - pythonVer, - distroVer: `${parts[1]}-${parts[2]}-${parts[3]}`, - distro: 'pypy', - }); - } - - return Promise.resolve({ - pythonVer, - distroVer: undefined, - distro: 'pypy', - }); - } - - const parsers: Map Promise> = new Map(); - parsers.set('activepython', distroOnly); - parsers.set('anaconda', distroOnly); - parsers.set('graalpython', distroOnly); - parsers.set('ironpython', distroOnly); - parsers.set('jython', distroOnly); - parsers.set('micropython', distroOnly); - parsers.set('miniconda', distroOnly); - parsers.set('miniforge', distroOnly); - parsers.set('pypy', pypyParser); - parsers.set('pyston', distroOnly); - parsers.set('stackless', distroOnly); - parsers.set('3', pythonOnly); - parsers.set('2', pythonOnly); - - return parsers; -} - -/** - * This function parses the name of the commonly installed versions of pyenv based environments. - * @param str string to parse. - * - * Remarks: Depending on the environment, the name itself can contain distribution info like - * name and version. Sometimes it may also have python version as a part of the name. This function - * extracts the various strings. - */ -export function parsePyenvVersion(str: string): Promise { - const allParsers = getKnownPyenvVersionParsers(); - const knownPrefixes = Array.from(allParsers.keys()); - - const parsers = knownPrefixes - .filter((k) => str.startsWith(k)) - .map((p) => allParsers.get(p)) - .filter((p) => p !== undefined); - - if (parsers.length > 0 && parsers[0]) { - return parsers[0](str); - } - - return Promise.resolve(undefined); -} - /** * Gets all the pyenv environments. * diff --git a/src/test/pythonEnvironments/discovery/locators/pyenvLocator.unit.test.ts b/src/test/pythonEnvironments/discovery/locators/pyenvLocator.unit.test.ts index 6d2a06b1095d..9baa09ab8e0f 100644 --- a/src/test/pythonEnvironments/discovery/locators/pyenvLocator.unit.test.ts +++ b/src/test/pythonEnvironments/discovery/locators/pyenvLocator.unit.test.ts @@ -11,7 +11,7 @@ import { isPyenvEnvironment, isPyenvShimDir, parsePyenvVersion, -} from '../../../../client/pythonEnvironments/discovery/locators/services/pyenvLocator'; +} from '../../../../client/pythonEnvironments/discovery/locators/services/pyenv'; suite('Pyenv Identifier Tests', () => { const home = platformUtils.getUserHomeDir() || ''; From 7f54f4624f9a162d903abc99cc49062e2fea57ac Mon Sep 17 00:00:00 2001 From: Kartik Raj Date: Fri, 16 Jul 2021 13:55:15 -0700 Subject: [PATCH 06/19] Move pyenv.ts --- .../base/locators/composite/resolverUtils.ts | 2 +- .../base/locators/lowLevel/windowsKnownPathsLocator.ts | 2 +- src/client/pythonEnvironments/common/environmentIdentifier.ts | 2 +- .../locators/services => common/environmentManagers}/pyenv.ts | 4 ++-- .../discovery/locators/services/posixKnownPathsLocator.ts | 2 +- .../discovery/locators/services/pyenvLocator.ts | 2 +- .../discovery/locators/pyenvLocator.unit.test.ts | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) rename src/client/pythonEnvironments/{discovery/locators/services => common/environmentManagers}/pyenv.ts (98%) diff --git a/src/client/pythonEnvironments/base/locators/composite/resolverUtils.ts b/src/client/pythonEnvironments/base/locators/composite/resolverUtils.ts index 211af3ff74d7..69ca1f7c7003 100644 --- a/src/client/pythonEnvironments/base/locators/composite/resolverUtils.ts +++ b/src/client/pythonEnvironments/base/locators/composite/resolverUtils.ts @@ -14,7 +14,7 @@ import { } from '../../../common/commonUtils'; import { getFileInfo, getWorkspaceFolders, isParentPath } from '../../../common/externalDependencies'; import { AnacondaCompanyName, Conda } from '../../../common/environmentManagers/conda'; -import { parsePyenvVersion } from '../../../discovery/locators/services/pyenv'; +import { parsePyenvVersion } from '../../../common/environmentManagers/pyenv'; import { Architecture, getOSType, OSType } from '../../../../common/utils/platform'; import { getPythonVersionFromPath as parsePythonVersionFromPath, parseVersion } from '../../info/pythonVersion'; import { getRegistryInterpreters, getRegistryInterpretersSync } from '../../../common/windowsUtils'; diff --git a/src/client/pythonEnvironments/base/locators/lowLevel/windowsKnownPathsLocator.ts b/src/client/pythonEnvironments/base/locators/lowLevel/windowsKnownPathsLocator.ts index 9fa9de1d70d4..d1cb7073070c 100644 --- a/src/client/pythonEnvironments/base/locators/lowLevel/windowsKnownPathsLocator.ts +++ b/src/client/pythonEnvironments/base/locators/lowLevel/windowsKnownPathsLocator.ts @@ -8,7 +8,7 @@ import { Event } from 'vscode'; import { getSearchPathEntries } from '../../../../common/utils/exec'; import { Disposables, IDisposable } from '../../../../common/utils/resourceLifecycle'; import { iterPythonExecutablesInDir, looksLikeBasicGlobalPython } from '../../../common/commonUtils'; -import { isPyenvShimDir } from '../../../discovery/locators/services/pyenv'; +import { isPyenvShimDir } from '../../../common/environmentManagers/pyenv'; import { isWindowsStoreDir } from '../../../discovery/locators/services/windowsStoreLocator'; import { PythonEnvKind, PythonEnvSource } from '../../info'; import { BasicEnvInfo, ILocator, IPythonEnvsIterator, PythonLocatorQuery } from '../../locator'; diff --git a/src/client/pythonEnvironments/common/environmentIdentifier.ts b/src/client/pythonEnvironments/common/environmentIdentifier.ts index 0d1dd68c01d8..278f170fbd16 100644 --- a/src/client/pythonEnvironments/common/environmentIdentifier.ts +++ b/src/client/pythonEnvironments/common/environmentIdentifier.ts @@ -6,7 +6,7 @@ import { getPrioritizedEnvKinds } from '../base/info/envKind'; import { isCondaEnvironment } from './environmentManagers/conda'; import { isPipenvEnvironment } from './environmentManagers/pipenv'; import { isPoetryEnvironment } from './environmentManagers/poetry'; -import { isPyenvEnvironment } from '../discovery/locators/services/pyenv'; +import { isPyenvEnvironment } from './environmentManagers/pyenv'; import { isVenvEnvironment, isVirtualenvEnvironment as isVirtualEnvEnvironment, diff --git a/src/client/pythonEnvironments/discovery/locators/services/pyenv.ts b/src/client/pythonEnvironments/common/environmentManagers/pyenv.ts similarity index 98% rename from src/client/pythonEnvironments/discovery/locators/services/pyenv.ts rename to src/client/pythonEnvironments/common/environmentManagers/pyenv.ts index 681d1f6d6a85..52c219ff8535 100644 --- a/src/client/pythonEnvironments/discovery/locators/services/pyenv.ts +++ b/src/client/pythonEnvironments/common/environmentManagers/pyenv.ts @@ -1,6 +1,6 @@ import * as path from 'path'; -import { getEnvironmentVariable, getOSType, getUserHomeDir, OSType } from '../../../../common/utils/platform'; -import { arePathsSame, pathExists } from '../../../common/externalDependencies'; +import { getEnvironmentVariable, getOSType, getUserHomeDir, OSType } from '../../../common/utils/platform'; +import { arePathsSame, pathExists } from '../externalDependencies'; export function getPyenvDir(): string { // Check if the pyenv environment variables exist: PYENV on Windows, PYENV_ROOT on Unix. diff --git a/src/client/pythonEnvironments/discovery/locators/services/posixKnownPathsLocator.ts b/src/client/pythonEnvironments/discovery/locators/services/posixKnownPathsLocator.ts index 5b084254032f..cbc926e74d80 100644 --- a/src/client/pythonEnvironments/discovery/locators/services/posixKnownPathsLocator.ts +++ b/src/client/pythonEnvironments/discovery/locators/services/posixKnownPathsLocator.ts @@ -5,7 +5,7 @@ import { traceError } from '../../../../common/logger'; import { PythonEnvKind, PythonEnvSource } from '../../../base/info'; import { BasicEnvInfo, IPythonEnvsIterator, Locator } from '../../../base/locator'; import { commonPosixBinPaths, getPythonBinFromPosixPaths } from '../../../common/posixUtils'; -import { isPyenvShimDir } from './pyenv'; +import { isPyenvShimDir } from '../../../common/environmentManagers/pyenv'; export class PosixKnownPathsLocator extends Locator { private kind: PythonEnvKind = PythonEnvKind.OtherGlobal; diff --git a/src/client/pythonEnvironments/discovery/locators/services/pyenvLocator.ts b/src/client/pythonEnvironments/discovery/locators/services/pyenvLocator.ts index 0a082d7a7cfb..bfdab4260844 100644 --- a/src/client/pythonEnvironments/discovery/locators/services/pyenvLocator.ts +++ b/src/client/pythonEnvironments/discovery/locators/services/pyenvLocator.ts @@ -8,7 +8,7 @@ import { BasicEnvInfo, IPythonEnvsIterator } from '../../../base/locator'; import { FSWatchingLocator } from '../../../base/locators/lowLevel/fsWatchingLocator'; import { getInterpreterPathFromDir } from '../../../common/commonUtils'; import { getSubDirs } from '../../../common/externalDependencies'; -import { getPyenvDir } from './pyenv'; +import { getPyenvDir } from '../../../common/environmentManagers/pyenv'; function getPyenvVersionsDir(): string { return path.join(getPyenvDir(), 'versions'); diff --git a/src/test/pythonEnvironments/discovery/locators/pyenvLocator.unit.test.ts b/src/test/pythonEnvironments/discovery/locators/pyenvLocator.unit.test.ts index 9baa09ab8e0f..b89b0b4fe662 100644 --- a/src/test/pythonEnvironments/discovery/locators/pyenvLocator.unit.test.ts +++ b/src/test/pythonEnvironments/discovery/locators/pyenvLocator.unit.test.ts @@ -11,7 +11,7 @@ import { isPyenvEnvironment, isPyenvShimDir, parsePyenvVersion, -} from '../../../../client/pythonEnvironments/discovery/locators/services/pyenv'; +} from '../../../../client/pythonEnvironments/common/environmentManagers/pyenv'; suite('Pyenv Identifier Tests', () => { const home = platformUtils.getUserHomeDir() || ''; From 192a314c762d9b9dbabb777dcb0b8059594bc788 Mon Sep 17 00:00:00 2001 From: Kartik Raj Date: Fri, 16 Jul 2021 16:04:50 -0700 Subject: [PATCH 07/19] Move and rename virtualEnvironmentIdentifier.ts --- .../locators/lowLevel/workspaceVirtualEnvLocator.ts | 5 +---- src/client/pythonEnvironments/common/commonUtils.ts | 2 +- .../common/environmentIdentifier.ts | 2 +- .../common/environmentManagers/poetry.ts | 2 +- .../environmentManagers/simplevirtualenvs.ts} | 12 ++++++------ .../locators/services/customVirtualEnvLocator.ts | 2 +- .../services/globalVirtualEnvronmentLocator.ts | 2 +- .../virtualEnvironmentIdentifier.unit.test.ts | 2 +- 8 files changed, 13 insertions(+), 16 deletions(-) rename src/client/pythonEnvironments/{discovery/locators/services/virtualEnvironmentIdentifier.ts => common/environmentManagers/simplevirtualenvs.ts} (95%) diff --git a/src/client/pythonEnvironments/base/locators/lowLevel/workspaceVirtualEnvLocator.ts b/src/client/pythonEnvironments/base/locators/lowLevel/workspaceVirtualEnvLocator.ts index fbfa8ad12032..0b0e60dd94d0 100644 --- a/src/client/pythonEnvironments/base/locators/lowLevel/workspaceVirtualEnvLocator.ts +++ b/src/client/pythonEnvironments/base/locators/lowLevel/workspaceVirtualEnvLocator.ts @@ -7,10 +7,7 @@ import { chain, iterable } from '../../../../common/utils/async'; import { findInterpretersInDir, looksLikeBasicVirtualPython } from '../../../common/commonUtils'; import { pathExists } from '../../../common/externalDependencies'; import { isPipenvEnvironment } from '../../../common/environmentManagers/pipenv'; -import { - isVenvEnvironment, - isVirtualenvEnvironment, -} from '../../../discovery/locators/services/virtualEnvironmentIdentifier'; +import { isVenvEnvironment, isVirtualenvEnvironment } from '../../../common/environmentManagers/simplevirtualenvs'; import { PythonEnvKind } from '../../info'; import { BasicEnvInfo, IPythonEnvsIterator } from '../../locator'; import { FSWatchingLocator } from './fsWatchingLocator'; diff --git a/src/client/pythonEnvironments/common/commonUtils.ts b/src/client/pythonEnvironments/common/commonUtils.ts index ccb00e2c7d33..f6b5ae810542 100644 --- a/src/client/pythonEnvironments/common/commonUtils.ts +++ b/src/client/pythonEnvironments/common/commonUtils.ts @@ -10,7 +10,7 @@ import { PythonVersion, UNKNOWN_PYTHON_VERSION } from '../base/info'; import { comparePythonVersionSpecificity } from '../base/info/env'; import { parseVersion } from '../base/info/pythonVersion'; import { getPythonVersionFromConda } from './environmentManagers/conda'; -import { getPythonVersionFromPyvenvCfg } from '../discovery/locators/services/virtualEnvironmentIdentifier'; +import { getPythonVersionFromPyvenvCfg } from './environmentManagers/simplevirtualenvs'; import * as posix from './posixUtils'; import * as windows from './windowsUtils'; diff --git a/src/client/pythonEnvironments/common/environmentIdentifier.ts b/src/client/pythonEnvironments/common/environmentIdentifier.ts index 278f170fbd16..bff1eb56ee15 100644 --- a/src/client/pythonEnvironments/common/environmentIdentifier.ts +++ b/src/client/pythonEnvironments/common/environmentIdentifier.ts @@ -11,7 +11,7 @@ import { isVenvEnvironment, isVirtualenvEnvironment as isVirtualEnvEnvironment, isVirtualenvwrapperEnvironment as isVirtualEnvWrapperEnvironment, -} from '../discovery/locators/services/virtualEnvironmentIdentifier'; +} from './environmentManagers/simplevirtualenvs'; import { isWindowsStoreEnvironment } from '../discovery/locators/services/windowsStoreLocator'; function getIdentifiers(): Map Promise> { diff --git a/src/client/pythonEnvironments/common/environmentManagers/poetry.ts b/src/client/pythonEnvironments/common/environmentManagers/poetry.ts index c197ce442bb8..eb52c5b653d5 100644 --- a/src/client/pythonEnvironments/common/environmentManagers/poetry.ts +++ b/src/client/pythonEnvironments/common/environmentManagers/poetry.ts @@ -8,7 +8,7 @@ import { traceError, traceVerbose } from '../../../common/logger'; import { getOSType, getUserHomeDir, OSType } from '../../../common/utils/platform'; import { getPythonSetting, isParentPath, pathExistsSync, readFileSync, shellExecute } from '../externalDependencies'; import { getEnvironmentDirFromPath } from '../commonUtils'; -import { isVirtualenvEnvironment } from '../../discovery/locators/services/virtualEnvironmentIdentifier'; +import { isVirtualenvEnvironment } from './simplevirtualenvs'; import { StopWatch } from '../../../common/utils/stopWatch'; import { cache } from '../../../common/utils/decorators'; import { isTestExecution } from '../../../common/constants'; diff --git a/src/client/pythonEnvironments/discovery/locators/services/virtualEnvironmentIdentifier.ts b/src/client/pythonEnvironments/common/environmentManagers/simplevirtualenvs.ts similarity index 95% rename from src/client/pythonEnvironments/discovery/locators/services/virtualEnvironmentIdentifier.ts rename to src/client/pythonEnvironments/common/environmentManagers/simplevirtualenvs.ts index 37387e092d1b..824c540689ed 100644 --- a/src/client/pythonEnvironments/discovery/locators/services/virtualEnvironmentIdentifier.ts +++ b/src/client/pythonEnvironments/common/environmentManagers/simplevirtualenvs.ts @@ -3,12 +3,12 @@ import * as fsapi from 'fs-extra'; import * as path from 'path'; -import '../../../../common/extensions'; -import { getEnvironmentVariable, getOSType, getUserHomeDir, OSType } from '../../../../common/utils/platform'; -import { PythonVersion, UNKNOWN_PYTHON_VERSION } from '../../../base/info'; -import { comparePythonVersionSpecificity } from '../../../base/info/env'; -import { parseBasicVersion, parseRelease, parseVersion } from '../../../base/info/pythonVersion'; -import { pathExists, readFile } from '../../../common/externalDependencies'; +import '../../../common/extensions'; +import { getEnvironmentVariable, getOSType, getUserHomeDir, OSType } from '../../../common/utils/platform'; +import { PythonVersion, UNKNOWN_PYTHON_VERSION } from '../../base/info'; +import { comparePythonVersionSpecificity } from '../../base/info/env'; +import { parseBasicVersion, parseRelease, parseVersion } from '../../base/info/pythonVersion'; +import { pathExists, readFile } from '../externalDependencies'; function getPyvenvConfigPathsFrom(interpreterPath: string): string[] { const pyvenvConfigFile = 'pyvenv.cfg'; diff --git a/src/client/pythonEnvironments/discovery/locators/services/customVirtualEnvLocator.ts b/src/client/pythonEnvironments/discovery/locators/services/customVirtualEnvLocator.ts index 9cf459f60640..393ff4894095 100644 --- a/src/client/pythonEnvironments/discovery/locators/services/customVirtualEnvLocator.ts +++ b/src/client/pythonEnvironments/discovery/locators/services/customVirtualEnvLocator.ts @@ -21,7 +21,7 @@ import { isVenvEnvironment, isVirtualenvEnvironment, isVirtualenvwrapperEnvironment, -} from './virtualEnvironmentIdentifier'; +} from '../../../common/environmentManagers/simplevirtualenvs'; import '../../../../common/extensions'; import { asyncFilter } from '../../../../common/utils/arrayUtils'; /** diff --git a/src/client/pythonEnvironments/discovery/locators/services/globalVirtualEnvronmentLocator.ts b/src/client/pythonEnvironments/discovery/locators/services/globalVirtualEnvronmentLocator.ts index b3d6f2946d3e..aefa9dc80eea 100644 --- a/src/client/pythonEnvironments/discovery/locators/services/globalVirtualEnvronmentLocator.ts +++ b/src/client/pythonEnvironments/discovery/locators/services/globalVirtualEnvronmentLocator.ts @@ -16,7 +16,7 @@ import { isVenvEnvironment, isVirtualenvEnvironment, isVirtualenvwrapperEnvironment, -} from './virtualEnvironmentIdentifier'; +} from '../../../common/environmentManagers/simplevirtualenvs'; import '../../../../common/extensions'; import { asyncFilter } from '../../../../common/utils/arrayUtils'; diff --git a/src/test/pythonEnvironments/discovery/locators/virtualEnvironmentIdentifier.unit.test.ts b/src/test/pythonEnvironments/discovery/locators/virtualEnvironmentIdentifier.unit.test.ts index 8fee657d89ce..5c32870988c2 100644 --- a/src/test/pythonEnvironments/discovery/locators/virtualEnvironmentIdentifier.unit.test.ts +++ b/src/test/pythonEnvironments/discovery/locators/virtualEnvironmentIdentifier.unit.test.ts @@ -14,7 +14,7 @@ import { isVenvEnvironment, isVirtualenvEnvironment, isVirtualenvwrapperEnvironment, -} from '../../../../client/pythonEnvironments/discovery/locators/services/virtualEnvironmentIdentifier'; +} from '../../../../client/pythonEnvironments/common/environmentManagers/simplevirtualenvs'; import { TEST_DATA_ROOT, TEST_LAYOUT_ROOT } from '../../common/commonTestConstants'; import { assertVersionsEqual } from './envTestUtils'; From b4088dd423726cbd0960c9ab0403f288bb41115d Mon Sep 17 00:00:00 2001 From: Kartik Raj Date: Fri, 16 Jul 2021 16:07:18 -0700 Subject: [PATCH 08/19] Move condaLocator.ts --- .../services => base/locators/lowLevel}/condaLocator.ts | 8 ++------ src/client/pythonEnvironments/index.ts | 2 +- .../discovery/locators/condaHelper.unit.test.ts | 2 +- 3 files changed, 4 insertions(+), 8 deletions(-) rename src/client/pythonEnvironments/{discovery/locators/services => base/locators/lowLevel}/condaLocator.ts (91%) diff --git a/src/client/pythonEnvironments/discovery/locators/services/condaLocator.ts b/src/client/pythonEnvironments/base/locators/lowLevel/condaLocator.ts similarity index 91% rename from src/client/pythonEnvironments/discovery/locators/services/condaLocator.ts rename to src/client/pythonEnvironments/base/locators/lowLevel/condaLocator.ts index 7d5b11b87740..7e54e9efcb82 100644 --- a/src/client/pythonEnvironments/discovery/locators/services/condaLocator.ts +++ b/src/client/pythonEnvironments/base/locators/lowLevel/condaLocator.ts @@ -1,17 +1,13 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. import '../../../../common/extensions'; -import { PythonEnvKind } from '../../../base/info'; -import { BasicEnvInfo, IPythonEnvsIterator, Locator } from '../../../base/locator'; +import { PythonEnvKind } from '../../info'; +import { BasicEnvInfo, IPythonEnvsIterator, Locator } from '../../locator'; import { getInterpreterPathFromDir } from '../../../common/commonUtils'; import { Conda } from '../../../common/environmentManagers/conda'; import { traceError, traceVerbose } from '../../../../common/logger'; export class CondaEnvironmentLocator extends Locator { - public constructor() { - super(); - } - // eslint-disable-next-line class-methods-use-this public async *iterEnvs(): IPythonEnvsIterator { const conda = await Conda.getConda(); diff --git a/src/client/pythonEnvironments/index.ts b/src/client/pythonEnvironments/index.ts index 454fd9a243e2..fac221d5c607 100644 --- a/src/client/pythonEnvironments/index.ts +++ b/src/client/pythonEnvironments/index.ts @@ -19,7 +19,7 @@ import { getEnvs } from './base/locatorUtils'; import { initializeExternalDependencies as initializeLegacyExternalDependencies } from './common/externalDependencies'; import { ExtensionLocators, WatchRootsArgs, WorkspaceLocators } from './discovery/locators'; import { CustomVirtualEnvironmentLocator } from './discovery/locators/services/customVirtualEnvLocator'; -import { CondaEnvironmentLocator } from './discovery/locators/services/condaLocator'; +import { CondaEnvironmentLocator } from './base/locators/lowLevel/condaLocator'; import { GlobalVirtualEnvironmentLocator } from './discovery/locators/services/globalVirtualEnvronmentLocator'; import { PosixKnownPathsLocator } from './discovery/locators/services/posixKnownPathsLocator'; import { PyenvLocator } from './discovery/locators/services/pyenvLocator'; diff --git a/src/test/pythonEnvironments/discovery/locators/condaHelper.unit.test.ts b/src/test/pythonEnvironments/discovery/locators/condaHelper.unit.test.ts index a3a1f5167480..24ae55373f65 100644 --- a/src/test/pythonEnvironments/discovery/locators/condaHelper.unit.test.ts +++ b/src/test/pythonEnvironments/discovery/locators/condaHelper.unit.test.ts @@ -11,7 +11,7 @@ import * as externalDependencies from '../../../../client/pythonEnvironments/com import * as windowsUtils from '../../../../client/pythonEnvironments/common/windowsUtils'; import { Conda, CondaInfo } from '../../../../client/pythonEnvironments/common/environmentManagers/conda'; import { parseCondaEnvFileContents } from '../../../../client/pythonEnvironments/discovery/locators/services/condaHelper'; -import { CondaEnvironmentLocator } from '../../../../client/pythonEnvironments/discovery/locators/services/condaLocator'; +import { CondaEnvironmentLocator } from '../../../../client/pythonEnvironments/base/locators/lowLevel/condaLocator'; import { createBasicEnv } from '../../base/common'; import { assertBasicEnvsEqual } from './envTestUtils'; From 72ae4e9d854b31c6a657f22742522ec7549b3715 Mon Sep 17 00:00:00 2001 From: Kartik Raj Date: Fri, 16 Jul 2021 16:09:31 -0700 Subject: [PATCH 09/19] Move customVirtualEnvLocator.ts --- .../locators/lowLevel}/customVirtualEnvLocator.ts | 6 +++--- src/client/pythonEnvironments/index.ts | 2 +- .../discovery/locators/customVirtualEnvLocator.unit.test.ts | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) rename src/client/pythonEnvironments/{discovery/locators/services => base/locators/lowLevel}/customVirtualEnvLocator.ts (96%) diff --git a/src/client/pythonEnvironments/discovery/locators/services/customVirtualEnvLocator.ts b/src/client/pythonEnvironments/base/locators/lowLevel/customVirtualEnvLocator.ts similarity index 96% rename from src/client/pythonEnvironments/discovery/locators/services/customVirtualEnvLocator.ts rename to src/client/pythonEnvironments/base/locators/lowLevel/customVirtualEnvLocator.ts index 393ff4894095..dcdc9aaa0685 100644 --- a/src/client/pythonEnvironments/discovery/locators/services/customVirtualEnvLocator.ts +++ b/src/client/pythonEnvironments/base/locators/lowLevel/customVirtualEnvLocator.ts @@ -6,9 +6,9 @@ import * as path from 'path'; import { traceError, traceVerbose } from '../../../../common/logger'; import { chain, iterable } from '../../../../common/utils/async'; import { getUserHomeDir } from '../../../../common/utils/platform'; -import { PythonEnvKind } from '../../../base/info'; -import { BasicEnvInfo, IPythonEnvsIterator } from '../../../base/locator'; -import { FSWatchingLocator } from '../../../base/locators/lowLevel/fsWatchingLocator'; +import { PythonEnvKind } from '../../info'; +import { BasicEnvInfo, IPythonEnvsIterator } from '../../locator'; +import { FSWatchingLocator } from './fsWatchingLocator'; import { findInterpretersInDir, looksLikeBasicVirtualPython } from '../../../common/commonUtils'; import { getPythonSetting, diff --git a/src/client/pythonEnvironments/index.ts b/src/client/pythonEnvironments/index.ts index fac221d5c607..58af04817971 100644 --- a/src/client/pythonEnvironments/index.ts +++ b/src/client/pythonEnvironments/index.ts @@ -18,7 +18,7 @@ import { WorkspaceVirtualEnvironmentLocator } from './base/locators/lowLevel/wor import { getEnvs } from './base/locatorUtils'; import { initializeExternalDependencies as initializeLegacyExternalDependencies } from './common/externalDependencies'; import { ExtensionLocators, WatchRootsArgs, WorkspaceLocators } from './discovery/locators'; -import { CustomVirtualEnvironmentLocator } from './discovery/locators/services/customVirtualEnvLocator'; +import { CustomVirtualEnvironmentLocator } from './base/locators/lowLevel/customVirtualEnvLocator'; import { CondaEnvironmentLocator } from './base/locators/lowLevel/condaLocator'; import { GlobalVirtualEnvironmentLocator } from './discovery/locators/services/globalVirtualEnvronmentLocator'; import { PosixKnownPathsLocator } from './discovery/locators/services/posixKnownPathsLocator'; diff --git a/src/test/pythonEnvironments/discovery/locators/customVirtualEnvLocator.unit.test.ts b/src/test/pythonEnvironments/discovery/locators/customVirtualEnvLocator.unit.test.ts index b45381142f56..903293cdda31 100644 --- a/src/test/pythonEnvironments/discovery/locators/customVirtualEnvLocator.unit.test.ts +++ b/src/test/pythonEnvironments/discovery/locators/customVirtualEnvLocator.unit.test.ts @@ -14,7 +14,7 @@ import { CustomVirtualEnvironmentLocator, VENVFOLDERS_SETTING_KEY, VENVPATH_SETTING_KEY, -} from '../../../../client/pythonEnvironments/discovery/locators/services/customVirtualEnvLocator'; +} from '../../../../client/pythonEnvironments/base/locators/lowLevel/customVirtualEnvLocator'; import { createBasicEnv } from '../../base/common'; import { TEST_LAYOUT_ROOT } from '../../common/commonTestConstants'; import { assertBasicEnvsEqual } from './envTestUtils'; From b09e64055239bde9ce7d028f25592a526218e243 Mon Sep 17 00:00:00 2001 From: Kartik Raj Date: Fri, 16 Jul 2021 16:10:23 -0700 Subject: [PATCH 10/19] Move globalVirtualEnvLocator.ts --- .../locators/lowLevel}/globalVirtualEnvronmentLocator.ts | 6 +++--- src/client/pythonEnvironments/index.ts | 2 +- .../globalVirtualEnvironmentLocator.functional.test.ts | 2 +- .../globalVirtualEnvironmentLocator.testvirtualenvs.ts | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) rename src/client/pythonEnvironments/{discovery/locators/services => base/locators/lowLevel}/globalVirtualEnvronmentLocator.ts (96%) diff --git a/src/client/pythonEnvironments/discovery/locators/services/globalVirtualEnvronmentLocator.ts b/src/client/pythonEnvironments/base/locators/lowLevel/globalVirtualEnvronmentLocator.ts similarity index 96% rename from src/client/pythonEnvironments/discovery/locators/services/globalVirtualEnvronmentLocator.ts rename to src/client/pythonEnvironments/base/locators/lowLevel/globalVirtualEnvronmentLocator.ts index aefa9dc80eea..2e17639dcb3a 100644 --- a/src/client/pythonEnvironments/discovery/locators/services/globalVirtualEnvronmentLocator.ts +++ b/src/client/pythonEnvironments/base/locators/lowLevel/globalVirtualEnvronmentLocator.ts @@ -6,9 +6,9 @@ import * as path from 'path'; import { traceError, traceVerbose } from '../../../../common/logger'; import { chain, iterable } from '../../../../common/utils/async'; import { getEnvironmentVariable, getOSType, getUserHomeDir, OSType } from '../../../../common/utils/platform'; -import { PythonEnvKind } from '../../../base/info'; -import { BasicEnvInfo, IPythonEnvsIterator } from '../../../base/locator'; -import { FSWatchingLocator } from '../../../base/locators/lowLevel/fsWatchingLocator'; +import { PythonEnvKind } from '../../info'; +import { BasicEnvInfo, IPythonEnvsIterator } from '../../locator'; +import { FSWatchingLocator } from './fsWatchingLocator'; import { findInterpretersInDir, looksLikeBasicVirtualPython } from '../../../common/commonUtils'; import { pathExists, untildify } from '../../../common/externalDependencies'; import { isPipenvEnvironment } from '../../../common/environmentManagers/pipenv'; diff --git a/src/client/pythonEnvironments/index.ts b/src/client/pythonEnvironments/index.ts index 58af04817971..859b4087e43d 100644 --- a/src/client/pythonEnvironments/index.ts +++ b/src/client/pythonEnvironments/index.ts @@ -20,7 +20,7 @@ import { initializeExternalDependencies as initializeLegacyExternalDependencies import { ExtensionLocators, WatchRootsArgs, WorkspaceLocators } from './discovery/locators'; import { CustomVirtualEnvironmentLocator } from './base/locators/lowLevel/customVirtualEnvLocator'; import { CondaEnvironmentLocator } from './base/locators/lowLevel/condaLocator'; -import { GlobalVirtualEnvironmentLocator } from './discovery/locators/services/globalVirtualEnvronmentLocator'; +import { GlobalVirtualEnvironmentLocator } from './base/locators/lowLevel/globalVirtualEnvronmentLocator'; import { PosixKnownPathsLocator } from './discovery/locators/services/posixKnownPathsLocator'; import { PyenvLocator } from './discovery/locators/services/pyenvLocator'; import { WindowsRegistryLocator } from './discovery/locators/services/windowsRegistryLocator'; diff --git a/src/test/pythonEnvironments/discovery/locators/globalVirtualEnvironmentLocator.functional.test.ts b/src/test/pythonEnvironments/discovery/locators/globalVirtualEnvironmentLocator.functional.test.ts index 6a8913a2da15..44062ddb3f5d 100644 --- a/src/test/pythonEnvironments/discovery/locators/globalVirtualEnvironmentLocator.functional.test.ts +++ b/src/test/pythonEnvironments/discovery/locators/globalVirtualEnvironmentLocator.functional.test.ts @@ -8,7 +8,7 @@ import * as platformUtils from '../../../../client/common/utils/platform'; import { PythonEnvKind } from '../../../../client/pythonEnvironments/base/info'; import { getEnvs } from '../../../../client/pythonEnvironments/base/locatorUtils'; import * as externalDependencies from '../../../../client/pythonEnvironments/common/externalDependencies'; -import { GlobalVirtualEnvironmentLocator } from '../../../../client/pythonEnvironments/discovery/locators/services/globalVirtualEnvronmentLocator'; +import { GlobalVirtualEnvironmentLocator } from '../../../../client/pythonEnvironments/base/locators/lowLevel/globalVirtualEnvronmentLocator'; import { createBasicEnv } from '../../base/common'; import { TEST_LAYOUT_ROOT } from '../../common/commonTestConstants'; import { assertBasicEnvsEqual } from './envTestUtils'; diff --git a/src/test/pythonEnvironments/discovery/locators/globalVirtualEnvironmentLocator.testvirtualenvs.ts b/src/test/pythonEnvironments/discovery/locators/globalVirtualEnvironmentLocator.testvirtualenvs.ts index c3484788cec6..cb6c10da9781 100644 --- a/src/test/pythonEnvironments/discovery/locators/globalVirtualEnvironmentLocator.testvirtualenvs.ts +++ b/src/test/pythonEnvironments/discovery/locators/globalVirtualEnvironmentLocator.testvirtualenvs.ts @@ -2,7 +2,7 @@ // Licensed under the MIT License. import * as path from 'path'; -import { GlobalVirtualEnvironmentLocator } from '../../../../client/pythonEnvironments/discovery/locators/services/globalVirtualEnvronmentLocator'; +import { GlobalVirtualEnvironmentLocator } from '../../../../client/pythonEnvironments/base/locators/lowLevel/globalVirtualEnvronmentLocator'; import { TEST_LAYOUT_ROOT } from '../../common/commonTestConstants'; import { testLocatorWatcher } from './watcherTestUtils'; From 8a089212f05153389d8d9552071687299e9bb817 Mon Sep 17 00:00:00 2001 From: Kartik Raj Date: Fri, 16 Jul 2021 16:21:19 -0700 Subject: [PATCH 11/19] Move poetryLocator.ts --- .../services => base/locators/lowLevel}/poetryLocator.ts | 6 +++--- src/client/pythonEnvironments/index.ts | 2 +- .../discovery/locators/poetryLocator.testvirtualenvs.ts | 2 +- .../discovery/locators/poetryLocator.unit.test.ts | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) rename src/client/pythonEnvironments/{discovery/locators/services => base/locators/lowLevel}/poetryLocator.ts (94%) diff --git a/src/client/pythonEnvironments/discovery/locators/services/poetryLocator.ts b/src/client/pythonEnvironments/base/locators/lowLevel/poetryLocator.ts similarity index 94% rename from src/client/pythonEnvironments/discovery/locators/services/poetryLocator.ts rename to src/client/pythonEnvironments/base/locators/lowLevel/poetryLocator.ts index 76f2f6d12b71..9382ab12cc68 100644 --- a/src/client/pythonEnvironments/discovery/locators/services/poetryLocator.ts +++ b/src/client/pythonEnvironments/base/locators/lowLevel/poetryLocator.ts @@ -6,9 +6,9 @@ import * as path from 'path'; import { traceError, traceVerbose } from '../../../../common/logger'; import { chain, iterable } from '../../../../common/utils/async'; -import { PythonEnvKind } from '../../../base/info'; -import { BasicEnvInfo, IPythonEnvsIterator } from '../../../base/locator'; -import { FSWatchingLocator } from '../../../base/locators/lowLevel/fsWatchingLocator'; +import { PythonEnvKind } from '../../info'; +import { BasicEnvInfo, IPythonEnvsIterator } from '../../locator'; +import { FSWatchingLocator } from './fsWatchingLocator'; import { getInterpreterPathFromDir } from '../../../common/commonUtils'; import { pathExists } from '../../../common/externalDependencies'; import { isPoetryEnvironment, localPoetryEnvDirName, Poetry } from '../../../common/environmentManagers/poetry'; diff --git a/src/client/pythonEnvironments/index.ts b/src/client/pythonEnvironments/index.ts index 859b4087e43d..3ef494765230 100644 --- a/src/client/pythonEnvironments/index.ts +++ b/src/client/pythonEnvironments/index.ts @@ -27,7 +27,7 @@ import { WindowsRegistryLocator } from './discovery/locators/services/windowsReg import { WindowsStoreLocator } from './discovery/locators/services/windowsStoreLocator'; import { getEnvironmentInfoService } from './info/environmentInfoService'; import { isComponentEnabled, registerLegacyDiscoveryForIOC, registerNewDiscoveryForIOC } from './legacyIOC'; -import { PoetryLocator } from './discovery/locators/services/poetryLocator'; +import { PoetryLocator } from './base/locators/lowLevel/poetryLocator'; /** * Set up the Python environments component (during extension activation).' diff --git a/src/test/pythonEnvironments/discovery/locators/poetryLocator.testvirtualenvs.ts b/src/test/pythonEnvironments/discovery/locators/poetryLocator.testvirtualenvs.ts index cf5d66767f49..6abff7c24239 100644 --- a/src/test/pythonEnvironments/discovery/locators/poetryLocator.testvirtualenvs.ts +++ b/src/test/pythonEnvironments/discovery/locators/poetryLocator.testvirtualenvs.ts @@ -9,7 +9,7 @@ import { PythonEnvKind } from '../../../../client/pythonEnvironments/base/info'; import { BasicEnvInfo, ILocator } from '../../../../client/pythonEnvironments/base/locator'; import { getEnvs } from '../../../../client/pythonEnvironments/base/locatorUtils'; import * as externalDependencies from '../../../../client/pythonEnvironments/common/externalDependencies'; -import { PoetryLocator } from '../../../../client/pythonEnvironments/discovery/locators/services/poetryLocator'; +import { PoetryLocator } from '../../../../client/pythonEnvironments/base/locators/lowLevel/poetryLocator'; import { EXTENSION_ROOT_DIR_FOR_TESTS } from '../../../constants'; import { TEST_LAYOUT_ROOT } from '../../common/commonTestConstants'; import { testLocatorWatcher } from './watcherTestUtils'; diff --git a/src/test/pythonEnvironments/discovery/locators/poetryLocator.unit.test.ts b/src/test/pythonEnvironments/discovery/locators/poetryLocator.unit.test.ts index 7953e08ec256..40d9ebd4e914 100644 --- a/src/test/pythonEnvironments/discovery/locators/poetryLocator.unit.test.ts +++ b/src/test/pythonEnvironments/discovery/locators/poetryLocator.unit.test.ts @@ -7,7 +7,7 @@ import { PythonEnvKind } from '../../../../client/pythonEnvironments/base/info'; import * as externalDependencies from '../../../../client/pythonEnvironments/common/externalDependencies'; import * as platformUtils from '../../../../client/common/utils/platform'; import { getEnvs } from '../../../../client/pythonEnvironments/base/locatorUtils'; -import { PoetryLocator } from '../../../../client/pythonEnvironments/discovery/locators/services/poetryLocator'; +import { PoetryLocator } from '../../../../client/pythonEnvironments/base/locators/lowLevel/poetryLocator'; import { TEST_LAYOUT_ROOT } from '../../common/commonTestConstants'; import { assertBasicEnvsEqual } from './envTestUtils'; import { ExecutionResult, ShellOptions } from '../../../../client/common/process/types'; From cdee3bf0a4923e2d0f9ed891c8a1cb36698b2c6f Mon Sep 17 00:00:00 2001 From: Kartik Raj Date: Fri, 16 Jul 2021 16:28:28 -0700 Subject: [PATCH 12/19] Move posixKnownPathsLocator.ts --- .../locators/lowLevel}/posixKnownPathsLocator.ts | 4 ++-- src/client/pythonEnvironments/index.ts | 2 +- .../discovery/locators/posixKnownPathsLocator.unit.test.ts | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) rename src/client/pythonEnvironments/{discovery/locators/services => base/locators/lowLevel}/posixKnownPathsLocator.ts (94%) diff --git a/src/client/pythonEnvironments/discovery/locators/services/posixKnownPathsLocator.ts b/src/client/pythonEnvironments/base/locators/lowLevel/posixKnownPathsLocator.ts similarity index 94% rename from src/client/pythonEnvironments/discovery/locators/services/posixKnownPathsLocator.ts rename to src/client/pythonEnvironments/base/locators/lowLevel/posixKnownPathsLocator.ts index cbc926e74d80..74070386355f 100644 --- a/src/client/pythonEnvironments/discovery/locators/services/posixKnownPathsLocator.ts +++ b/src/client/pythonEnvironments/base/locators/lowLevel/posixKnownPathsLocator.ts @@ -2,8 +2,8 @@ // Licensed under the MIT License. import { traceError } from '../../../../common/logger'; -import { PythonEnvKind, PythonEnvSource } from '../../../base/info'; -import { BasicEnvInfo, IPythonEnvsIterator, Locator } from '../../../base/locator'; +import { PythonEnvKind, PythonEnvSource } from '../../info'; +import { BasicEnvInfo, IPythonEnvsIterator, Locator } from '../../locator'; import { commonPosixBinPaths, getPythonBinFromPosixPaths } from '../../../common/posixUtils'; import { isPyenvShimDir } from '../../../common/environmentManagers/pyenv'; diff --git a/src/client/pythonEnvironments/index.ts b/src/client/pythonEnvironments/index.ts index 3ef494765230..3e51336eb1d8 100644 --- a/src/client/pythonEnvironments/index.ts +++ b/src/client/pythonEnvironments/index.ts @@ -21,7 +21,7 @@ import { ExtensionLocators, WatchRootsArgs, WorkspaceLocators } from './discover import { CustomVirtualEnvironmentLocator } from './base/locators/lowLevel/customVirtualEnvLocator'; import { CondaEnvironmentLocator } from './base/locators/lowLevel/condaLocator'; import { GlobalVirtualEnvironmentLocator } from './base/locators/lowLevel/globalVirtualEnvronmentLocator'; -import { PosixKnownPathsLocator } from './discovery/locators/services/posixKnownPathsLocator'; +import { PosixKnownPathsLocator } from './base/locators/lowLevel/posixKnownPathsLocator'; import { PyenvLocator } from './discovery/locators/services/pyenvLocator'; import { WindowsRegistryLocator } from './discovery/locators/services/windowsRegistryLocator'; import { WindowsStoreLocator } from './discovery/locators/services/windowsStoreLocator'; diff --git a/src/test/pythonEnvironments/discovery/locators/posixKnownPathsLocator.unit.test.ts b/src/test/pythonEnvironments/discovery/locators/posixKnownPathsLocator.unit.test.ts index 80e2cb310668..4187e3b503ca 100644 --- a/src/test/pythonEnvironments/discovery/locators/posixKnownPathsLocator.unit.test.ts +++ b/src/test/pythonEnvironments/discovery/locators/posixKnownPathsLocator.unit.test.ts @@ -7,7 +7,7 @@ import * as executablesAPI from '../../../../client/common/utils/exec'; import { PythonEnvKind, PythonEnvSource } from '../../../../client/pythonEnvironments/base/info'; import { BasicEnvInfo } from '../../../../client/pythonEnvironments/base/locator'; import { getEnvs } from '../../../../client/pythonEnvironments/base/locatorUtils'; -import { PosixKnownPathsLocator } from '../../../../client/pythonEnvironments/discovery/locators/services/posixKnownPathsLocator'; +import { PosixKnownPathsLocator } from '../../../../client/pythonEnvironments/base/locators/lowLevel/posixKnownPathsLocator'; import { createBasicEnv } from '../../base/common'; import { TEST_LAYOUT_ROOT } from '../../common/commonTestConstants'; import { assertBasicEnvsEqual } from './envTestUtils'; From d7abd3a8ec7123545918c5bcafbe489366841cb8 Mon Sep 17 00:00:00 2001 From: Kartik Raj Date: Fri, 16 Jul 2021 16:29:37 -0700 Subject: [PATCH 13/19] Move pyenvLocator.ts --- .../services => base/locators/lowLevel}/pyenvLocator.ts | 6 +++--- src/client/pythonEnvironments/index.ts | 2 +- .../discovery/locators/pyenvLocator.functional.test.ts | 2 +- .../discovery/locators/pyenvLocator.testvirtualenvs.ts | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) rename src/client/pythonEnvironments/{discovery/locators/services => base/locators/lowLevel}/pyenvLocator.ts (88%) diff --git a/src/client/pythonEnvironments/discovery/locators/services/pyenvLocator.ts b/src/client/pythonEnvironments/base/locators/lowLevel/pyenvLocator.ts similarity index 88% rename from src/client/pythonEnvironments/discovery/locators/services/pyenvLocator.ts rename to src/client/pythonEnvironments/base/locators/lowLevel/pyenvLocator.ts index bfdab4260844..00f71eaa65ab 100644 --- a/src/client/pythonEnvironments/discovery/locators/services/pyenvLocator.ts +++ b/src/client/pythonEnvironments/base/locators/lowLevel/pyenvLocator.ts @@ -3,9 +3,9 @@ import * as path from 'path'; import { traceError } from '../../../../common/logger'; -import { PythonEnvKind } from '../../../base/info'; -import { BasicEnvInfo, IPythonEnvsIterator } from '../../../base/locator'; -import { FSWatchingLocator } from '../../../base/locators/lowLevel/fsWatchingLocator'; +import { PythonEnvKind } from '../../info'; +import { BasicEnvInfo, IPythonEnvsIterator } from '../../locator'; +import { FSWatchingLocator } from './fsWatchingLocator'; import { getInterpreterPathFromDir } from '../../../common/commonUtils'; import { getSubDirs } from '../../../common/externalDependencies'; import { getPyenvDir } from '../../../common/environmentManagers/pyenv'; diff --git a/src/client/pythonEnvironments/index.ts b/src/client/pythonEnvironments/index.ts index 3e51336eb1d8..32ba460a58a5 100644 --- a/src/client/pythonEnvironments/index.ts +++ b/src/client/pythonEnvironments/index.ts @@ -22,7 +22,7 @@ import { CustomVirtualEnvironmentLocator } from './base/locators/lowLevel/custom import { CondaEnvironmentLocator } from './base/locators/lowLevel/condaLocator'; import { GlobalVirtualEnvironmentLocator } from './base/locators/lowLevel/globalVirtualEnvronmentLocator'; import { PosixKnownPathsLocator } from './base/locators/lowLevel/posixKnownPathsLocator'; -import { PyenvLocator } from './discovery/locators/services/pyenvLocator'; +import { PyenvLocator } from './base/locators/lowLevel/pyenvLocator'; import { WindowsRegistryLocator } from './discovery/locators/services/windowsRegistryLocator'; import { WindowsStoreLocator } from './discovery/locators/services/windowsStoreLocator'; import { getEnvironmentInfoService } from './info/environmentInfoService'; diff --git a/src/test/pythonEnvironments/discovery/locators/pyenvLocator.functional.test.ts b/src/test/pythonEnvironments/discovery/locators/pyenvLocator.functional.test.ts index da67fc66b035..873f41249216 100644 --- a/src/test/pythonEnvironments/discovery/locators/pyenvLocator.functional.test.ts +++ b/src/test/pythonEnvironments/discovery/locators/pyenvLocator.functional.test.ts @@ -7,7 +7,7 @@ import * as fsWatcher from '../../../../client/common/platform/fileSystemWatcher import * as platformUtils from '../../../../client/common/utils/platform'; import { PythonEnvKind } from '../../../../client/pythonEnvironments/base/info'; import { getEnvs } from '../../../../client/pythonEnvironments/base/locatorUtils'; -import { PyenvLocator } from '../../../../client/pythonEnvironments/discovery/locators/services/pyenvLocator'; +import { PyenvLocator } from '../../../../client/pythonEnvironments/base/locators/lowLevel/pyenvLocator'; import { createBasicEnv } from '../../base/common'; import { TEST_LAYOUT_ROOT } from '../../common/commonTestConstants'; import { assertBasicEnvsEqual } from './envTestUtils'; diff --git a/src/test/pythonEnvironments/discovery/locators/pyenvLocator.testvirtualenvs.ts b/src/test/pythonEnvironments/discovery/locators/pyenvLocator.testvirtualenvs.ts index fc800c008a1a..c851d6a18ee2 100644 --- a/src/test/pythonEnvironments/discovery/locators/pyenvLocator.testvirtualenvs.ts +++ b/src/test/pythonEnvironments/discovery/locators/pyenvLocator.testvirtualenvs.ts @@ -3,7 +3,7 @@ import * as path from 'path'; import { PythonEnvKind } from '../../../../client/pythonEnvironments/base/info'; -import { PyenvLocator } from '../../../../client/pythonEnvironments/discovery/locators/services/pyenvLocator'; +import { PyenvLocator } from '../../../../client/pythonEnvironments/base/locators/lowLevel/pyenvLocator'; import { TEST_LAYOUT_ROOT } from '../../common/commonTestConstants'; import { testLocatorWatcher } from './watcherTestUtils'; From f2ad01e9e449b2526269e9adb0291472b7d6ccd2 Mon Sep 17 00:00:00 2001 From: Kartik Raj Date: Fri, 16 Jul 2021 16:30:33 -0700 Subject: [PATCH 14/19] Move windowsRegistryLocator.ts --- .../locators/lowLevel}/windowsRegistryLocator.ts | 4 ++-- src/client/pythonEnvironments/index.ts | 2 +- .../discovery/locators/windowsRegistryLocator.unit.test.ts | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) rename src/client/pythonEnvironments/{discovery/locators/services => base/locators/lowLevel}/windowsRegistryLocator.ts (92%) diff --git a/src/client/pythonEnvironments/discovery/locators/services/windowsRegistryLocator.ts b/src/client/pythonEnvironments/base/locators/lowLevel/windowsRegistryLocator.ts similarity index 92% rename from src/client/pythonEnvironments/discovery/locators/services/windowsRegistryLocator.ts rename to src/client/pythonEnvironments/base/locators/lowLevel/windowsRegistryLocator.ts index 341cef43e8d0..fc493fc13e16 100644 --- a/src/client/pythonEnvironments/discovery/locators/services/windowsRegistryLocator.ts +++ b/src/client/pythonEnvironments/base/locators/lowLevel/windowsRegistryLocator.ts @@ -2,8 +2,8 @@ // Licensed under the MIT License. import { traceError } from '../../../../common/logger'; -import { PythonEnvKind, PythonEnvSource } from '../../../base/info'; -import { BasicEnvInfo, IPythonEnvsIterator, Locator } from '../../../base/locator'; +import { PythonEnvKind, PythonEnvSource } from '../../info'; +import { BasicEnvInfo, IPythonEnvsIterator, Locator } from '../../locator'; import { getRegistryInterpreters } from '../../../common/windowsUtils'; export class WindowsRegistryLocator extends Locator { diff --git a/src/client/pythonEnvironments/index.ts b/src/client/pythonEnvironments/index.ts index 32ba460a58a5..45ef720c0e20 100644 --- a/src/client/pythonEnvironments/index.ts +++ b/src/client/pythonEnvironments/index.ts @@ -23,7 +23,7 @@ import { CondaEnvironmentLocator } from './base/locators/lowLevel/condaLocator'; import { GlobalVirtualEnvironmentLocator } from './base/locators/lowLevel/globalVirtualEnvronmentLocator'; import { PosixKnownPathsLocator } from './base/locators/lowLevel/posixKnownPathsLocator'; import { PyenvLocator } from './base/locators/lowLevel/pyenvLocator'; -import { WindowsRegistryLocator } from './discovery/locators/services/windowsRegistryLocator'; +import { WindowsRegistryLocator } from './base/locators/lowLevel/windowsRegistryLocator'; import { WindowsStoreLocator } from './discovery/locators/services/windowsStoreLocator'; import { getEnvironmentInfoService } from './info/environmentInfoService'; import { isComponentEnabled, registerLegacyDiscoveryForIOC, registerNewDiscoveryForIOC } from './legacyIOC'; diff --git a/src/test/pythonEnvironments/discovery/locators/windowsRegistryLocator.unit.test.ts b/src/test/pythonEnvironments/discovery/locators/windowsRegistryLocator.unit.test.ts index eac49214b9a4..f62f8de0aea7 100644 --- a/src/test/pythonEnvironments/discovery/locators/windowsRegistryLocator.unit.test.ts +++ b/src/test/pythonEnvironments/discovery/locators/windowsRegistryLocator.unit.test.ts @@ -7,7 +7,7 @@ import * as sinon from 'sinon'; import { PythonEnvKind, PythonEnvSource } from '../../../../client/pythonEnvironments/base/info'; import { getEnvs } from '../../../../client/pythonEnvironments/base/locatorUtils'; import * as winreg from '../../../../client/pythonEnvironments/common/windowsRegistry'; -import { WindowsRegistryLocator } from '../../../../client/pythonEnvironments/discovery/locators/services/windowsRegistryLocator'; +import { WindowsRegistryLocator } from '../../../../client/pythonEnvironments/base/locators/lowLevel/windowsRegistryLocator'; import { createBasicEnv } from '../../base/common'; import { TEST_LAYOUT_ROOT } from '../../common/commonTestConstants'; import { assertBasicEnvsEqual } from './envTestUtils'; From db1c5049e0634e17dc1cb0762d69ce9631d17c37 Mon Sep 17 00:00:00 2001 From: Kartik Raj Date: Fri, 16 Jul 2021 16:33:44 -0700 Subject: [PATCH 15/19] Move windowsStoreLocator.ts --- .../base/locators/lowLevel/windowsKnownPathsLocator.ts | 2 +- .../locators/lowLevel}/windowsStoreLocator.ts | 6 +++--- .../pythonEnvironments/common/environmentIdentifier.ts | 2 +- src/client/pythonEnvironments/index.ts | 2 +- src/client/pythonEnvironments/legacyIOC.ts | 2 +- .../discovery/locators/windowsStoreLocator.test.ts | 2 +- .../discovery/locators/windowsStoreLocator.unit.test.ts | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) rename src/client/pythonEnvironments/{discovery/locators/services => base/locators/lowLevel}/windowsStoreLocator.ts (97%) diff --git a/src/client/pythonEnvironments/base/locators/lowLevel/windowsKnownPathsLocator.ts b/src/client/pythonEnvironments/base/locators/lowLevel/windowsKnownPathsLocator.ts index d1cb7073070c..d9dd7eb79357 100644 --- a/src/client/pythonEnvironments/base/locators/lowLevel/windowsKnownPathsLocator.ts +++ b/src/client/pythonEnvironments/base/locators/lowLevel/windowsKnownPathsLocator.ts @@ -9,7 +9,7 @@ import { getSearchPathEntries } from '../../../../common/utils/exec'; import { Disposables, IDisposable } from '../../../../common/utils/resourceLifecycle'; import { iterPythonExecutablesInDir, looksLikeBasicGlobalPython } from '../../../common/commonUtils'; import { isPyenvShimDir } from '../../../common/environmentManagers/pyenv'; -import { isWindowsStoreDir } from '../../../discovery/locators/services/windowsStoreLocator'; +import { isWindowsStoreDir } from './windowsStoreLocator'; import { PythonEnvKind, PythonEnvSource } from '../../info'; import { BasicEnvInfo, ILocator, IPythonEnvsIterator, PythonLocatorQuery } from '../../locator'; import { Locators } from '../../locators'; diff --git a/src/client/pythonEnvironments/discovery/locators/services/windowsStoreLocator.ts b/src/client/pythonEnvironments/base/locators/lowLevel/windowsStoreLocator.ts similarity index 97% rename from src/client/pythonEnvironments/discovery/locators/services/windowsStoreLocator.ts rename to src/client/pythonEnvironments/base/locators/lowLevel/windowsStoreLocator.ts index 080ed9122457..49c2717337eb 100644 --- a/src/client/pythonEnvironments/discovery/locators/services/windowsStoreLocator.ts +++ b/src/client/pythonEnvironments/base/locators/lowLevel/windowsStoreLocator.ts @@ -6,9 +6,9 @@ import * as minimatch from 'minimatch'; import * as path from 'path'; import { traceWarning } from '../../../../common/logger'; import { getEnvironmentVariable } from '../../../../common/utils/platform'; -import { PythonEnvKind } from '../../../base/info'; -import { IPythonEnvsIterator, BasicEnvInfo } from '../../../base/locator'; -import { FSWatchingLocator } from '../../../base/locators/lowLevel/fsWatchingLocator'; +import { PythonEnvKind } from '../../info'; +import { IPythonEnvsIterator, BasicEnvInfo } from '../../locator'; +import { FSWatchingLocator } from './fsWatchingLocator'; import { pathExists } from '../../../common/externalDependencies'; import { PythonEnvStructure } from '../../../common/pythonBinariesWatcher'; diff --git a/src/client/pythonEnvironments/common/environmentIdentifier.ts b/src/client/pythonEnvironments/common/environmentIdentifier.ts index bff1eb56ee15..82441347b56f 100644 --- a/src/client/pythonEnvironments/common/environmentIdentifier.ts +++ b/src/client/pythonEnvironments/common/environmentIdentifier.ts @@ -12,7 +12,7 @@ import { isVirtualenvEnvironment as isVirtualEnvEnvironment, isVirtualenvwrapperEnvironment as isVirtualEnvWrapperEnvironment, } from './environmentManagers/simplevirtualenvs'; -import { isWindowsStoreEnvironment } from '../discovery/locators/services/windowsStoreLocator'; +import { isWindowsStoreEnvironment } from '../base/locators/lowLevel/windowsStoreLocator'; function getIdentifiers(): Map Promise> { const notImplemented = () => Promise.resolve(false); diff --git a/src/client/pythonEnvironments/index.ts b/src/client/pythonEnvironments/index.ts index 45ef720c0e20..5b197a9e0714 100644 --- a/src/client/pythonEnvironments/index.ts +++ b/src/client/pythonEnvironments/index.ts @@ -24,7 +24,7 @@ import { GlobalVirtualEnvironmentLocator } from './base/locators/lowLevel/global import { PosixKnownPathsLocator } from './base/locators/lowLevel/posixKnownPathsLocator'; import { PyenvLocator } from './base/locators/lowLevel/pyenvLocator'; import { WindowsRegistryLocator } from './base/locators/lowLevel/windowsRegistryLocator'; -import { WindowsStoreLocator } from './discovery/locators/services/windowsStoreLocator'; +import { WindowsStoreLocator } from './base/locators/lowLevel/windowsStoreLocator'; import { getEnvironmentInfoService } from './info/environmentInfoService'; import { isComponentEnabled, registerLegacyDiscoveryForIOC, registerNewDiscoveryForIOC } from './legacyIOC'; import { PoetryLocator } from './base/locators/lowLevel/poetryLocator'; diff --git a/src/client/pythonEnvironments/legacyIOC.ts b/src/client/pythonEnvironments/legacyIOC.ts index 8406d42957e7..38f9231229d3 100644 --- a/src/client/pythonEnvironments/legacyIOC.ts +++ b/src/client/pythonEnvironments/legacyIOC.ts @@ -57,7 +57,7 @@ import { KnownPathsService, KnownSearchPathsForInterpreters } from './discovery/ import { PipEnvService } from './discovery/locators/services/pipEnvService'; import { PipEnvServiceHelper } from './discovery/locators/services/pipEnvServiceHelper'; import { WindowsRegistryService } from './discovery/locators/services/windowsRegistryService'; -import { isWindowsStoreEnvironment } from './discovery/locators/services/windowsStoreLocator'; +import { isWindowsStoreEnvironment } from './base/locators/lowLevel/windowsStoreLocator'; import { WorkspaceVirtualEnvironmentsSearchPathProvider, WorkspaceVirtualEnvService, diff --git a/src/test/pythonEnvironments/discovery/locators/windowsStoreLocator.test.ts b/src/test/pythonEnvironments/discovery/locators/windowsStoreLocator.test.ts index fac557769dc3..cab77f770524 100644 --- a/src/test/pythonEnvironments/discovery/locators/windowsStoreLocator.test.ts +++ b/src/test/pythonEnvironments/discovery/locators/windowsStoreLocator.test.ts @@ -14,7 +14,7 @@ import { PythonEnvKind } from '../../../../client/pythonEnvironments/base/info'; import { getEnvs } from '../../../../client/pythonEnvironments/base/locatorUtils'; import { PythonEnvsChangedEvent } from '../../../../client/pythonEnvironments/base/watcher'; import * as externalDeps from '../../../../client/pythonEnvironments/common/externalDependencies'; -import { WindowsStoreLocator } from '../../../../client/pythonEnvironments/discovery/locators/services/windowsStoreLocator'; +import { WindowsStoreLocator } from '../../../../client/pythonEnvironments/base/locators/lowLevel/windowsStoreLocator'; import { TEST_TIMEOUT } from '../../../constants'; import { TEST_LAYOUT_ROOT } from '../../common/commonTestConstants'; diff --git a/src/test/pythonEnvironments/discovery/locators/windowsStoreLocator.unit.test.ts b/src/test/pythonEnvironments/discovery/locators/windowsStoreLocator.unit.test.ts index 3218f1fab1c6..aab4a5df740e 100644 --- a/src/test/pythonEnvironments/discovery/locators/windowsStoreLocator.unit.test.ts +++ b/src/test/pythonEnvironments/discovery/locators/windowsStoreLocator.unit.test.ts @@ -14,7 +14,7 @@ import { getWindowsStorePythonExes, isWindowsStoreDir, WindowsStoreLocator, -} from '../../../../client/pythonEnvironments/discovery/locators/services/windowsStoreLocator'; +} from '../../../../client/pythonEnvironments/base/locators/lowLevel/windowsStoreLocator'; import { getEnvs } from '../../base/common'; import { TEST_LAYOUT_ROOT } from '../../common/commonTestConstants'; import { assertBasicEnvsEqual } from './envTestUtils'; From 63407a11bb296c3f68348cf1b542c79c70603531 Mon Sep 17 00:00:00 2001 From: Kartik Raj Date: Fri, 16 Jul 2021 16:49:03 -0700 Subject: [PATCH 16/19] Refactor Windows Store domain knowledge out of the locator --- .../lowLevel/customVirtualEnvLocator.ts | 2 +- .../globalVirtualEnvronmentLocator.ts | 2 +- .../lowLevel/windowsKnownPathsLocator.ts | 2 +- .../locators/lowLevel/windowsStoreLocator.ts | 121 +---------------- .../lowLevel/workspaceVirtualEnvLocator.ts | 2 +- .../pythonEnvironments/common/commonUtils.ts | 2 +- .../common/environmentIdentifier.ts | 4 +- .../common/environmentManagers/poetry.ts | 2 +- .../environmentManagers/windowsStoreEnv.ts | 122 ++++++++++++++++++ src/client/pythonEnvironments/legacyIOC.ts | 2 +- .../virtualEnvironmentIdentifier.unit.test.ts | 2 +- .../locators/windowsStoreLocator.unit.test.ts | 2 +- 12 files changed, 134 insertions(+), 131 deletions(-) create mode 100644 src/client/pythonEnvironments/common/environmentManagers/windowsStoreEnv.ts diff --git a/src/client/pythonEnvironments/base/locators/lowLevel/customVirtualEnvLocator.ts b/src/client/pythonEnvironments/base/locators/lowLevel/customVirtualEnvLocator.ts index dcdc9aaa0685..a440d048c831 100644 --- a/src/client/pythonEnvironments/base/locators/lowLevel/customVirtualEnvLocator.ts +++ b/src/client/pythonEnvironments/base/locators/lowLevel/customVirtualEnvLocator.ts @@ -21,7 +21,7 @@ import { isVenvEnvironment, isVirtualenvEnvironment, isVirtualenvwrapperEnvironment, -} from '../../../common/environmentManagers/simplevirtualenvs'; +} from '../../../common/environmentManagers/simpleVirtualEnvs'; import '../../../../common/extensions'; import { asyncFilter } from '../../../../common/utils/arrayUtils'; /** diff --git a/src/client/pythonEnvironments/base/locators/lowLevel/globalVirtualEnvronmentLocator.ts b/src/client/pythonEnvironments/base/locators/lowLevel/globalVirtualEnvronmentLocator.ts index 2e17639dcb3a..27c34ad76c60 100644 --- a/src/client/pythonEnvironments/base/locators/lowLevel/globalVirtualEnvronmentLocator.ts +++ b/src/client/pythonEnvironments/base/locators/lowLevel/globalVirtualEnvronmentLocator.ts @@ -16,7 +16,7 @@ import { isVenvEnvironment, isVirtualenvEnvironment, isVirtualenvwrapperEnvironment, -} from '../../../common/environmentManagers/simplevirtualenvs'; +} from '../../../common/environmentManagers/simpleVirtualEnvs'; import '../../../../common/extensions'; import { asyncFilter } from '../../../../common/utils/arrayUtils'; diff --git a/src/client/pythonEnvironments/base/locators/lowLevel/windowsKnownPathsLocator.ts b/src/client/pythonEnvironments/base/locators/lowLevel/windowsKnownPathsLocator.ts index d9dd7eb79357..532cb89b8b6d 100644 --- a/src/client/pythonEnvironments/base/locators/lowLevel/windowsKnownPathsLocator.ts +++ b/src/client/pythonEnvironments/base/locators/lowLevel/windowsKnownPathsLocator.ts @@ -9,7 +9,7 @@ import { getSearchPathEntries } from '../../../../common/utils/exec'; import { Disposables, IDisposable } from '../../../../common/utils/resourceLifecycle'; import { iterPythonExecutablesInDir, looksLikeBasicGlobalPython } from '../../../common/commonUtils'; import { isPyenvShimDir } from '../../../common/environmentManagers/pyenv'; -import { isWindowsStoreDir } from './windowsStoreLocator'; +import { isWindowsStoreDir } from '../../../common/environmentManagers/windowsStoreEnv'; import { PythonEnvKind, PythonEnvSource } from '../../info'; import { BasicEnvInfo, ILocator, IPythonEnvsIterator, PythonLocatorQuery } from '../../locator'; import { Locators } from '../../locators'; diff --git a/src/client/pythonEnvironments/base/locators/lowLevel/windowsStoreLocator.ts b/src/client/pythonEnvironments/base/locators/lowLevel/windowsStoreLocator.ts index 49c2717337eb..dd5ee551fbe8 100644 --- a/src/client/pythonEnvironments/base/locators/lowLevel/windowsStoreLocator.ts +++ b/src/client/pythonEnvironments/base/locators/lowLevel/windowsStoreLocator.ts @@ -4,130 +4,11 @@ import * as fsapi from 'fs-extra'; import * as minimatch from 'minimatch'; import * as path from 'path'; -import { traceWarning } from '../../../../common/logger'; -import { getEnvironmentVariable } from '../../../../common/utils/platform'; import { PythonEnvKind } from '../../info'; import { IPythonEnvsIterator, BasicEnvInfo } from '../../locator'; import { FSWatchingLocator } from './fsWatchingLocator'; -import { pathExists } from '../../../common/externalDependencies'; import { PythonEnvStructure } from '../../../common/pythonBinariesWatcher'; - -/** - * Gets path to the Windows Apps directory. - * @returns {string} : Returns path to the Windows Apps directory under - * `%LOCALAPPDATA%/Microsoft/WindowsApps`. - */ -function getWindowsStoreAppsRoot(): string { - const localAppData = getEnvironmentVariable('LOCALAPPDATA') || ''; - return path.join(localAppData, 'Microsoft', 'WindowsApps'); -} - -/** - * Checks if a given path is under the forbidden windows store directory. - * @param {string} absPath : Absolute path to a file or directory. - * @returns {boolean} : Returns true if `interpreterPath` is under - * `%ProgramFiles%/WindowsApps`. - */ -function isForbiddenStorePath(absPath: string): boolean { - const programFilesStorePath = path - .join(getEnvironmentVariable('ProgramFiles') || 'Program Files', 'WindowsApps') - .normalize() - .toUpperCase(); - return path.normalize(absPath).toUpperCase().includes(programFilesStorePath); -} - -/** - * Checks if a given directory is any one of the possible windows store directories, or - * its sub-directory. - * @param {string} dirPath : Absolute path to a directory. - * - * Remarks: - * These locations are tested: - * 1. %LOCALAPPDATA%/Microsoft/WindowsApps - * 2. %ProgramFiles%/WindowsApps - */ -export function isWindowsStoreDir(dirPath: string): boolean { - const storeRootPath = path.normalize(getWindowsStoreAppsRoot()).toUpperCase(); - return path.normalize(dirPath).toUpperCase().includes(storeRootPath) || isForbiddenStorePath(dirPath); -} - -/** - * Checks if store python is installed. - * @param {string} interpreterPath : Absolute path to a interpreter. - * Remarks: - * If store python was never installed then the store apps directory will not - * have idle.exe or pip.exe. We can use this as a way to identify the python.exe - * found in the store apps directory is a real python or a store install shortcut. - */ -async function isStorePythonInstalled(interpreterPath?: string): Promise { - let results = await Promise.all([ - pathExists(path.join(getWindowsStoreAppsRoot(), 'idle.exe')), - pathExists(path.join(getWindowsStoreAppsRoot(), 'pip.exe')), - ]); - - if (results.includes(true)) { - return true; - } - - if (interpreterPath) { - results = await Promise.all([ - pathExists(path.join(path.dirname(interpreterPath), 'idle.exe')), - pathExists(path.join(path.dirname(interpreterPath), 'pip.exe')), - ]); - return results.includes(true); - } - return false; -} - -/** - * Checks if the given interpreter belongs to Windows Store Python environment. - * @param interpreterPath: Absolute path to any python interpreter. - * - * Remarks: - * 1. Checking if the path includes `Microsoft\WindowsApps`, `Program Files\WindowsApps`, is - * NOT enough. In WSL, `/mnt/c/users/user/AppData/Local/Microsoft/WindowsApps` is available as a search - * path. It is possible to get a false positive for that path. So the comparison should check if the - * absolute path to 'WindowsApps' directory is present in the given interpreter path. The WSL path to - * 'WindowsApps' is not a valid path to access, Windows Store Python. - * - * 2. 'startsWith' comparison may not be right, user can provide '\\?\C:\users\' style long paths in windows. - * - * 3. A limitation of the checks here is that they don't handle 8.3 style windows paths. - * For example, - * `C:\Users\USER\AppData\Local\MICROS~1\WINDOW~1\PYTHON~2.EXE` - * is the shortened form of - * `C:\Users\USER\AppData\Local\Microsoft\WindowsApps\python3.7.exe` - * - * The correct way to compare these would be to always convert given paths to long path (or to short path). - * For either approach to work correctly you need actual file to exist, and accessible from the user's - * account. - * - * To convert to short path without using N-API in node would be to use this command. This is very expensive: - * `> cmd /c for %A in ("C:\Users\USER\AppData\Local\Microsoft\WindowsApps\python3.7.exe") do @echo %~sA` - * The above command will print out this: - * `C:\Users\USER\AppData\Local\MICROS~1\WINDOW~1\PYTHON~2.EXE` - * - * If we go down the N-API route, use node-ffi and either call GetShortPathNameW or GetLongPathNameW from, - * Kernel32 to convert between the two path variants. - * - */ -export async function isWindowsStoreEnvironment(interpreterPath: string): Promise { - if (await isStorePythonInstalled(interpreterPath)) { - const pythonPathToCompare = path.normalize(interpreterPath).toUpperCase(); - const localAppDataStorePath = path.normalize(getWindowsStoreAppsRoot()).toUpperCase(); - if (pythonPathToCompare.includes(localAppDataStorePath)) { - return true; - } - - // Program Files store path is a forbidden path. Only admins and system has access this path. - // We should never have to look at this path or even execute python from this path. - if (isForbiddenStorePath(pythonPathToCompare)) { - traceWarning('isWindowsStoreEnvironment called with Program Files store path.'); - return true; - } - } - return false; -} +import { isStorePythonInstalled, getWindowsStoreAppsRoot } from '../../../common/environmentManagers/windowsStoreEnv'; /** * This is a glob pattern which matches following file names: diff --git a/src/client/pythonEnvironments/base/locators/lowLevel/workspaceVirtualEnvLocator.ts b/src/client/pythonEnvironments/base/locators/lowLevel/workspaceVirtualEnvLocator.ts index 0b0e60dd94d0..e101ce20e3bf 100644 --- a/src/client/pythonEnvironments/base/locators/lowLevel/workspaceVirtualEnvLocator.ts +++ b/src/client/pythonEnvironments/base/locators/lowLevel/workspaceVirtualEnvLocator.ts @@ -7,7 +7,7 @@ import { chain, iterable } from '../../../../common/utils/async'; import { findInterpretersInDir, looksLikeBasicVirtualPython } from '../../../common/commonUtils'; import { pathExists } from '../../../common/externalDependencies'; import { isPipenvEnvironment } from '../../../common/environmentManagers/pipenv'; -import { isVenvEnvironment, isVirtualenvEnvironment } from '../../../common/environmentManagers/simplevirtualenvs'; +import { isVenvEnvironment, isVirtualenvEnvironment } from '../../../common/environmentManagers/simpleVirtualEnvs'; import { PythonEnvKind } from '../../info'; import { BasicEnvInfo, IPythonEnvsIterator } from '../../locator'; import { FSWatchingLocator } from './fsWatchingLocator'; diff --git a/src/client/pythonEnvironments/common/commonUtils.ts b/src/client/pythonEnvironments/common/commonUtils.ts index f6b5ae810542..b9d63ab851fc 100644 --- a/src/client/pythonEnvironments/common/commonUtils.ts +++ b/src/client/pythonEnvironments/common/commonUtils.ts @@ -10,7 +10,7 @@ import { PythonVersion, UNKNOWN_PYTHON_VERSION } from '../base/info'; import { comparePythonVersionSpecificity } from '../base/info/env'; import { parseVersion } from '../base/info/pythonVersion'; import { getPythonVersionFromConda } from './environmentManagers/conda'; -import { getPythonVersionFromPyvenvCfg } from './environmentManagers/simplevirtualenvs'; +import { getPythonVersionFromPyvenvCfg } from './environmentManagers/simpleVirtualEnvs'; import * as posix from './posixUtils'; import * as windows from './windowsUtils'; diff --git a/src/client/pythonEnvironments/common/environmentIdentifier.ts b/src/client/pythonEnvironments/common/environmentIdentifier.ts index 82441347b56f..e9b40de86afb 100644 --- a/src/client/pythonEnvironments/common/environmentIdentifier.ts +++ b/src/client/pythonEnvironments/common/environmentIdentifier.ts @@ -11,8 +11,8 @@ import { isVenvEnvironment, isVirtualenvEnvironment as isVirtualEnvEnvironment, isVirtualenvwrapperEnvironment as isVirtualEnvWrapperEnvironment, -} from './environmentManagers/simplevirtualenvs'; -import { isWindowsStoreEnvironment } from '../base/locators/lowLevel/windowsStoreLocator'; +} from './environmentManagers/simpleVirtualEnvs'; +import { isWindowsStoreEnvironment } from './environmentManagers/windowsStoreEnv'; function getIdentifiers(): Map Promise> { const notImplemented = () => Promise.resolve(false); diff --git a/src/client/pythonEnvironments/common/environmentManagers/poetry.ts b/src/client/pythonEnvironments/common/environmentManagers/poetry.ts index eb52c5b653d5..a4a3bfa8fb89 100644 --- a/src/client/pythonEnvironments/common/environmentManagers/poetry.ts +++ b/src/client/pythonEnvironments/common/environmentManagers/poetry.ts @@ -8,7 +8,7 @@ import { traceError, traceVerbose } from '../../../common/logger'; import { getOSType, getUserHomeDir, OSType } from '../../../common/utils/platform'; import { getPythonSetting, isParentPath, pathExistsSync, readFileSync, shellExecute } from '../externalDependencies'; import { getEnvironmentDirFromPath } from '../commonUtils'; -import { isVirtualenvEnvironment } from './simplevirtualenvs'; +import { isVirtualenvEnvironment } from './simpleVirtualEnvs'; import { StopWatch } from '../../../common/utils/stopWatch'; import { cache } from '../../../common/utils/decorators'; import { isTestExecution } from '../../../common/constants'; diff --git a/src/client/pythonEnvironments/common/environmentManagers/windowsStoreEnv.ts b/src/client/pythonEnvironments/common/environmentManagers/windowsStoreEnv.ts new file mode 100644 index 000000000000..098cb75eb6eb --- /dev/null +++ b/src/client/pythonEnvironments/common/environmentManagers/windowsStoreEnv.ts @@ -0,0 +1,122 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +import * as path from 'path'; +import { traceWarning } from '../../../common/logger'; +import { getEnvironmentVariable } from '../../../common/utils/platform'; +import { pathExists } from '../externalDependencies'; + +/** + * Gets path to the Windows Apps directory. + * @returns {string} : Returns path to the Windows Apps directory under + * `%LOCALAPPDATA%/Microsoft/WindowsApps`. + */ +export function getWindowsStoreAppsRoot(): string { + const localAppData = getEnvironmentVariable('LOCALAPPDATA') || ''; + return path.join(localAppData, 'Microsoft', 'WindowsApps'); +} +/** + * Checks if a given path is under the forbidden windows store directory. + * @param {string} absPath : Absolute path to a file or directory. + * @returns {boolean} : Returns true if `interpreterPath` is under + * `%ProgramFiles%/WindowsApps`. + */ +function isForbiddenStorePath(absPath: string): boolean { + const programFilesStorePath = path + .join(getEnvironmentVariable('ProgramFiles') || 'Program Files', 'WindowsApps') + .normalize() + .toUpperCase(); + return path.normalize(absPath).toUpperCase().includes(programFilesStorePath); +} +/** + * Checks if a given directory is any one of the possible windows store directories, or + * its sub-directory. + * @param {string} dirPath : Absolute path to a directory. + * + * Remarks: + * These locations are tested: + * 1. %LOCALAPPDATA%/Microsoft/WindowsApps + * 2. %ProgramFiles%/WindowsApps + */ + +export function isWindowsStoreDir(dirPath: string): boolean { + const storeRootPath = path.normalize(getWindowsStoreAppsRoot()).toUpperCase(); + return path.normalize(dirPath).toUpperCase().includes(storeRootPath) || isForbiddenStorePath(dirPath); +} +/** + * Checks if store python is installed. + * @param {string} interpreterPath : Absolute path to a interpreter. + * Remarks: + * If store python was never installed then the store apps directory will not + * have idle.exe or pip.exe. We can use this as a way to identify the python.exe + * found in the store apps directory is a real python or a store install shortcut. + */ +export async function isStorePythonInstalled(interpreterPath?: string): Promise { + let results = await Promise.all([ + pathExists(path.join(getWindowsStoreAppsRoot(), 'idle.exe')), + pathExists(path.join(getWindowsStoreAppsRoot(), 'pip.exe')), + ]); + + if (results.includes(true)) { + return true; + } + + if (interpreterPath) { + results = await Promise.all([ + pathExists(path.join(path.dirname(interpreterPath), 'idle.exe')), + pathExists(path.join(path.dirname(interpreterPath), 'pip.exe')), + ]); + return results.includes(true); + } + return false; +} +/** + * Checks if the given interpreter belongs to Windows Store Python environment. + * @param interpreterPath: Absolute path to any python interpreter. + * + * Remarks: + * 1. Checking if the path includes `Microsoft\WindowsApps`, `Program Files\WindowsApps`, is + * NOT enough. In WSL, `/mnt/c/users/user/AppData/Local/Microsoft/WindowsApps` is available as a search + * path. It is possible to get a false positive for that path. So the comparison should check if the + * absolute path to 'WindowsApps' directory is present in the given interpreter path. The WSL path to + * 'WindowsApps' is not a valid path to access, Windows Store Python. + * + * 2. 'startsWith' comparison may not be right, user can provide '\\?\C:\users\' style long paths in windows. + * + * 3. A limitation of the checks here is that they don't handle 8.3 style windows paths. + * For example, + * `C:\Users\USER\AppData\Local\MICROS~1\WINDOW~1\PYTHON~2.EXE` + * is the shortened form of + * `C:\Users\USER\AppData\Local\Microsoft\WindowsApps\python3.7.exe` + * + * The correct way to compare these would be to always convert given paths to long path (or to short path). + * For either approach to work correctly you need actual file to exist, and accessible from the user's + * account. + * + * To convert to short path without using N-API in node would be to use this command. This is very expensive: + * `> cmd /c for %A in ("C:\Users\USER\AppData\Local\Microsoft\WindowsApps\python3.7.exe") do @echo %~sA` + * The above command will print out this: + * `C:\Users\USER\AppData\Local\MICROS~1\WINDOW~1\PYTHON~2.EXE` + * + * If we go down the N-API route, use node-ffi and either call GetShortPathNameW or GetLongPathNameW from, + * Kernel32 to convert between the two path variants. + * + */ + +export async function isWindowsStoreEnvironment(interpreterPath: string): Promise { + if (await isStorePythonInstalled(interpreterPath)) { + const pythonPathToCompare = path.normalize(interpreterPath).toUpperCase(); + const localAppDataStorePath = path.normalize(getWindowsStoreAppsRoot()).toUpperCase(); + if (pythonPathToCompare.includes(localAppDataStorePath)) { + return true; + } + + // Program Files store path is a forbidden path. Only admins and system has access this path. + // We should never have to look at this path or even execute python from this path. + if (isForbiddenStorePath(pythonPathToCompare)) { + traceWarning('isWindowsStoreEnvironment called with Program Files store path.'); + return true; + } + } + return false; +} diff --git a/src/client/pythonEnvironments/legacyIOC.ts b/src/client/pythonEnvironments/legacyIOC.ts index 38f9231229d3..fffda08be543 100644 --- a/src/client/pythonEnvironments/legacyIOC.ts +++ b/src/client/pythonEnvironments/legacyIOC.ts @@ -57,7 +57,7 @@ import { KnownPathsService, KnownSearchPathsForInterpreters } from './discovery/ import { PipEnvService } from './discovery/locators/services/pipEnvService'; import { PipEnvServiceHelper } from './discovery/locators/services/pipEnvServiceHelper'; import { WindowsRegistryService } from './discovery/locators/services/windowsRegistryService'; -import { isWindowsStoreEnvironment } from './base/locators/lowLevel/windowsStoreLocator'; +import { isWindowsStoreEnvironment } from './common/environmentManagers/windowsStoreEnv'; import { WorkspaceVirtualEnvironmentsSearchPathProvider, WorkspaceVirtualEnvService, diff --git a/src/test/pythonEnvironments/discovery/locators/virtualEnvironmentIdentifier.unit.test.ts b/src/test/pythonEnvironments/discovery/locators/virtualEnvironmentIdentifier.unit.test.ts index 5c32870988c2..6d6c9c6520c0 100644 --- a/src/test/pythonEnvironments/discovery/locators/virtualEnvironmentIdentifier.unit.test.ts +++ b/src/test/pythonEnvironments/discovery/locators/virtualEnvironmentIdentifier.unit.test.ts @@ -14,7 +14,7 @@ import { isVenvEnvironment, isVirtualenvEnvironment, isVirtualenvwrapperEnvironment, -} from '../../../../client/pythonEnvironments/common/environmentManagers/simplevirtualenvs'; +} from '../../../../client/pythonEnvironments/common/environmentManagers/simpleVirtualEnvs'; import { TEST_DATA_ROOT, TEST_LAYOUT_ROOT } from '../../common/commonTestConstants'; import { assertVersionsEqual } from './envTestUtils'; diff --git a/src/test/pythonEnvironments/discovery/locators/windowsStoreLocator.unit.test.ts b/src/test/pythonEnvironments/discovery/locators/windowsStoreLocator.unit.test.ts index aab4a5df740e..bcb06940b510 100644 --- a/src/test/pythonEnvironments/discovery/locators/windowsStoreLocator.unit.test.ts +++ b/src/test/pythonEnvironments/discovery/locators/windowsStoreLocator.unit.test.ts @@ -12,9 +12,9 @@ import { BasicEnvInfo } from '../../../../client/pythonEnvironments/base/locator import * as externalDep from '../../../../client/pythonEnvironments/common/externalDependencies'; import { getWindowsStorePythonExes, - isWindowsStoreDir, WindowsStoreLocator, } from '../../../../client/pythonEnvironments/base/locators/lowLevel/windowsStoreLocator'; +import { isWindowsStoreDir } from '../../../../client/pythonEnvironments/common/environmentManagers/windowsStoreEnv'; import { getEnvs } from '../../base/common'; import { TEST_LAYOUT_ROOT } from '../../common/commonTestConstants'; import { assertBasicEnvsEqual } from './envTestUtils'; From 64b4d2a0a9e535a07c7324b04411b6f887c112ea Mon Sep 17 00:00:00 2001 From: Kartik Raj Date: Fri, 16 Jul 2021 17:16:42 -0700 Subject: [PATCH 17/19] Refactor new discovery code from index.ts and move it --- .../pythonEnvironments/base/locators/index.ts | 138 ++++++++++++++++++ .../discovery/locators/index.ts | 136 +---------------- src/client/pythonEnvironments/index.ts | 2 +- .../discovery/locators/index.unit.test.ts | 7 +- 4 files changed, 142 insertions(+), 141 deletions(-) create mode 100644 src/client/pythonEnvironments/base/locators/index.ts diff --git a/src/client/pythonEnvironments/base/locators/index.ts b/src/client/pythonEnvironments/base/locators/index.ts new file mode 100644 index 000000000000..744444bf8338 --- /dev/null +++ b/src/client/pythonEnvironments/base/locators/index.ts @@ -0,0 +1,138 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// eslint-disable-next-line max-classes-per-file +import { Uri } from 'vscode'; +import { iterEmpty } from '../../../common/utils/async'; +import { getURIFilter } from '../../../common/utils/misc'; +import { Disposables, IDisposable } from '../../../common/utils/resourceLifecycle'; +import { PythonEnvInfo } from '../info'; +import { ILocator, IPythonEnvsIterator, PythonLocatorQuery } from '../locator'; +import { combineIterators, Locators } from '../locators'; +import { LazyResourceBasedLocator } from './common/resourceBasedLocator'; + +/** + * A wrapper around all locators used by the extension. + */ + +export class ExtensionLocators extends Locators { + constructor( + // These are expected to be low-level locators (e.g. system). + nonWorkspace: ILocator[], + // This is expected to be a locator wrapping any found in + // the workspace (i.e. WorkspaceLocators). + workspace: ILocator, + ) { + super([...nonWorkspace, workspace]); + } +} +type WorkspaceLocatorFactoryResult = ILocator & Partial; +type WorkspaceLocatorFactory = (root: Uri) => WorkspaceLocatorFactoryResult[]; +type RootURI = string; + +export type WatchRootsArgs = { + initRoot(root: Uri): void; + addRoot(root: Uri): void; + removeRoot(root: Uri): void; +}; +type WatchRootsFunc = (args: WatchRootsArgs) => IDisposable; +// XXX Factor out RootedLocators and MultiRootedLocators. +/** + * The collection of all workspace-specific locators used by the extension. + * + * The factories are used to produce the locators for each workspace folder. + */ + +export class WorkspaceLocators extends LazyResourceBasedLocator { + private readonly locators: Record, IDisposable]> = {}; + + private readonly roots: Record = {}; + + constructor(private readonly watchRoots: WatchRootsFunc, private readonly factories: WorkspaceLocatorFactory[]) { + super(); + } + + public async dispose(): Promise { + await super.dispose(); + + // Clear all the roots. + const roots = Object.keys(this.roots).map((key) => this.roots[key]); + roots.forEach((root) => this.removeRoot(root)); + } + + protected doIterEnvs(query?: PythonLocatorQuery): IPythonEnvsIterator { + const iterators = Object.keys(this.locators).map((key) => { + if (query?.searchLocations !== undefined) { + const root = this.roots[key]; + // Match any related search location. + const filter = getURIFilter(root, { checkParent: true, checkChild: true, checkExact: true }); + // Ignore any requests for global envs. + if (!query.searchLocations.roots.some(filter)) { + // This workspace folder did not match the query, so skip it! + return iterEmpty(); + } + } + // The query matches or was not location-specific. + const [locator] = this.locators[key]; + return locator.iterEnvs(query); + }); + return combineIterators(iterators); + } + + protected async initResources(): Promise { + const disposable = this.watchRoots({ + initRoot: (root: Uri) => this.addRoot(root), + addRoot: (root: Uri) => { + // Drop the old one, if necessary. + this.removeRoot(root); + this.addRoot(root); + this.emitter.fire({ searchLocation: root }); + }, + removeRoot: (root: Uri) => { + this.removeRoot(root); + this.emitter.fire({ searchLocation: root }); + }, + }); + this.disposables.push(disposable); + } + + private addRoot(root: Uri): void { + // Create the root's locator, wrapping each factory-generated locator. + const locators: ILocator[] = []; + const disposables = new Disposables(); + this.factories.forEach((create) => { + create(root).forEach((loc) => { + locators.push(loc); + if (loc.dispose !== undefined) { + disposables.push(loc as IDisposable); + } + }); + }); + const locator = new Locators(locators); + // Cache it. + const key = root.toString(); + this.locators[key] = [locator, disposables]; + this.roots[key] = root; + // Hook up the watchers. + disposables.push( + locator.onChanged((e) => { + if (e.searchLocation === undefined) { + e.searchLocation = root; + } + this.emitter.fire(e); + }), + ); + } + + private removeRoot(root: Uri): void { + const key = root.toString(); + const found = this.locators[key]; + if (found === undefined) { + return; + } + const [, disposables] = found; + delete this.locators[key]; + delete this.roots[key]; + disposables.dispose(); + } +} diff --git a/src/client/pythonEnvironments/discovery/locators/index.ts b/src/client/pythonEnvironments/discovery/locators/index.ts index 824d7dfaf8bc..4038ddc39a6a 100644 --- a/src/client/pythonEnvironments/discovery/locators/index.ts +++ b/src/client/pythonEnvironments/discovery/locators/index.ts @@ -6,10 +6,8 @@ import { Disposable, Event, EventEmitter, Uri } from 'vscode'; import { traceDecorators } from '../../../common/logger'; import { IPlatformService } from '../../../common/platform/types'; import { IDisposableRegistry } from '../../../common/types'; -import { createDeferred, Deferred, iterEmpty } from '../../../common/utils/async'; -import { getURIFilter } from '../../../common/utils/misc'; +import { createDeferred, Deferred } from '../../../common/utils/async'; import { OSType } from '../../../common/utils/platform'; -import { Disposables, IDisposable } from '../../../common/utils/resourceLifecycle'; import { CONDA_ENV_FILE_SERVICE, CONDA_ENV_SERVICE, @@ -24,141 +22,9 @@ import { WORKSPACE_VIRTUAL_ENV_SERVICE, } from '../../../interpreter/contracts'; import { IServiceContainer } from '../../../ioc/types'; -import { PythonEnvInfo } from '../../base/info'; -import { ILocator, IPythonEnvsIterator, PythonLocatorQuery } from '../../base/locator'; -import { combineIterators, Locators } from '../../base/locators'; -import { LazyResourceBasedLocator } from '../../base/locators/common/resourceBasedLocator'; import { PythonEnvironment } from '../../info'; import { isHiddenInterpreter } from './services/interpreterFilter'; -/** - * A wrapper around all locators used by the extension. - */ -export class ExtensionLocators extends Locators { - constructor( - // These are expected to be low-level locators (e.g. system). - nonWorkspace: ILocator[], - // This is expected to be a locator wrapping any found in - // the workspace (i.e. WorkspaceLocators). - workspace: ILocator, - ) { - super([...nonWorkspace, workspace]); - } -} - -type WorkspaceLocatorFactoryResult = ILocator & Partial; -type WorkspaceLocatorFactory = (root: Uri) => WorkspaceLocatorFactoryResult[]; - -type RootURI = string; - -export type WatchRootsArgs = { - initRoot(root: Uri): void; - addRoot(root: Uri): void; - removeRoot(root: Uri): void; -}; -type WatchRootsFunc = (args: WatchRootsArgs) => IDisposable; - -// XXX Factor out RootedLocators and MultiRootedLocators. - -/** - * The collection of all workspace-specific locators used by the extension. - * - * The factories are used to produce the locators for each workspace folder. - */ -export class WorkspaceLocators extends LazyResourceBasedLocator { - private readonly locators: Record, IDisposable]> = {}; - - private readonly roots: Record = {}; - - constructor(private readonly watchRoots: WatchRootsFunc, private readonly factories: WorkspaceLocatorFactory[]) { - super(); - } - - public async dispose(): Promise { - await super.dispose(); - - // Clear all the roots. - const roots = Object.keys(this.roots).map((key) => this.roots[key]); - roots.forEach((root) => this.removeRoot(root)); - } - - protected doIterEnvs(query?: PythonLocatorQuery): IPythonEnvsIterator { - const iterators = Object.keys(this.locators).map((key) => { - if (query?.searchLocations !== undefined) { - const root = this.roots[key]; - // Match any related search location. - const filter = getURIFilter(root, { checkParent: true, checkChild: true, checkExact: true }); - // Ignore any requests for global envs. - if (!query.searchLocations.roots.some(filter)) { - // This workspace folder did not match the query, so skip it! - return iterEmpty(); - } - } - // The query matches or was not location-specific. - const [locator] = this.locators[key]; - return locator.iterEnvs(query); - }); - return combineIterators(iterators); - } - - protected async initResources(): Promise { - const disposable = this.watchRoots({ - initRoot: (root: Uri) => this.addRoot(root), - addRoot: (root: Uri) => { - // Drop the old one, if necessary. - this.removeRoot(root); - this.addRoot(root); - this.emitter.fire({ searchLocation: root }); - }, - removeRoot: (root: Uri) => { - this.removeRoot(root); - this.emitter.fire({ searchLocation: root }); - }, - }); - this.disposables.push(disposable); - } - - private addRoot(root: Uri): void { - // Create the root's locator, wrapping each factory-generated locator. - const locators: ILocator[] = []; - const disposables = new Disposables(); - this.factories.forEach((create) => { - create(root).forEach((loc) => { - locators.push(loc); - if (loc.dispose !== undefined) { - disposables.push(loc as IDisposable); - } - }); - }); - const locator = new Locators(locators); - // Cache it. - const key = root.toString(); - this.locators[key] = [locator, disposables]; - this.roots[key] = root; - // Hook up the watchers. - disposables.push( - locator.onChanged((e) => { - if (e.searchLocation === undefined) { - e.searchLocation = root; - } - this.emitter.fire(e); - }), - ); - } - - private removeRoot(root: Uri): void { - const key = root.toString(); - const found = this.locators[key]; - if (found === undefined) { - return; - } - const [, disposables] = found; - delete this.locators[key]; - delete this.roots[key]; - disposables.dispose(); - } -} - /** * Facilitates locating Python interpreters. */ diff --git a/src/client/pythonEnvironments/index.ts b/src/client/pythonEnvironments/index.ts index 5b197a9e0714..5642ebe88ed3 100644 --- a/src/client/pythonEnvironments/index.ts +++ b/src/client/pythonEnvironments/index.ts @@ -17,7 +17,7 @@ import { WindowsPathEnvVarLocator } from './base/locators/lowLevel/windowsKnownP import { WorkspaceVirtualEnvironmentLocator } from './base/locators/lowLevel/workspaceVirtualEnvLocator'; import { getEnvs } from './base/locatorUtils'; import { initializeExternalDependencies as initializeLegacyExternalDependencies } from './common/externalDependencies'; -import { ExtensionLocators, WatchRootsArgs, WorkspaceLocators } from './discovery/locators'; +import { ExtensionLocators, WatchRootsArgs, WorkspaceLocators } from './base/locators/'; import { CustomVirtualEnvironmentLocator } from './base/locators/lowLevel/customVirtualEnvLocator'; import { CondaEnvironmentLocator } from './base/locators/lowLevel/condaLocator'; import { GlobalVirtualEnvironmentLocator } from './base/locators/lowLevel/globalVirtualEnvronmentLocator'; diff --git a/src/test/pythonEnvironments/discovery/locators/index.unit.test.ts b/src/test/pythonEnvironments/discovery/locators/index.unit.test.ts index 81abb89ff3ac..e0627126e598 100644 --- a/src/test/pythonEnvironments/discovery/locators/index.unit.test.ts +++ b/src/test/pythonEnvironments/discovery/locators/index.unit.test.ts @@ -28,11 +28,8 @@ import { import { IServiceContainer } from '../../../../client/ioc/types'; import { PythonEnvInfo, PythonEnvKind } from '../../../../client/pythonEnvironments/base/info'; import { PythonEnvsChangedEvent } from '../../../../client/pythonEnvironments/base/watcher'; -import { - PythonInterpreterLocatorService, - WatchRootsArgs, - WorkspaceLocators, -} from '../../../../client/pythonEnvironments/discovery/locators'; +import { PythonInterpreterLocatorService } from '../../../../client/pythonEnvironments/discovery/locators'; +import { WatchRootsArgs, WorkspaceLocators } from '../../../../client/pythonEnvironments/base/locators/'; import { EnvironmentType, PythonEnvironment } from '../../../../client/pythonEnvironments/info'; import { assertSameEnvs, createLocatedEnv, createNamedEnv, getEnvs, SimpleLocator } from '../../base/common'; From be1a930f45139458c2b27ea83e8cb0a1920c7d20 Mon Sep 17 00:00:00 2001 From: Kartik Raj Date: Fri, 16 Jul 2021 17:28:08 -0700 Subject: [PATCH 18/19] Remove environmentInfoService.ts Rename --- .../{ => base}/info/environmentInfoService.ts | 12 ++++++------ .../base/locators/composite/environmentsResolver.ts | 2 +- .../locators/lowLevel/customVirtualEnvLocator.ts | 2 +- .../lowLevel/globalVirtualEnvronmentLocator.ts | 2 +- .../locators/lowLevel/workspaceVirtualEnvLocator.ts | 2 +- src/client/pythonEnvironments/common/commonUtils.ts | 2 +- .../common/environmentIdentifier.ts | 2 +- .../common/environmentManagers/poetry.ts | 2 +- src/client/pythonEnvironments/index.ts | 2 +- src/client/pythonEnvironments/legacyIOC.ts | 2 +- .../composite/environmentsResolver.unit.test.ts | 2 +- .../virtualEnvironmentIdentifier.unit.test.ts | 2 +- .../info/environmentInfoService.functional.test.ts | 2 +- 13 files changed, 18 insertions(+), 18 deletions(-) rename src/client/pythonEnvironments/{ => base}/info/environmentInfoService.ts (90%) diff --git a/src/client/pythonEnvironments/info/environmentInfoService.ts b/src/client/pythonEnvironments/base/info/environmentInfoService.ts similarity index 90% rename from src/client/pythonEnvironments/info/environmentInfoService.ts rename to src/client/pythonEnvironments/base/info/environmentInfoService.ts index ad793f4ecaa7..490a556a50ba 100644 --- a/src/client/pythonEnvironments/info/environmentInfoService.ts +++ b/src/client/pythonEnvironments/base/info/environmentInfoService.ts @@ -1,12 +1,12 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -import { traceVerbose } from '../../common/logger'; -import { IDisposableRegistry } from '../../common/types'; -import { createDeferred, Deferred } from '../../common/utils/async'; -import { createRunningWorkerPool, IWorkerPool, QueuePosition } from '../../common/utils/workerPool'; -import { getInterpreterInfo, InterpreterInformation } from '../base/info/interpreter'; -import { buildPythonExecInfo } from '../exec'; +import { traceVerbose } from '../../../common/logger'; +import { IDisposableRegistry } from '../../../common/types'; +import { createDeferred, Deferred } from '../../../common/utils/async'; +import { createRunningWorkerPool, IWorkerPool, QueuePosition } from '../../../common/utils/workerPool'; +import { getInterpreterInfo, InterpreterInformation } from './interpreter'; +import { buildPythonExecInfo } from '../../exec'; export enum EnvironmentInfoServiceQueuePriority { Default, diff --git a/src/client/pythonEnvironments/base/locators/composite/environmentsResolver.ts b/src/client/pythonEnvironments/base/locators/composite/environmentsResolver.ts index 4ed6e2d31285..17fe292b644f 100644 --- a/src/client/pythonEnvironments/base/locators/composite/environmentsResolver.ts +++ b/src/client/pythonEnvironments/base/locators/composite/environmentsResolver.ts @@ -5,7 +5,7 @@ import { cloneDeep } from 'lodash'; import { Event, EventEmitter } from 'vscode'; import { traceVerbose } from '../../../../common/logger'; import { identifyEnvironment } from '../../../common/environmentIdentifier'; -import { IEnvironmentInfoService } from '../../../info/environmentInfoService'; +import { IEnvironmentInfoService } from '../../info/environmentInfoService'; import { PythonEnvInfo } from '../../info'; import { getEnvDisplayString } from '../../info/env'; import { InterpreterInformation } from '../../info/interpreter'; diff --git a/src/client/pythonEnvironments/base/locators/lowLevel/customVirtualEnvLocator.ts b/src/client/pythonEnvironments/base/locators/lowLevel/customVirtualEnvLocator.ts index a440d048c831..dcdc9aaa0685 100644 --- a/src/client/pythonEnvironments/base/locators/lowLevel/customVirtualEnvLocator.ts +++ b/src/client/pythonEnvironments/base/locators/lowLevel/customVirtualEnvLocator.ts @@ -21,7 +21,7 @@ import { isVenvEnvironment, isVirtualenvEnvironment, isVirtualenvwrapperEnvironment, -} from '../../../common/environmentManagers/simpleVirtualEnvs'; +} from '../../../common/environmentManagers/simplevirtualenvs'; import '../../../../common/extensions'; import { asyncFilter } from '../../../../common/utils/arrayUtils'; /** diff --git a/src/client/pythonEnvironments/base/locators/lowLevel/globalVirtualEnvronmentLocator.ts b/src/client/pythonEnvironments/base/locators/lowLevel/globalVirtualEnvronmentLocator.ts index 27c34ad76c60..2e17639dcb3a 100644 --- a/src/client/pythonEnvironments/base/locators/lowLevel/globalVirtualEnvronmentLocator.ts +++ b/src/client/pythonEnvironments/base/locators/lowLevel/globalVirtualEnvronmentLocator.ts @@ -16,7 +16,7 @@ import { isVenvEnvironment, isVirtualenvEnvironment, isVirtualenvwrapperEnvironment, -} from '../../../common/environmentManagers/simpleVirtualEnvs'; +} from '../../../common/environmentManagers/simplevirtualenvs'; import '../../../../common/extensions'; import { asyncFilter } from '../../../../common/utils/arrayUtils'; diff --git a/src/client/pythonEnvironments/base/locators/lowLevel/workspaceVirtualEnvLocator.ts b/src/client/pythonEnvironments/base/locators/lowLevel/workspaceVirtualEnvLocator.ts index e101ce20e3bf..0b0e60dd94d0 100644 --- a/src/client/pythonEnvironments/base/locators/lowLevel/workspaceVirtualEnvLocator.ts +++ b/src/client/pythonEnvironments/base/locators/lowLevel/workspaceVirtualEnvLocator.ts @@ -7,7 +7,7 @@ import { chain, iterable } from '../../../../common/utils/async'; import { findInterpretersInDir, looksLikeBasicVirtualPython } from '../../../common/commonUtils'; import { pathExists } from '../../../common/externalDependencies'; import { isPipenvEnvironment } from '../../../common/environmentManagers/pipenv'; -import { isVenvEnvironment, isVirtualenvEnvironment } from '../../../common/environmentManagers/simpleVirtualEnvs'; +import { isVenvEnvironment, isVirtualenvEnvironment } from '../../../common/environmentManagers/simplevirtualenvs'; import { PythonEnvKind } from '../../info'; import { BasicEnvInfo, IPythonEnvsIterator } from '../../locator'; import { FSWatchingLocator } from './fsWatchingLocator'; diff --git a/src/client/pythonEnvironments/common/commonUtils.ts b/src/client/pythonEnvironments/common/commonUtils.ts index b9d63ab851fc..f6b5ae810542 100644 --- a/src/client/pythonEnvironments/common/commonUtils.ts +++ b/src/client/pythonEnvironments/common/commonUtils.ts @@ -10,7 +10,7 @@ import { PythonVersion, UNKNOWN_PYTHON_VERSION } from '../base/info'; import { comparePythonVersionSpecificity } from '../base/info/env'; import { parseVersion } from '../base/info/pythonVersion'; import { getPythonVersionFromConda } from './environmentManagers/conda'; -import { getPythonVersionFromPyvenvCfg } from './environmentManagers/simpleVirtualEnvs'; +import { getPythonVersionFromPyvenvCfg } from './environmentManagers/simplevirtualenvs'; import * as posix from './posixUtils'; import * as windows from './windowsUtils'; diff --git a/src/client/pythonEnvironments/common/environmentIdentifier.ts b/src/client/pythonEnvironments/common/environmentIdentifier.ts index e9b40de86afb..0dcdbd37e68c 100644 --- a/src/client/pythonEnvironments/common/environmentIdentifier.ts +++ b/src/client/pythonEnvironments/common/environmentIdentifier.ts @@ -11,7 +11,7 @@ import { isVenvEnvironment, isVirtualenvEnvironment as isVirtualEnvEnvironment, isVirtualenvwrapperEnvironment as isVirtualEnvWrapperEnvironment, -} from './environmentManagers/simpleVirtualEnvs'; +} from './environmentManagers/simplevirtualenvs'; import { isWindowsStoreEnvironment } from './environmentManagers/windowsStoreEnv'; function getIdentifiers(): Map Promise> { diff --git a/src/client/pythonEnvironments/common/environmentManagers/poetry.ts b/src/client/pythonEnvironments/common/environmentManagers/poetry.ts index a4a3bfa8fb89..eb52c5b653d5 100644 --- a/src/client/pythonEnvironments/common/environmentManagers/poetry.ts +++ b/src/client/pythonEnvironments/common/environmentManagers/poetry.ts @@ -8,7 +8,7 @@ import { traceError, traceVerbose } from '../../../common/logger'; import { getOSType, getUserHomeDir, OSType } from '../../../common/utils/platform'; import { getPythonSetting, isParentPath, pathExistsSync, readFileSync, shellExecute } from '../externalDependencies'; import { getEnvironmentDirFromPath } from '../commonUtils'; -import { isVirtualenvEnvironment } from './simpleVirtualEnvs'; +import { isVirtualenvEnvironment } from './simplevirtualenvs'; import { StopWatch } from '../../../common/utils/stopWatch'; import { cache } from '../../../common/utils/decorators'; import { isTestExecution } from '../../../common/constants'; diff --git a/src/client/pythonEnvironments/index.ts b/src/client/pythonEnvironments/index.ts index 5642ebe88ed3..a31bbc7af3d9 100644 --- a/src/client/pythonEnvironments/index.ts +++ b/src/client/pythonEnvironments/index.ts @@ -25,7 +25,7 @@ import { PosixKnownPathsLocator } from './base/locators/lowLevel/posixKnownPaths import { PyenvLocator } from './base/locators/lowLevel/pyenvLocator'; import { WindowsRegistryLocator } from './base/locators/lowLevel/windowsRegistryLocator'; import { WindowsStoreLocator } from './base/locators/lowLevel/windowsStoreLocator'; -import { getEnvironmentInfoService } from './info/environmentInfoService'; +import { getEnvironmentInfoService } from './base/info/environmentInfoService'; import { isComponentEnabled, registerLegacyDiscoveryForIOC, registerNewDiscoveryForIOC } from './legacyIOC'; import { PoetryLocator } from './base/locators/lowLevel/poetryLocator'; diff --git a/src/client/pythonEnvironments/legacyIOC.ts b/src/client/pythonEnvironments/legacyIOC.ts index fffda08be543..5ecde18f2889 100644 --- a/src/client/pythonEnvironments/legacyIOC.ts +++ b/src/client/pythonEnvironments/legacyIOC.ts @@ -67,7 +67,7 @@ import { EnvironmentType, PythonEnvironment } from './info'; import { toSemverLikeVersion } from './base/info/pythonVersion'; import { PythonVersion } from './info/pythonVersion'; import { IExtensionSingleActivationService } from '../activation/types'; -import { EnvironmentInfoServiceQueuePriority, getEnvironmentInfoService } from './info/environmentInfoService'; +import { EnvironmentInfoServiceQueuePriority, getEnvironmentInfoService } from './base/info/environmentInfoService'; const convertedKinds = new Map( Object.entries({ diff --git a/src/test/pythonEnvironments/base/locators/composite/environmentsResolver.unit.test.ts b/src/test/pythonEnvironments/base/locators/composite/environmentsResolver.unit.test.ts index ae8db581ca06..3b14d339514f 100644 --- a/src/test/pythonEnvironments/base/locators/composite/environmentsResolver.unit.test.ts +++ b/src/test/pythonEnvironments/base/locators/composite/environmentsResolver.unit.test.ts @@ -25,7 +25,7 @@ import * as externalDependencies from '../../../../../client/pythonEnvironments/ import { getEnvironmentInfoService, IEnvironmentInfoService, -} from '../../../../../client/pythonEnvironments/info/environmentInfoService'; +} from '../../../../../client/pythonEnvironments/base/info/environmentInfoService'; import { TEST_LAYOUT_ROOT } from '../../../common/commonTestConstants'; import { assertEnvEqual, assertEnvsEqual } from '../../../discovery/locators/envTestUtils'; import { createBasicEnv, getEnvs, getEnvsWithUpdates, SimpleLocator } from '../../common'; diff --git a/src/test/pythonEnvironments/discovery/locators/virtualEnvironmentIdentifier.unit.test.ts b/src/test/pythonEnvironments/discovery/locators/virtualEnvironmentIdentifier.unit.test.ts index 6d6c9c6520c0..5c32870988c2 100644 --- a/src/test/pythonEnvironments/discovery/locators/virtualEnvironmentIdentifier.unit.test.ts +++ b/src/test/pythonEnvironments/discovery/locators/virtualEnvironmentIdentifier.unit.test.ts @@ -14,7 +14,7 @@ import { isVenvEnvironment, isVirtualenvEnvironment, isVirtualenvwrapperEnvironment, -} from '../../../../client/pythonEnvironments/common/environmentManagers/simpleVirtualEnvs'; +} from '../../../../client/pythonEnvironments/common/environmentManagers/simplevirtualenvs'; import { TEST_DATA_ROOT, TEST_LAYOUT_ROOT } from '../../common/commonTestConstants'; import { assertVersionsEqual } from './envTestUtils'; diff --git a/src/test/pythonEnvironments/info/environmentInfoService.functional.test.ts b/src/test/pythonEnvironments/info/environmentInfoService.functional.test.ts index fc8e2482978f..9b76b62ce1ab 100644 --- a/src/test/pythonEnvironments/info/environmentInfoService.functional.test.ts +++ b/src/test/pythonEnvironments/info/environmentInfoService.functional.test.ts @@ -15,7 +15,7 @@ import * as ExternalDep from '../../../client/pythonEnvironments/common/external import { EnvironmentInfoServiceQueuePriority, getEnvironmentInfoService, -} from '../../../client/pythonEnvironments/info/environmentInfoService'; +} from '../../../client/pythonEnvironments/base/info/environmentInfoService'; suite('Environment Info Service', () => { let stubShellExec: sinon.SinonStub; From a17dc9c78f5096529fe172b647ff6e365177adfd Mon Sep 17 00:00:00 2001 From: Kartik Raj Date: Tue, 20 Jul 2021 16:14:41 -0700 Subject: [PATCH 19/19] Remove unnecessary async signatures in pyenv --- .../base/locators/composite/resolverUtils.ts | 2 +- .../common/environmentManagers/pyenv.ts | 54 +++++++++---------- .../locators/pyenvLocator.unit.test.ts | 2 +- 3 files changed, 29 insertions(+), 29 deletions(-) diff --git a/src/client/pythonEnvironments/base/locators/composite/resolverUtils.ts b/src/client/pythonEnvironments/base/locators/composite/resolverUtils.ts index 69ca1f7c7003..6b63a3a7756f 100644 --- a/src/client/pythonEnvironments/base/locators/composite/resolverUtils.ts +++ b/src/client/pythonEnvironments/base/locators/composite/resolverUtils.ts @@ -169,7 +169,7 @@ async function resolvePyenvEnv(executablePath: string): Promise { // The sub-directory name sometimes can contain distro and python versions. // here we attempt to extract the texts out of the name. - const versionStrings = await parsePyenvVersion(name); + const versionStrings = parsePyenvVersion(name); const envInfo = buildEnvInfo({ kind: PythonEnvKind.Pyenv, diff --git a/src/client/pythonEnvironments/common/environmentManagers/pyenv.ts b/src/client/pythonEnvironments/common/environmentManagers/pyenv.ts index 52c219ff8535..e4aa47e7154f 100644 --- a/src/client/pythonEnvironments/common/environmentManagers/pyenv.ts +++ b/src/client/pythonEnvironments/common/environmentManagers/pyenv.ts @@ -68,7 +68,7 @@ export interface IPyenvVersionStrings { * * The parsers below were written based on the list obtained from pyenv version 1.2.21 */ -function getKnownPyenvVersionParsers(): Map Promise> { +function getKnownPyenvVersionParsers(): Map IPyenvVersionStrings | undefined> { /** * This function parses versions that are plain python versions. * @param str string to parse @@ -77,12 +77,12 @@ function getKnownPyenvVersionParsers(): Map Promise { - return Promise.resolve({ + function pythonOnly(str: string): IPyenvVersionStrings { + return { pythonVer: str, distro: undefined, distroVer: undefined, - }); + }; } /** @@ -93,29 +93,29 @@ function getKnownPyenvVersionParsers(): Map Promise { + function distroOnly(str: string): IPyenvVersionStrings | undefined { const parts = str.split('-'); if (parts.length === 3) { - return Promise.resolve({ + return { pythonVer: undefined, distroVer: `${parts[1]}-${parts[2]}`, distro: parts[0], - }); + }; } if (parts.length === 2) { - return Promise.resolve({ + return { pythonVer: undefined, distroVer: parts[1], distro: parts[0], - }); + }; } - return Promise.resolve({ + return { pythonVer: undefined, distroVer: undefined, distro: str, - }); + }; } /** @@ -135,17 +135,17 @@ function getKnownPyenvVersionParsers(): Map Promise { + function pypyParser(str: string): IPyenvVersionStrings | undefined { const pattern = /[0-9\.]+/; const parts = str.split('-'); const pythonVer = parts[0].search(pattern) > 0 ? parts[0].substr('pypy'.length) : undefined; if (parts.length === 2) { - return Promise.resolve({ + return { pythonVer, distroVer: parts[1], distro: 'pypy', - }); + }; } if ( @@ -156,45 +156,45 @@ function getKnownPyenvVersionParsers(): Map Promise Promise> = new Map(); + const parsers: Map IPyenvVersionStrings | undefined> = new Map(); parsers.set('activepython', distroOnly); parsers.set('anaconda', distroOnly); parsers.set('graalpython', distroOnly); @@ -220,7 +220,7 @@ function getKnownPyenvVersionParsers(): Map Promise { +export function parsePyenvVersion(str: string): IPyenvVersionStrings | undefined { const allParsers = getKnownPyenvVersionParsers(); const knownPrefixes = Array.from(allParsers.keys()); @@ -233,5 +233,5 @@ export function parsePyenvVersion(str: string): Promise { testData.forEach((data) => { test(`Parse pyenv version [${data.input}]`, async () => { - assert.deepStrictEqual(await parsePyenvVersion(data.input), data.expectedOutput); + assert.deepStrictEqual(parsePyenvVersion(data.input), data.expectedOutput); }); }); });