From a592daf7925bfe7d3a932e86431189b7ce53f82a Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Tue, 4 Aug 2020 16:00:54 -0600 Subject: [PATCH] Revert "PyEnvs: Register proxies with the DI framework to replace @injectable usage. (#12795)" This reverts commit 3016ad86b34695e22969a744f120e66800bbf618. --- .../common/process/pythonExecutionFactory.ts | 3 +- .../pipEnvActivationProvider.ts | 13 +- src/client/interpreter/contracts.ts | 8 +- src/client/interpreter/helpers.ts | 3 +- src/client/interpreter/interpreterService.ts | 3 +- src/client/interpreter/locators/types.ts | 6 - src/client/interpreter/virtualEnvs/index.ts | 7 +- .../discovery/locators/helpers.ts | 6 +- .../discovery/locators/index.ts | 7 +- .../discovery/locators/progressService.ts | 7 +- .../locators/services/KnownPathsService.ts | 6 +- .../services/baseVirtualEnvService.ts | 10 +- .../services/cacheableLocatorService.ts | 8 +- .../locators/services/condaEnvFileService.ts | 3 +- .../locators/services/condaEnvService.ts | 3 +- .../locators/services/condaService.ts | 7 +- .../locators/services/currentPathService.ts | 6 +- .../services/globalVirtualEnvService.ts | 6 +- .../locators/services/hashProvider.ts | 6 +- .../locators/services/hashProviderFactory.ts | 15 +- .../services/interpreterWatcherBuilder.ts | 12 +- .../locators/services/pipEnvService.ts | 3 +- .../locators/services/pipEnvServiceHelper.ts | 4 +- .../services/windowsRegistryService.ts | 6 +- .../services/windowsStoreInterpreter.ts | 6 +- .../services/workspaceVirtualEnvService.ts | 6 +- .../workspaceVirtualEnvWatcherService.ts | 6 +- src/client/pythonEnvironments/legacyIOC.ts | 479 ++---------------- .../virtualEnvManager.unit.test.ts | 10 +- .../virtualEnvs/index.unit.test.ts | 6 +- .../locators/hasProviderFactory.unit.test.ts | 6 +- .../interpreterWatcherBuilder.unit.test.ts | 20 +- .../pythonEnvironments/legacyIOC.unit.test.ts | 106 ++++ .../testing/pytest/pytest.discovery.test.ts | 4 +- src/test/testing/pytest/pytest.run.test.ts | 4 +- 35 files changed, 267 insertions(+), 544 deletions(-) create mode 100644 src/test/pythonEnvironments/legacyIOC.unit.test.ts diff --git a/src/client/common/process/pythonExecutionFactory.ts b/src/client/common/process/pythonExecutionFactory.ts index 81a1bb89d968..3242070a8aab 100644 --- a/src/client/common/process/pythonExecutionFactory.ts +++ b/src/client/common/process/pythonExecutionFactory.ts @@ -10,6 +10,7 @@ import { ICondaService, IInterpreterService } from '../../interpreter/contracts' import { IWindowsStoreInterpreter } from '../../interpreter/locators/types'; import { IServiceContainer } from '../../ioc/types'; import { CondaEnvironmentInfo } from '../../pythonEnvironments/discovery/locators/services/conda'; +import { WindowsStoreInterpreter } from '../../pythonEnvironments/discovery/locators/services/windowsStoreInterpreter'; import { sendTelemetryEvent } from '../../telemetry'; import { EventName } from '../../telemetry/constants'; import { traceError } from '../logger'; @@ -50,7 +51,7 @@ export class PythonExecutionFactory implements IPythonExecutionFactory { @inject(IConfigurationService) private readonly configService: IConfigurationService, @inject(ICondaService) private readonly condaService: ICondaService, @inject(IBufferDecoder) private readonly decoder: IBufferDecoder, - @inject(IWindowsStoreInterpreter) private readonly windowsStoreInterpreter: IWindowsStoreInterpreter, + @inject(WindowsStoreInterpreter) private readonly windowsStoreInterpreter: IWindowsStoreInterpreter, @inject(IPlatformService) private readonly platformService: IPlatformService ) { // Acquire other objects here so that if we are called during dispose they are available. diff --git a/src/client/common/terminal/environmentActivationProviders/pipEnvActivationProvider.ts b/src/client/common/terminal/environmentActivationProviders/pipEnvActivationProvider.ts index f6ecf8c1b24a..be1f2bf9bd75 100644 --- a/src/client/common/terminal/environmentActivationProviders/pipEnvActivationProvider.ts +++ b/src/client/common/terminal/environmentActivationProviders/pipEnvActivationProvider.ts @@ -3,10 +3,15 @@ 'use strict'; -import { inject, injectable } from 'inversify'; +import { inject, injectable, named } from 'inversify'; import { Uri } from 'vscode'; import '../../../common/extensions'; -import { IInterpreterService, IPipEnvService } from '../../../interpreter/contracts'; +import { + IInterpreterLocatorService, + IInterpreterService, + IPipEnvService, + PIPENV_SERVICE +} from '../../../interpreter/contracts'; import { InterpreterType } from '../../../pythonEnvironments/info'; import { IWorkspaceService } from '../../application/types'; import { IFileSystem } from '../../platform/types'; @@ -16,7 +21,9 @@ import { ITerminalActivationCommandProvider, TerminalShellType } from '../types' export class PipEnvActivationCommandProvider implements ITerminalActivationCommandProvider { constructor( @inject(IInterpreterService) private readonly interpreterService: IInterpreterService, - @inject(IPipEnvService) private readonly pipenvService: IPipEnvService, + @inject(IInterpreterLocatorService) + @named(PIPENV_SERVICE) + private readonly pipenvService: IPipEnvService, @inject(IWorkspaceService) private readonly workspaceService: IWorkspaceService, @inject(IFileSystem) private readonly fs: IFileSystem ) {} diff --git a/src/client/interpreter/contracts.ts b/src/client/interpreter/contracts.ts index c2ab3dfc6ff6..cfa9cd6884a9 100644 --- a/src/client/interpreter/contracts.ts +++ b/src/client/interpreter/contracts.ts @@ -89,7 +89,7 @@ export interface IInterpreterHelper { } export const IPipEnvService = Symbol('IPipEnvService'); -export interface IPipEnvService { +export interface IPipEnvService extends IInterpreterLocatorService { executable: string; isRelatedPipEnvironment(dir: string, pythonPath: string): Promise; } @@ -99,15 +99,11 @@ export interface IInterpreterLocatorHelper { mergeInterpreters(interpreters: PythonInterpreter[]): Promise; } +export const IInterpreterWatcher = Symbol('IInterpreterWatcher'); export interface IInterpreterWatcher { onDidCreate: Event; } -export const IInterpreterWatcherRegistry = Symbol('IInterpreterWatcherRegistry'); -export interface IInterpreterWatcherRegistry extends IInterpreterWatcher { - register(resource: Resource): Promise; -} - export const IInterpreterWatcherBuilder = Symbol('IInterpreterWatcherBuilder'); export interface IInterpreterWatcherBuilder { getWorkspaceVirtualEnvInterpreterWatcher(resource: Resource): Promise; diff --git a/src/client/interpreter/helpers.ts b/src/client/interpreter/helpers.ts index 1eb9c8ccd18d..030c54f98f6c 100644 --- a/src/client/interpreter/helpers.ts +++ b/src/client/interpreter/helpers.ts @@ -7,6 +7,7 @@ import { IPythonExecutionFactory } from '../common/process/types'; import { IPersistentStateFactory, Resource } from '../common/types'; import { IServiceContainer } from '../ioc/types'; import { isMacDefaultPythonPath } from '../pythonEnvironments/discovery'; +import { InterpeterHashProviderFactory } from '../pythonEnvironments/discovery/locators/services/hashProviderFactory'; import { getInterpreterTypeName, InterpreterInformation, @@ -48,7 +49,7 @@ export class InterpreterHelper implements IInterpreterHelper { private readonly persistentFactory: IPersistentStateFactory; constructor( @inject(IServiceContainer) private serviceContainer: IServiceContainer, - @inject(IInterpreterHashProviderFactory) private readonly hashProviderFactory: IInterpreterHashProviderFactory + @inject(InterpeterHashProviderFactory) private readonly hashProviderFactory: IInterpreterHashProviderFactory ) { this.persistentFactory = this.serviceContainer.get(IPersistentStateFactory); } diff --git a/src/client/interpreter/interpreterService.ts b/src/client/interpreter/interpreterService.ts index d268ec8a58f1..2304c6b587cc 100644 --- a/src/client/interpreter/interpreterService.ts +++ b/src/client/interpreter/interpreterService.ts @@ -20,6 +20,7 @@ import { } from '../common/types'; import { sleep } from '../common/utils/async'; import { IServiceContainer } from '../ioc/types'; +import { InterpeterHashProviderFactory } from '../pythonEnvironments/discovery/locators/services/hashProviderFactory'; import { InterpreterType, PythonInterpreter } from '../pythonEnvironments/info'; import { captureTelemetry } from '../telemetry'; import { EventName } from '../telemetry/constants'; @@ -69,7 +70,7 @@ export class InterpreterService implements Disposable, IInterpreterService { constructor( @inject(IServiceContainer) private serviceContainer: IServiceContainer, - @inject(IInterpreterHashProviderFactory) private readonly hashProviderFactory: IInterpreterHashProviderFactory + @inject(InterpeterHashProviderFactory) private readonly hashProviderFactory: IInterpreterHashProviderFactory ) { this.locator = serviceContainer.get( IInterpreterLocatorService, diff --git a/src/client/interpreter/locators/types.ts b/src/client/interpreter/locators/types.ts index 6b36fba8eb94..f39589800074 100644 --- a/src/client/interpreter/locators/types.ts +++ b/src/client/interpreter/locators/types.ts @@ -15,7 +15,6 @@ export interface IPipEnvServiceHelper { trackWorkspaceFolder(pythonPath: string, workspaceFolder: Uri): Promise; } -export const IInterpreterHashProviderFactory = Symbol('IInterpreterHashProviderFactory'); /** * Factory to create a hash provider. * Getting the hash of an interpreter can vary based on the type of the interpreter. @@ -27,7 +26,6 @@ export interface IInterpreterHashProviderFactory { create(options: { pythonPath: string } | { resource: Uri }): Promise; } -export const IInterpreterHashProvider = Symbol('IInterpreterHashProvider'); /** * Provides the ability to get the has of a given interpreter. * @@ -46,10 +44,6 @@ export interface IInterpreterHashProvider { getInterpreterHash(pythonPath: string): Promise; } -export const IWindowsStoreHashProvider = Symbol('IWindowStoreHashProvider'); -export interface IWindowsStoreHashProvider extends IInterpreterHashProvider {} - -export const IWindowsStoreInterpreter = Symbol('IWindowsStoreInterpreter'); export interface IWindowsStoreInterpreter { /** * Whether this is a Windows Store/App Interpreter. diff --git a/src/client/interpreter/virtualEnvs/index.ts b/src/client/interpreter/virtualEnvs/index.ts index a88fdd9e2324..04368633d1f5 100644 --- a/src/client/interpreter/virtualEnvs/index.ts +++ b/src/client/interpreter/virtualEnvs/index.ts @@ -14,7 +14,7 @@ import { IServiceContainer } from '../../ioc/types'; import * as globalenvs from '../../pythonEnvironments/discovery/globalenv'; import * as subenvs from '../../pythonEnvironments/discovery/subenv'; import { InterpreterType } from '../../pythonEnvironments/info'; -import { IPipEnvService } from '../contracts'; +import { IInterpreterLocatorService, IPipEnvService, PIPENV_SERVICE } from '../contracts'; import { IVirtualEnvironmentManager } from './types'; @injectable() @@ -26,7 +26,10 @@ export class VirtualEnvironmentManager implements IVirtualEnvironmentManager { constructor(@inject(IServiceContainer) private readonly serviceContainer: IServiceContainer) { this.processServiceFactory = serviceContainer.get(IProcessServiceFactory); this.fs = serviceContainer.get(IFileSystem); - this.pipEnvService = serviceContainer.get(IPipEnvService); + this.pipEnvService = serviceContainer.get( + IInterpreterLocatorService, + PIPENV_SERVICE + ) as IPipEnvService; this.workspaceService = serviceContainer.get(IWorkspaceService); } diff --git a/src/client/pythonEnvironments/discovery/locators/helpers.ts b/src/client/pythonEnvironments/discovery/locators/helpers.ts index f1d259671b46..2d543840dc65 100644 --- a/src/client/pythonEnvironments/discovery/locators/helpers.ts +++ b/src/client/pythonEnvironments/discovery/locators/helpers.ts @@ -1,9 +1,10 @@ import * as fsapi from 'fs-extra'; -import { inject } from 'inversify'; +import { inject, injectable } from 'inversify'; import * as path from 'path'; import { traceError } from '../../../common/logger'; import { IS_WINDOWS } from '../../../common/platform/constants'; import { IFileSystem } from '../../../common/platform/types'; +import { IInterpreterLocatorHelper } from '../../../interpreter/contracts'; import { IPipEnvServiceHelper } from '../../../interpreter/locators/types'; import { InterpreterType, PythonInterpreter } from '../../info'; @@ -25,7 +26,8 @@ export async function lookForInterpretersInDirectory(pathToCheck: string, _: IFi } } -export class InterpreterLocatorHelper { +@injectable() +export class InterpreterLocatorHelper implements IInterpreterLocatorHelper { constructor( @inject(IFileSystem) private readonly fs: IFileSystem, @inject(IPipEnvServiceHelper) private readonly pipEnvServiceHelper: IPipEnvServiceHelper diff --git a/src/client/pythonEnvironments/discovery/locators/index.ts b/src/client/pythonEnvironments/discovery/locators/index.ts index 40591b183d5c..4b2a5188c235 100644 --- a/src/client/pythonEnvironments/discovery/locators/index.ts +++ b/src/client/pythonEnvironments/discovery/locators/index.ts @@ -1,7 +1,8 @@ -import { inject } from 'inversify'; +import { inject, injectable } from 'inversify'; 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 } from '../../../common/utils/async'; import { OSType } from '../../../common/utils/platform'; import { @@ -27,7 +28,8 @@ const flatten = require('lodash/flatten') as typeof import('lodash/flatten'); /** * Facilitates locating Python interpreters. */ -export class PythonInterpreterLocatorService { +@injectable() +export class PythonInterpreterLocatorService implements IInterpreterLocatorService { public didTriggerInterpreterSuggestions: boolean; private readonly disposables: Disposable[] = []; @@ -37,6 +39,7 @@ export class PythonInterpreterLocatorService { constructor(@inject(IServiceContainer) private serviceContainer: IServiceContainer) { this._hasInterpreters = createDeferred(); + serviceContainer.get(IDisposableRegistry).push(this); this.platform = serviceContainer.get(IPlatformService); this.interpreterLocatorHelper = serviceContainer.get(IInterpreterLocatorHelper); this.didTriggerInterpreterSuggestions = false; diff --git a/src/client/pythonEnvironments/discovery/locators/progressService.ts b/src/client/pythonEnvironments/discovery/locators/progressService.ts index 37ad078060cf..ed6a48f282f0 100644 --- a/src/client/pythonEnvironments/discovery/locators/progressService.ts +++ b/src/client/pythonEnvironments/discovery/locators/progressService.ts @@ -3,17 +3,18 @@ 'use strict'; -import { inject } from 'inversify'; +import { inject, injectable } from 'inversify'; import { Disposable, Event, EventEmitter } from 'vscode'; import { traceDecorators } from '../../../common/logger'; import { IDisposableRegistry } from '../../../common/types'; import { createDeferredFrom, Deferred } from '../../../common/utils/async'; import { noop } from '../../../common/utils/misc'; -import { IInterpreterLocatorService } from '../../../interpreter/contracts'; +import { IInterpreterLocatorProgressService, IInterpreterLocatorService } from '../../../interpreter/contracts'; import { IServiceContainer } from '../../../ioc/types'; import { PythonInterpreter } from '../../info'; -export class InterpreterLocatorProgressService { +@injectable() +export class InterpreterLocatorProgressService implements IInterpreterLocatorProgressService { private deferreds: Deferred[] = []; private readonly refreshing = new EventEmitter(); private readonly refreshed = new EventEmitter(); diff --git a/src/client/pythonEnvironments/discovery/locators/services/KnownPathsService.ts b/src/client/pythonEnvironments/discovery/locators/services/KnownPathsService.ts index d0dd4d9b3f7e..367bef9de946 100644 --- a/src/client/pythonEnvironments/discovery/locators/services/KnownPathsService.ts +++ b/src/client/pythonEnvironments/discovery/locators/services/KnownPathsService.ts @@ -1,5 +1,5 @@ // tslint:disable:no-require-imports no-var-requires no-unnecessary-callback-wrapper -import { inject } from 'inversify'; +import { inject, injectable } from 'inversify'; import * as path from 'path'; import { Uri } from 'vscode'; import { IFileSystem, IPlatformService } from '../../../../common/platform/types'; @@ -14,6 +14,7 @@ const flatten = require('lodash/flatten') as typeof import('lodash/flatten'); /** * Locates "known" paths. */ +@injectable() export class KnownPathsService extends CacheableLocatorService { public constructor( @inject(IKnownSearchPathsForInterpreters) private knownSearchPaths: IKnownSearchPathsForInterpreters, @@ -83,7 +84,8 @@ export class KnownPathsService extends CacheableLocatorService { } } -export class KnownSearchPathsForInterpreters { +@injectable() +export class KnownSearchPathsForInterpreters implements IKnownSearchPathsForInterpreters { constructor(@inject(IServiceContainer) private readonly serviceContainer: IServiceContainer) {} /** * Return the paths where Python interpreters might be found. diff --git a/src/client/pythonEnvironments/discovery/locators/services/baseVirtualEnvService.ts b/src/client/pythonEnvironments/discovery/locators/services/baseVirtualEnvService.ts index a7a68da26e3a..8838659ca14f 100644 --- a/src/client/pythonEnvironments/discovery/locators/services/baseVirtualEnvService.ts +++ b/src/client/pythonEnvironments/discovery/locators/services/baseVirtualEnvService.ts @@ -1,5 +1,6 @@ // tslint:disable:no-unnecessary-callback-wrapper no-require-imports no-var-requires +import { injectable, unmanaged } from 'inversify'; import * as path from 'path'; import { Uri } from 'vscode'; import { traceError } from '../../../../common/logger'; @@ -12,15 +13,16 @@ import { lookForInterpretersInDirectory } from '../helpers'; import { CacheableLocatorService } from './cacheableLocatorService'; const flatten = require('lodash/flatten') as typeof import('lodash/flatten'); +@injectable() export class BaseVirtualEnvService extends CacheableLocatorService { private readonly virtualEnvMgr: IVirtualEnvironmentManager; private readonly helper: IInterpreterHelper; private readonly fileSystem: IFileSystem; public constructor( - private searchPathsProvider: IVirtualEnvironmentsSearchPathProvider, - serviceContainer: IServiceContainer, - name: string, - cachePerWorkspace: boolean = false + @unmanaged() private searchPathsProvider: IVirtualEnvironmentsSearchPathProvider, + @unmanaged() serviceContainer: IServiceContainer, + @unmanaged() name: string, + @unmanaged() cachePerWorkspace: boolean = false ) { super(name, serviceContainer, cachePerWorkspace); this.virtualEnvMgr = serviceContainer.get(IVirtualEnvironmentManager); diff --git a/src/client/pythonEnvironments/discovery/locators/services/cacheableLocatorService.ts b/src/client/pythonEnvironments/discovery/locators/services/cacheableLocatorService.ts index 50883258cbbf..8bcd4b96136c 100644 --- a/src/client/pythonEnvironments/discovery/locators/services/cacheableLocatorService.ts +++ b/src/client/pythonEnvironments/discovery/locators/services/cacheableLocatorService.ts @@ -3,6 +3,7 @@ // tslint:disable:no-any +import { injectable, unmanaged } from 'inversify'; import * as md5 from 'md5'; import { Disposable, Event, EventEmitter, Uri } from 'vscode'; import { IWorkspaceService } from '../../../../common/application/types'; @@ -59,6 +60,7 @@ export class CacheableLocatorPromiseCache { } } +@injectable() export abstract class CacheableLocatorService implements IInterpreterLocatorService { protected readonly _hasInterpreters: Deferred; private readonly promisesPerResource = new CacheableLocatorPromiseCache(); @@ -68,9 +70,9 @@ export abstract class CacheableLocatorService implements IInterpreterLocatorServ private _didTriggerInterpreterSuggestions: boolean; constructor( - private readonly name: string, - protected readonly serviceContainer: IServiceContainer, - private cachePerWorkspace: boolean = false + @unmanaged() private readonly name: string, + @unmanaged() protected readonly serviceContainer: IServiceContainer, + @unmanaged() private cachePerWorkspace: boolean = false ) { this._hasInterpreters = createDeferred(); this.cacheKeyPrefix = `INTERPRETERS_CACHE_v3_${name}`; diff --git a/src/client/pythonEnvironments/discovery/locators/services/condaEnvFileService.ts b/src/client/pythonEnvironments/discovery/locators/services/condaEnvFileService.ts index 2af93d0d7f08..6b76a95f567d 100644 --- a/src/client/pythonEnvironments/discovery/locators/services/condaEnvFileService.ts +++ b/src/client/pythonEnvironments/discovery/locators/services/condaEnvFileService.ts @@ -8,7 +8,7 @@ * More details: https://github.com/microsoft/vscode-python/issues/8886 */ -import { inject } from 'inversify'; +import { inject, injectable } from 'inversify'; import * as path from 'path'; import { Uri } from 'vscode'; import { traceError } from '../../../../common/logger'; @@ -22,6 +22,7 @@ import { AnacondaCompanyName } from './conda'; /** * Locate conda env interpreters based on the "conda environments file". */ +@injectable() export class CondaEnvFileService extends CacheableLocatorService { constructor( @inject(IInterpreterHelper) private helperService: IInterpreterHelper, diff --git a/src/client/pythonEnvironments/discovery/locators/services/condaEnvService.ts b/src/client/pythonEnvironments/discovery/locators/services/condaEnvService.ts index 0c9f232ea19a..54e5d01100b8 100644 --- a/src/client/pythonEnvironments/discovery/locators/services/condaEnvService.ts +++ b/src/client/pythonEnvironments/discovery/locators/services/condaEnvService.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -import { inject } from 'inversify'; +import { inject, injectable } from 'inversify'; import { Uri } from 'vscode'; import { traceError } from '../../../../common/logger'; import { IFileSystem } from '../../../../common/platform/types'; @@ -14,6 +14,7 @@ import { parseCondaInfo } from './conda'; /** * Locates conda env interpreters based on the conda service's info. */ +@injectable() export class CondaEnvService extends CacheableLocatorService { constructor( @inject(ICondaService) private condaService: ICondaService, diff --git a/src/client/pythonEnvironments/discovery/locators/services/condaService.ts b/src/client/pythonEnvironments/discovery/locators/services/condaService.ts index 05a4fac6f1a0..7f9a7e57233a 100644 --- a/src/client/pythonEnvironments/discovery/locators/services/condaService.ts +++ b/src/client/pythonEnvironments/discovery/locators/services/condaService.ts @@ -1,4 +1,4 @@ -import { inject, named, optional } from 'inversify'; +import { inject, injectable, named, optional } from 'inversify'; import * as path from 'path'; import { compare, parse, SemVer } from 'semver'; import { ConfigurationChangeEvent, Uri } from 'vscode'; @@ -9,7 +9,7 @@ import { IFileSystem, IPlatformService } from '../../../../common/platform/types import { IProcessServiceFactory } from '../../../../common/process/types'; import { IConfigurationService, IDisposableRegistry, IPersistentStateFactory } from '../../../../common/types'; import { cache } from '../../../../common/utils/decorators'; -import { IInterpreterLocatorService, WINDOWS_REGISTRY_SERVICE } from '../../../../interpreter/contracts'; +import { ICondaService, IInterpreterLocatorService, WINDOWS_REGISTRY_SERVICE } from '../../../../interpreter/contracts'; import { InterpreterType, PythonInterpreter } from '../../../info'; import { CondaEnvironmentInfo, CondaInfo } from './conda'; import { parseCondaEnvFileContents } from './condaHelper'; @@ -48,7 +48,8 @@ export const CondaGetEnvironmentPrefix = 'Outputting Environment Now...'; /** * A wrapper around a conda installation. */ -export class CondaService { +@injectable() +export class CondaService implements ICondaService { private condaFile?: Promise; private isAvailable: boolean | undefined; diff --git a/src/client/pythonEnvironments/discovery/locators/services/currentPathService.ts b/src/client/pythonEnvironments/discovery/locators/services/currentPathService.ts index 849b318cb981..e0d523abf19f 100644 --- a/src/client/pythonEnvironments/discovery/locators/services/currentPathService.ts +++ b/src/client/pythonEnvironments/discovery/locators/services/currentPathService.ts @@ -1,5 +1,5 @@ // tslint:disable:no-require-imports no-var-requires underscore-consistent-invocation no-unnecessary-callback-wrapper -import { inject } from 'inversify'; +import { inject, injectable } from 'inversify'; import { Uri } from 'vscode'; import { traceError, traceInfo } from '../../../../common/logger'; import { IFileSystem, IPlatformService } from '../../../../common/platform/types'; @@ -19,6 +19,7 @@ import { CacheableLocatorService } from './cacheableLocatorService'; * If no interpreter is configured then it falls back to the system * Python (3 then 2). */ +@injectable() export class CurrentPathService extends CacheableLocatorService { private readonly fs: IFileSystem; @@ -124,7 +125,8 @@ export class CurrentPathService extends CacheableLocatorService { } } -export class PythonInPathCommandProvider { +@injectable() +export class PythonInPathCommandProvider implements IPythonInPathCommandProvider { constructor(@inject(IPlatformService) private readonly platform: IPlatformService) {} public getCommands(): { command: string; args?: string[] }[] { const paths = ['python3.7', 'python3.6', 'python3', 'python2', 'python'].map((item) => { diff --git a/src/client/pythonEnvironments/discovery/locators/services/globalVirtualEnvService.ts b/src/client/pythonEnvironments/discovery/locators/services/globalVirtualEnvService.ts index 205f3f54fb53..5324c35d35dc 100644 --- a/src/client/pythonEnvironments/discovery/locators/services/globalVirtualEnvService.ts +++ b/src/client/pythonEnvironments/discovery/locators/services/globalVirtualEnvService.ts @@ -3,7 +3,7 @@ 'use strict'; -import { inject, named } from 'inversify'; +import { inject, injectable, named } from 'inversify'; import * as os from 'os'; import * as path from 'path'; import { Uri } from 'vscode'; @@ -16,6 +16,7 @@ import { BaseVirtualEnvService } from './baseVirtualEnvService'; // tslint:disable-next-line:no-require-imports no-var-requires const untildify: (value: string) => string = require('untildify'); +@injectable() export class GlobalVirtualEnvService extends BaseVirtualEnvService { public constructor( @inject(IVirtualEnvironmentsSearchPathProvider) @@ -27,7 +28,8 @@ export class GlobalVirtualEnvService extends BaseVirtualEnvService { } } -export class GlobalVirtualEnvironmentsSearchPathProvider { +@injectable() +export class GlobalVirtualEnvironmentsSearchPathProvider implements IVirtualEnvironmentsSearchPathProvider { private readonly config: IConfigurationService; private readonly currentProcess: ICurrentProcess; private readonly virtualEnvMgr: IVirtualEnvironmentManager; diff --git a/src/client/pythonEnvironments/discovery/locators/services/hashProvider.ts b/src/client/pythonEnvironments/discovery/locators/services/hashProvider.ts index 50aa5f604bf6..453ecddd4c10 100644 --- a/src/client/pythonEnvironments/discovery/locators/services/hashProvider.ts +++ b/src/client/pythonEnvironments/discovery/locators/services/hashProvider.ts @@ -3,10 +3,12 @@ 'use strict'; -import { inject } from 'inversify'; +import { inject, injectable } from 'inversify'; import { IFileSystem } from '../../../../common/platform/types'; +import { IInterpreterHashProvider } from '../../../../interpreter/locators/types'; -export class InterpreterHashProvider { +@injectable() +export class InterpreterHashProvider implements IInterpreterHashProvider { constructor(@inject(IFileSystem) private readonly fs: IFileSystem) {} public async getInterpreterHash(pythonPath: string): Promise { return this.fs.getFileHash(pythonPath); diff --git a/src/client/pythonEnvironments/discovery/locators/services/hashProviderFactory.ts b/src/client/pythonEnvironments/discovery/locators/services/hashProviderFactory.ts index 32092b15aee0..31d012e7422a 100644 --- a/src/client/pythonEnvironments/discovery/locators/services/hashProviderFactory.ts +++ b/src/client/pythonEnvironments/discovery/locators/services/hashProviderFactory.ts @@ -3,21 +3,24 @@ 'use strict'; -import { inject } from 'inversify'; +import { inject, injectable } from 'inversify'; import { Uri } from 'vscode'; import { IConfigurationService } from '../../../../common/types'; import { IInterpreterHashProvider, - IWindowsStoreHashProvider, + IInterpreterHashProviderFactory, IWindowsStoreInterpreter } from '../../../../interpreter/locators/types'; +import { InterpreterHashProvider } from './hashProvider'; +import { WindowsStoreInterpreter } from './windowsStoreInterpreter'; -export class InterpreterHashProviderFactory { +@injectable() +export class InterpeterHashProviderFactory implements IInterpreterHashProviderFactory { constructor( @inject(IConfigurationService) private readonly configService: IConfigurationService, - @inject(IWindowsStoreInterpreter) private readonly windowsStoreInterpreter: IWindowsStoreInterpreter, - @inject(IWindowsStoreHashProvider) private readonly windowsStoreHashProvider: IWindowsStoreHashProvider, - @inject(IInterpreterHashProvider) private readonly hashProvider: IInterpreterHashProvider + @inject(WindowsStoreInterpreter) private readonly windowsStoreInterpreter: IWindowsStoreInterpreter, + @inject(WindowsStoreInterpreter) private readonly windowsStoreHashProvider: IInterpreterHashProvider, + @inject(InterpreterHashProvider) private readonly hashProvider: IInterpreterHashProvider ) {} public async create(options: { pythonPath: string } | { resource: Uri }): Promise { diff --git a/src/client/pythonEnvironments/discovery/locators/services/interpreterWatcherBuilder.ts b/src/client/pythonEnvironments/discovery/locators/services/interpreterWatcherBuilder.ts index acfeed9b624d..86362011c7fb 100644 --- a/src/client/pythonEnvironments/discovery/locators/services/interpreterWatcherBuilder.ts +++ b/src/client/pythonEnvironments/discovery/locators/services/interpreterWatcherBuilder.ts @@ -3,19 +3,21 @@ 'use strict'; -import { inject } from 'inversify'; +import { inject, injectable } from 'inversify'; import { Uri } from 'vscode'; import { IWorkspaceService } from '../../../../common/application/types'; import { traceDecorators } from '../../../../common/logger'; import { createDeferred } from '../../../../common/utils/async'; import { IInterpreterWatcher, - IInterpreterWatcherRegistry, + IInterpreterWatcherBuilder, WORKSPACE_VIRTUAL_ENV_SERVICE } from '../../../../interpreter/contracts'; import { IServiceContainer } from '../../../../ioc/types'; +import { WorkspaceVirtualEnvWatcherService } from './workspaceVirtualEnvWatcherService'; -export class InterpreterWatcherBuilder { +@injectable() +export class InterpreterWatcherBuilder implements IInterpreterWatcherBuilder { private readonly watchersByResource = new Map>(); /** * Creates an instance of InterpreterWatcherBuilder. @@ -35,8 +37,8 @@ export class InterpreterWatcherBuilder { if (!this.watchersByResource.has(key)) { const deferred = createDeferred(); this.watchersByResource.set(key, deferred.promise); - const watcher = this.serviceContainer.get( - IInterpreterWatcherRegistry, + const watcher = this.serviceContainer.get( + IInterpreterWatcher, WORKSPACE_VIRTUAL_ENV_SERVICE ); await watcher.register(resource); diff --git a/src/client/pythonEnvironments/discovery/locators/services/pipEnvService.ts b/src/client/pythonEnvironments/discovery/locators/services/pipEnvService.ts index cb03dca08734..79dba15b6729 100644 --- a/src/client/pythonEnvironments/discovery/locators/services/pipEnvService.ts +++ b/src/client/pythonEnvironments/discovery/locators/services/pipEnvService.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -import { inject } from 'inversify'; +import { inject, injectable } from 'inversify'; import * as path from 'path'; import { Uri } from 'vscode'; import { IApplicationShell, IWorkspaceService } from '../../../../common/application/types'; @@ -21,6 +21,7 @@ import { CacheableLocatorService } from './cacheableLocatorService'; const pipEnvFileNameVariable = 'PIPENV_PIPFILE'; +@injectable() export class PipEnvService extends CacheableLocatorService implements IPipEnvService { private readonly helper: IInterpreterHelper; private readonly processServiceFactory: IProcessServiceFactory; diff --git a/src/client/pythonEnvironments/discovery/locators/services/pipEnvServiceHelper.ts b/src/client/pythonEnvironments/discovery/locators/services/pipEnvServiceHelper.ts index 262c1dfbb446..87fef788f867 100644 --- a/src/client/pythonEnvironments/discovery/locators/services/pipEnvServiceHelper.ts +++ b/src/client/pythonEnvironments/discovery/locators/services/pipEnvServiceHelper.ts @@ -3,7 +3,7 @@ 'use strict'; -import { inject } from 'inversify'; +import { inject, injectable } from 'inversify'; import * as path from 'path'; import { Uri } from 'vscode'; import { IFileSystem } from '../../../../common/platform/types'; @@ -11,7 +11,7 @@ import { IPersistentState, IPersistentStateFactory } from '../../../../common/ty import { IPipEnvServiceHelper } from '../../../../interpreter/locators/types'; type PipEnvInformation = { pythonPath: string; workspaceFolder: string; envName: string }; - +@injectable() export class PipEnvServiceHelper implements IPipEnvServiceHelper { private initialized = false; private readonly state: IPersistentState>; diff --git a/src/client/pythonEnvironments/discovery/locators/services/windowsRegistryService.ts b/src/client/pythonEnvironments/discovery/locators/services/windowsRegistryService.ts index 2c145c12f5d5..4cc062982ebb 100644 --- a/src/client/pythonEnvironments/discovery/locators/services/windowsRegistryService.ts +++ b/src/client/pythonEnvironments/discovery/locators/services/windowsRegistryService.ts @@ -1,6 +1,6 @@ // tslint:disable:no-require-imports no-var-requires underscore-consistent-invocation -import { inject } from 'inversify'; +import { inject, injectable } from 'inversify'; import * as path from 'path'; import { Uri } from 'vscode'; import { traceError } from '../../../../common/logger'; @@ -14,6 +14,7 @@ import { InterpreterType, PythonInterpreter } from '../../../info'; import { parsePythonVersion } from '../../../info/pythonVersion'; import { CacheableLocatorService } from './cacheableLocatorService'; import { AnacondaCompanyName, AnacondaCompanyNames } from './conda'; +import { WindowsStoreInterpreter } from './windowsStoreInterpreter'; const flatten = require('lodash/flatten') as typeof import('lodash/flatten'); // tslint:disable-next-line:variable-name @@ -31,6 +32,7 @@ type CompanyInterpreter = { arch?: Architecture; }; +@injectable() export class WindowsRegistryService extends CacheableLocatorService { private readonly pathUtils: IPathUtils; private readonly fs: IFileSystem; @@ -38,7 +40,7 @@ export class WindowsRegistryService extends CacheableLocatorService { @inject(IRegistry) private registry: IRegistry, @inject(IPlatformService) private readonly platform: IPlatformService, @inject(IServiceContainer) serviceContainer: IServiceContainer, - @inject(IWindowsStoreInterpreter) private readonly windowsStoreInterpreter: IWindowsStoreInterpreter + @inject(WindowsStoreInterpreter) private readonly windowsStoreInterpreter: IWindowsStoreInterpreter ) { super('WindowsRegistryService', serviceContainer); this.pathUtils = serviceContainer.get(IPathUtils); diff --git a/src/client/pythonEnvironments/discovery/locators/services/windowsStoreInterpreter.ts b/src/client/pythonEnvironments/discovery/locators/services/windowsStoreInterpreter.ts index 0943552b999b..e28a3c320ff5 100644 --- a/src/client/pythonEnvironments/discovery/locators/services/windowsStoreInterpreter.ts +++ b/src/client/pythonEnvironments/discovery/locators/services/windowsStoreInterpreter.ts @@ -3,12 +3,13 @@ 'use strict'; -import { inject } from 'inversify'; +import { inject, injectable } from 'inversify'; import * as path from 'path'; import { traceDecorators } from '../../../../common/logger'; import { IFileSystem } from '../../../../common/platform/types'; import { IPythonExecutionFactory } from '../../../../common/process/types'; import { IPersistentStateFactory } from '../../../../common/types'; +import { IInterpreterHashProvider, IWindowsStoreInterpreter } from '../../../../interpreter/locators/types'; import { IServiceContainer } from '../../../../ioc/types'; /** @@ -53,7 +54,8 @@ export function isRestrictedWindowsStoreInterpreterPath(pythonPath: string): boo * @implements {IWindowsStoreInterpreter} * @implements {IInterpreterHashProvider} */ -export class WindowsStoreInterpreter { +@injectable() +export class WindowsStoreInterpreter implements IWindowsStoreInterpreter, IInterpreterHashProvider { constructor( @inject(IServiceContainer) private readonly serviceContainer: IServiceContainer, @inject(IPersistentStateFactory) private readonly persistentFactory: IPersistentStateFactory, diff --git a/src/client/pythonEnvironments/discovery/locators/services/workspaceVirtualEnvService.ts b/src/client/pythonEnvironments/discovery/locators/services/workspaceVirtualEnvService.ts index 62e3fb4edaa8..8f1d75b4ebc0 100644 --- a/src/client/pythonEnvironments/discovery/locators/services/workspaceVirtualEnvService.ts +++ b/src/client/pythonEnvironments/discovery/locators/services/workspaceVirtualEnvService.ts @@ -5,7 +5,7 @@ // tslint:disable:no-require-imports -import { inject, named } from 'inversify'; +import { inject, injectable, named } from 'inversify'; import * as path from 'path'; import untildify = require('untildify'); import { Uri } from 'vscode'; @@ -19,6 +19,7 @@ import { import { IServiceContainer } from '../../../../ioc/types'; import { BaseVirtualEnvService } from './baseVirtualEnvService'; +@injectable() export class WorkspaceVirtualEnvService extends BaseVirtualEnvService { public constructor( @inject(IVirtualEnvironmentsSearchPathProvider) @@ -34,7 +35,8 @@ export class WorkspaceVirtualEnvService extends BaseVirtualEnvService { } } -export class WorkspaceVirtualEnvironmentsSearchPathProvider { +@injectable() +export class WorkspaceVirtualEnvironmentsSearchPathProvider implements IVirtualEnvironmentsSearchPathProvider { public constructor(@inject(IServiceContainer) private serviceContainer: IServiceContainer) {} public async getSearchPaths(resource?: Uri): Promise { const configService = this.serviceContainer.get(IConfigurationService); diff --git a/src/client/pythonEnvironments/discovery/locators/services/workspaceVirtualEnvWatcherService.ts b/src/client/pythonEnvironments/discovery/locators/services/workspaceVirtualEnvWatcherService.ts index 844d3fde4c70..85eea917e9fa 100644 --- a/src/client/pythonEnvironments/discovery/locators/services/workspaceVirtualEnvWatcherService.ts +++ b/src/client/pythonEnvironments/discovery/locators/services/workspaceVirtualEnvWatcherService.ts @@ -3,7 +3,7 @@ 'use strict'; -import { inject } from 'inversify'; +import { inject, injectable } from 'inversify'; import * as path from 'path'; import { Disposable, Event, EventEmitter, FileSystemWatcher, RelativePattern, Uri } from 'vscode'; import { IWorkspaceService } from '../../../../common/application/types'; @@ -12,11 +12,13 @@ import { traceDecorators, traceVerbose } from '../../../../common/logger'; import { IPlatformService } from '../../../../common/platform/types'; import { IPythonExecutionFactory } from '../../../../common/process/types'; import { IDisposableRegistry, Resource } from '../../../../common/types'; +import { IInterpreterWatcher } from '../../../../interpreter/contracts'; const maxTimeToWaitForEnvCreation = 60_000; const timeToPollForEnvCreation = 2_000; -export class WorkspaceVirtualEnvWatcherService { +@injectable() +export class WorkspaceVirtualEnvWatcherService implements IInterpreterWatcher, Disposable { private readonly didCreate: EventEmitter; private timers = new Map(); private fsWatchers: FileSystemWatcher[] = []; diff --git a/src/client/pythonEnvironments/legacyIOC.ts b/src/client/pythonEnvironments/legacyIOC.ts index 6d39f540171f..5f4517bc7a21 100644 --- a/src/client/pythonEnvironments/legacyIOC.ts +++ b/src/client/pythonEnvironments/legacyIOC.ts @@ -1,50 +1,30 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -// tslint:disable:no-use-before-declare max-classes-per-file - -import { inject, injectable, named, optional } from 'inversify'; -import { SemVer } from 'semver'; -import { Disposable, Event, Uri } from 'vscode'; -import { IWorkspaceService } from '../common/application/types'; -import { IFileSystem, IPlatformService, IRegistry } from '../common/platform/types'; -import { IProcessServiceFactory, IPythonExecutionFactory } from '../common/process/types'; -import { IConfigurationService, IDisposableRegistry, IPersistentStateFactory, Resource } from '../common/types'; import { CONDA_ENV_FILE_SERVICE, CONDA_ENV_SERVICE, CURRENT_PATH_SERVICE, GLOBAL_VIRTUAL_ENV_SERVICE, ICondaService, - IInterpreterHelper, IInterpreterLocatorHelper, IInterpreterLocatorProgressService, IInterpreterLocatorService, IInterpreterWatcher, IInterpreterWatcherBuilder, - IInterpreterWatcherRegistry, IKnownSearchPathsForInterpreters, INTERPRETER_LOCATOR_SERVICE, - IPipEnvService, IVirtualEnvironmentsSearchPathProvider, KNOWN_PATH_SERVICE, PIPENV_SERVICE, WINDOWS_REGISTRY_SERVICE, WORKSPACE_VIRTUAL_ENV_SERVICE } from '../interpreter/contracts'; -import { - IInterpreterHashProvider, - IInterpreterHashProviderFactory, - IPipEnvServiceHelper, - IPythonInPathCommandProvider, - IWindowsStoreHashProvider, - IWindowsStoreInterpreter -} from '../interpreter/locators/types'; -import { IServiceContainer, IServiceManager } from '../ioc/types'; +import { IPipEnvServiceHelper, IPythonInPathCommandProvider } from '../interpreter/locators/types'; +import { IServiceManager } from '../ioc/types'; import { PythonInterpreterLocatorService } from './discovery/locators'; import { InterpreterLocatorHelper } from './discovery/locators/helpers'; import { InterpreterLocatorProgressService } from './discovery/locators/progressService'; -import { CondaEnvironmentInfo, CondaInfo } from './discovery/locators/services/conda'; import { CondaEnvFileService } from './discovery/locators/services/condaEnvFileService'; import { CondaEnvService } from './discovery/locators/services/condaEnvService'; import { CondaService } from './discovery/locators/services/condaService'; @@ -54,7 +34,7 @@ import { GlobalVirtualEnvService } from './discovery/locators/services/globalVirtualEnvService'; import { InterpreterHashProvider } from './discovery/locators/services/hashProvider'; -import { InterpreterHashProviderFactory } from './discovery/locators/services/hashProviderFactory'; +import { InterpeterHashProviderFactory } from './discovery/locators/services/hashProviderFactory'; import { InterpreterWatcherBuilder } from './discovery/locators/services/interpreterWatcherBuilder'; import { KnownPathsService, KnownSearchPathsForInterpreters } from './discovery/locators/services/KnownPathsService'; import { PipEnvService } from './discovery/locators/services/pipEnvService'; @@ -66,487 +46,86 @@ import { WorkspaceVirtualEnvService } from './discovery/locators/services/workspaceVirtualEnvService'; import { WorkspaceVirtualEnvWatcherService } from './discovery/locators/services/workspaceVirtualEnvWatcherService'; -import { GetInterpreterLocatorOptions } from './discovery/locators/types'; -import { PythonInterpreter } from './info'; export function registerForIOC(serviceManager: IServiceManager) { - serviceManager.addSingleton(IInterpreterLocatorHelper, InterpreterLocatorHelperProxy); + serviceManager.addSingleton(IInterpreterLocatorHelper, InterpreterLocatorHelper); serviceManager.addSingleton( IInterpreterLocatorService, - PythonInterpreterLocatorServiceProxy, + PythonInterpreterLocatorService, INTERPRETER_LOCATOR_SERVICE ); serviceManager.addSingleton( IInterpreterLocatorProgressService, - InterpreterLocatorProgressServiceProxy + InterpreterLocatorProgressService ); serviceManager.addSingleton( IInterpreterLocatorService, - CondaEnvFileServiceProxy, + CondaEnvFileService, CONDA_ENV_FILE_SERVICE ); serviceManager.addSingleton( IInterpreterLocatorService, - CondaEnvServiceProxy, + CondaEnvService, CONDA_ENV_SERVICE ); serviceManager.addSingleton( IInterpreterLocatorService, - CurrentPathServiceProxy, + CurrentPathService, CURRENT_PATH_SERVICE ); serviceManager.addSingleton( IInterpreterLocatorService, - GlobalVirtualEnvServiceProxy, + GlobalVirtualEnvService, GLOBAL_VIRTUAL_ENV_SERVICE ); serviceManager.addSingleton( IInterpreterLocatorService, - WorkspaceVirtualEnvServiceProxy, + WorkspaceVirtualEnvService, WORKSPACE_VIRTUAL_ENV_SERVICE ); - serviceManager.addSingleton( - IInterpreterLocatorService, - PipEnvLocatorServiceProxy, - PIPENV_SERVICE - ); + serviceManager.addSingleton(IInterpreterLocatorService, PipEnvService, PIPENV_SERVICE); serviceManager.addSingleton( IInterpreterLocatorService, - WindowsRegistryServiceProxy, + WindowsRegistryService, WINDOWS_REGISTRY_SERVICE ); serviceManager.addSingleton( IInterpreterLocatorService, - KnownPathsServiceProxy, + KnownPathsService, KNOWN_PATH_SERVICE ); - serviceManager.addSingleton(ICondaService, CondaServiceProxy); - serviceManager.addSingleton(IPipEnvService, PipEnvServiceProxy); - serviceManager.addSingleton(IPipEnvServiceHelper, PipEnvServiceHelperProxy); + serviceManager.addSingleton(ICondaService, CondaService); + serviceManager.addSingleton(IPipEnvServiceHelper, PipEnvServiceHelper); serviceManager.addSingleton( IPythonInPathCommandProvider, - PythonInPathCommandProviderProxy + PythonInPathCommandProvider ); - serviceManager.add( - IInterpreterWatcherRegistry, - WorkspaceVirtualEnvWatcherServiceProxy, + serviceManager.add( + IInterpreterWatcher, + WorkspaceVirtualEnvWatcherService, WORKSPACE_VIRTUAL_ENV_SERVICE ); - serviceManager.addSingleton(IWindowsStoreInterpreter, WindowsStoreInterpreterProxy); - serviceManager.addSingleton(IWindowsStoreHashProvider, WindowsStoreInterpreterProxy); - serviceManager.addSingleton(IInterpreterHashProvider, InterpreterHashProviderProxy); - serviceManager.addSingleton( - IInterpreterHashProviderFactory, - InterpreterHashProviderFactoryProxy + serviceManager.addSingleton(WindowsStoreInterpreter, WindowsStoreInterpreter); + serviceManager.addSingleton(InterpreterHashProvider, InterpreterHashProvider); + serviceManager.addSingleton( + InterpeterHashProviderFactory, + InterpeterHashProviderFactory ); serviceManager.addSingleton( IVirtualEnvironmentsSearchPathProvider, - GlobalVirtualEnvironmentsSearchPathProviderProxy, + GlobalVirtualEnvironmentsSearchPathProvider, 'global' ); serviceManager.addSingleton( IVirtualEnvironmentsSearchPathProvider, - WorkspaceVirtualEnvironmentsSearchPathProviderProxy, + WorkspaceVirtualEnvironmentsSearchPathProvider, 'workspace' ); serviceManager.addSingleton( IKnownSearchPathsForInterpreters, - KnownSearchPathsForInterpretersProxy + KnownSearchPathsForInterpreters ); - serviceManager.addSingleton(IInterpreterWatcherBuilder, InterpreterWatcherBuilderProxy); -} - -@injectable() -class InterpreterLocatorHelperProxy implements IInterpreterLocatorHelper { - private readonly impl: IInterpreterLocatorHelper; - constructor( - @inject(IFileSystem) fs: IFileSystem, - @inject(IPipEnvServiceHelper) pipEnvServiceHelper: IPipEnvServiceHelper - ) { - this.impl = new InterpreterLocatorHelper(fs, pipEnvServiceHelper); - } - public async mergeInterpreters(interpreters: PythonInterpreter[]): Promise { - return this.impl.mergeInterpreters(interpreters); - } -} - -@injectable() -class InterpreterLocatorProgressServiceProxy implements IInterpreterLocatorProgressService { - private readonly impl: IInterpreterLocatorProgressService; - constructor( - @inject(IServiceContainer) serviceContainer: IServiceContainer, - @inject(IDisposableRegistry) disposables: Disposable[] - ) { - this.impl = new InterpreterLocatorProgressService(serviceContainer, disposables); - } - - public get onRefreshing(): Event { - return this.impl.onRefreshing; - } - public get onRefreshed(): Event { - return this.impl.onRefreshed; - } - public register(): void { - this.impl.register(); - } -} - -@injectable() -class InterpreterHashProviderFactoryProxy implements IInterpreterHashProviderFactory { - private readonly impl: IInterpreterHashProviderFactory; - constructor( - @inject(IConfigurationService) configService: IConfigurationService, - @inject(IWindowsStoreInterpreter) windowsStoreInterpreter: IWindowsStoreInterpreter, - @inject(IWindowsStoreHashProvider) windowsStoreHashProvider: IWindowsStoreHashProvider, - @inject(IInterpreterHashProvider) hashProvider: IInterpreterHashProvider - ) { - this.impl = new InterpreterHashProviderFactory( - configService, - windowsStoreInterpreter, - windowsStoreHashProvider, - hashProvider - ); - } - public async create(options: { pythonPath: string } | { resource: Uri }): Promise { - return this.impl.create(options); - } -} - -@injectable() -class InterpreterHashProviderProxy implements IInterpreterHashProvider { - private readonly impl: IInterpreterHashProvider; - constructor(@inject(IFileSystem) fs: IFileSystem) { - this.impl = new InterpreterHashProvider(fs); - } - public async getInterpreterHash(pythonPath: string): Promise { - return this.impl.getInterpreterHash(pythonPath); - } -} - -@injectable() -class WindowsStoreInterpreterProxy implements IWindowsStoreInterpreter, IWindowsStoreHashProvider { - private readonly impl: IWindowsStoreInterpreter & IWindowsStoreHashProvider; - constructor( - @inject(IServiceContainer) serviceContainer: IServiceContainer, - @inject(IPersistentStateFactory) persistentFactory: IPersistentStateFactory, - @inject(IFileSystem) fs: IFileSystem - ) { - this.impl = new WindowsStoreInterpreter(serviceContainer, persistentFactory, fs); - } - public isWindowsStoreInterpreter(pythonPath: string): boolean { - return this.impl.isWindowsStoreInterpreter(pythonPath); - } - public isHiddenInterpreter(pythonPath: string): boolean { - return this.impl.isHiddenInterpreter(pythonPath); - } - public async getInterpreterHash(pythonPath: string): Promise { - return this.impl.getInterpreterHash(pythonPath); - } -} - -@injectable() -class PythonInPathCommandProviderProxy implements IPythonInPathCommandProvider { - private readonly impl: IPythonInPathCommandProvider; - constructor(@inject(IPlatformService) platform: IPlatformService) { - this.impl = new PythonInPathCommandProvider(platform); - } - public getCommands(): { command: string; args?: string[] }[] { - return this.impl.getCommands(); - } -} - -@injectable() -class KnownSearchPathsForInterpretersProxy implements IKnownSearchPathsForInterpreters { - private readonly impl: IKnownSearchPathsForInterpreters; - constructor(@inject(IServiceContainer) serviceContainer: IServiceContainer) { - this.impl = new KnownSearchPathsForInterpreters(serviceContainer); - } - public getSearchPaths(): string[] { - return this.impl.getSearchPaths(); - } -} - -@injectable() -class WorkspaceVirtualEnvironmentsSearchPathProviderProxy implements IVirtualEnvironmentsSearchPathProvider { - private readonly impl: IVirtualEnvironmentsSearchPathProvider; - public constructor(@inject(IServiceContainer) serviceContainer: IServiceContainer) { - this.impl = new WorkspaceVirtualEnvironmentsSearchPathProvider(serviceContainer); - } - public async getSearchPaths(resource?: Uri): Promise { - return this.impl.getSearchPaths(resource); - } -} - -@injectable() -class GlobalVirtualEnvironmentsSearchPathProviderProxy implements IVirtualEnvironmentsSearchPathProvider { - private readonly impl: IVirtualEnvironmentsSearchPathProvider; - constructor(@inject(IServiceContainer) serviceContainer: IServiceContainer) { - this.impl = new GlobalVirtualEnvironmentsSearchPathProvider(serviceContainer); - } - public async getSearchPaths(resource?: Uri): Promise { - return this.impl.getSearchPaths(resource); - } -} - -@injectable() -class PipEnvServiceProxy { - private readonly impl: IPipEnvService; - constructor(@inject(IInterpreterLocatorService) @named(PIPENV_SERVICE) proxy: IPipEnvService) { - // tslint:disable-next-line:no-any - const locator = (proxy as unknown) as any; - this.impl = locator.pipEnvService; - } - public async isRelatedPipEnvironment(dir: string, pythonPath: string): Promise { - return this.impl.isRelatedPipEnvironment(dir, pythonPath); - } - public get executable(): string { - return this.impl.executable; - } -} - -@injectable() -class PipEnvServiceHelperProxy implements IPipEnvServiceHelper { - private readonly impl: IPipEnvServiceHelper; - constructor( - @inject(IPersistentStateFactory) statefactory: IPersistentStateFactory, - @inject(IFileSystem) fs: IFileSystem - ) { - this.impl = new PipEnvServiceHelper(statefactory, fs); - } - public async getPipEnvInfo(pythonPath: string): Promise<{ workspaceFolder: Uri; envName: string } | undefined> { - return this.impl.getPipEnvInfo(pythonPath); - } - public async trackWorkspaceFolder(pythonPath: string, workspaceFolder: Uri): Promise { - return this.impl.trackWorkspaceFolder(pythonPath, workspaceFolder); - } -} - -@injectable() -class CondaServiceProxy implements ICondaService { - private readonly impl: ICondaService; - constructor( - @inject(IProcessServiceFactory) processServiceFactory: IProcessServiceFactory, - @inject(IPlatformService) platform: IPlatformService, - @inject(IFileSystem) fileSystem: IFileSystem, - @inject(IPersistentStateFactory) persistentStateFactory: IPersistentStateFactory, - @inject(IConfigurationService) configService: IConfigurationService, - @inject(IDisposableRegistry) disposableRegistry: IDisposableRegistry, - @inject(IWorkspaceService) workspaceService: IWorkspaceService, - @inject(IInterpreterLocatorService) - @named(WINDOWS_REGISTRY_SERVICE) - @optional() - registryLookupForConda?: IInterpreterLocatorService - ) { - this.impl = new CondaService( - processServiceFactory, - platform, - fileSystem, - persistentStateFactory, - configService, - disposableRegistry, - workspaceService, - registryLookupForConda - ); - } - public get condaEnvironmentsFile(): string | undefined { - return this.impl.condaEnvironmentsFile; - } - public async getCondaFile(): Promise { - return this.impl.getCondaFile(); - } - public async isCondaAvailable(): Promise { - return this.impl.isCondaAvailable(); - } - public async getCondaVersion(): Promise { - return this.impl.getCondaVersion(); - } - public async getCondaInfo(): Promise { - return this.impl.getCondaInfo(); - } - public async getCondaEnvironments(ignoreCache: boolean): Promise { - return this.impl.getCondaEnvironments(ignoreCache); - } - public getInterpreterPath(condaEnvironmentPath: string): string { - return this.impl.getInterpreterPath(condaEnvironmentPath); - } - public async getCondaFileFromInterpreter(interpreterPath?: string, envName?: string): Promise { - return this.impl.getCondaFileFromInterpreter(interpreterPath, envName); - } - public async isCondaEnvironment(interpreterPath: string): Promise { - return this.impl.isCondaEnvironment(interpreterPath); - } - public async getCondaEnvironment(interpreterPath: string): Promise<{ name: string; path: string } | undefined> { - return this.impl.getCondaEnvironment(interpreterPath); - } -} - -@injectable() -class InterpreterWatcherBuilderProxy implements IInterpreterWatcherBuilder { - private readonly impl: IInterpreterWatcherBuilder; - constructor( - @inject(IWorkspaceService) workspaceService: IWorkspaceService, - @inject(IServiceContainer) serviceContainer: IServiceContainer - ) { - this.impl = new InterpreterWatcherBuilder(workspaceService, serviceContainer); - } - public async getWorkspaceVirtualEnvInterpreterWatcher(resource: Uri | undefined): Promise { - return this.impl.getWorkspaceVirtualEnvInterpreterWatcher(resource); - } -} - -@injectable() -class WorkspaceVirtualEnvWatcherServiceProxy implements IInterpreterWatcherRegistry, Disposable { - private readonly impl: IInterpreterWatcherRegistry & Disposable; - constructor( - @inject(IDisposableRegistry) disposableRegistry: Disposable[], - @inject(IWorkspaceService) workspaceService: IWorkspaceService, - @inject(IPlatformService) platformService: IPlatformService, - @inject(IPythonExecutionFactory) pythonExecFactory: IPythonExecutionFactory - ) { - this.impl = new WorkspaceVirtualEnvWatcherService( - disposableRegistry, - workspaceService, - platformService, - pythonExecFactory - ); - } - public get onDidCreate(): Event { - return this.impl.onDidCreate; - } - public async register(resource: Resource): Promise { - return this.impl.register(resource); - } - public dispose() { - return this.impl.dispose(); - } -} - -//=========================== -// locators - -@injectable() -class BaseLocatorServiceProxy implements IInterpreterLocatorService { - constructor(protected readonly impl: IInterpreterLocatorService) {} - public dispose() { - this.impl.dispose(); - } - public get onLocating(): Event> { - return this.impl.onLocating; - } - public get hasInterpreters(): Promise { - return this.impl.hasInterpreters; - } - public get didTriggerInterpreterSuggestions(): boolean { - return this.impl.didTriggerInterpreterSuggestions as boolean; - } - public set didTriggerInterpreterSuggestions(value: boolean) { - this.impl.didTriggerInterpreterSuggestions = value; - } - public async getInterpreters(resource?: Uri, options?: GetInterpreterLocatorOptions): Promise { - return this.impl.getInterpreters(resource, options); - } -} - -@injectable() -class PythonInterpreterLocatorServiceProxy extends BaseLocatorServiceProxy { - constructor(@inject(IServiceContainer) serviceContainer: IServiceContainer) { - super(new PythonInterpreterLocatorService(serviceContainer)); - serviceContainer.get(IDisposableRegistry).push(this.impl); - } -} - -@injectable() -class CondaEnvFileServiceProxy extends BaseLocatorServiceProxy { - constructor( - @inject(IInterpreterHelper) helperService: IInterpreterHelper, - @inject(ICondaService) condaService: ICondaService, - @inject(IFileSystem) fileSystem: IFileSystem, - @inject(IServiceContainer) serviceContainer: IServiceContainer - ) { - super(new CondaEnvFileService(helperService, condaService, fileSystem, serviceContainer)); - } -} - -@injectable() -class CondaEnvServiceProxy extends BaseLocatorServiceProxy { - constructor( - @inject(ICondaService) condaService: ICondaService, - @inject(IInterpreterHelper) helper: IInterpreterHelper, - @inject(IServiceContainer) serviceContainer: IServiceContainer, - @inject(IFileSystem) fileSystem: IFileSystem - ) { - super(new CondaEnvService(condaService, helper, serviceContainer, fileSystem)); - } -} - -@injectable() -class CurrentPathServiceProxy extends BaseLocatorServiceProxy { - constructor( - @inject(IInterpreterHelper) helper: IInterpreterHelper, - @inject(IProcessServiceFactory) processServiceFactory: IProcessServiceFactory, - @inject(IPythonInPathCommandProvider) pythonCommandProvider: IPythonInPathCommandProvider, - @inject(IServiceContainer) serviceContainer: IServiceContainer - ) { - super(new CurrentPathService(helper, processServiceFactory, pythonCommandProvider, serviceContainer)); - } -} - -@injectable() -class GlobalVirtualEnvServiceProxy extends BaseLocatorServiceProxy { - public constructor( - @inject(IVirtualEnvironmentsSearchPathProvider) - @named('global') - globalVirtualEnvPathProvider: IVirtualEnvironmentsSearchPathProvider, - @inject(IServiceContainer) serviceContainer: IServiceContainer - ) { - super(new GlobalVirtualEnvService(globalVirtualEnvPathProvider, serviceContainer)); - } -} - -@injectable() -class WorkspaceVirtualEnvServiceProxy extends BaseLocatorServiceProxy { - public constructor( - @inject(IVirtualEnvironmentsSearchPathProvider) - @named('workspace') - workspaceVirtualEnvPathProvider: IVirtualEnvironmentsSearchPathProvider, - @inject(IServiceContainer) serviceContainer: IServiceContainer, - @inject(IInterpreterWatcherBuilder) builder: IInterpreterWatcherBuilder - ) { - super(new WorkspaceVirtualEnvService(workspaceVirtualEnvPathProvider, serviceContainer, builder)); - } -} - -@injectable() -class KnownPathsServiceProxy extends BaseLocatorServiceProxy { - public constructor( - @inject(IKnownSearchPathsForInterpreters) knownSearchPaths: IKnownSearchPathsForInterpreters, - @inject(IInterpreterHelper) helper: IInterpreterHelper, - @inject(IServiceContainer) serviceContainer: IServiceContainer - ) { - super(new KnownPathsService(knownSearchPaths, helper, serviceContainer)); - } -} - -@injectable() -class PipEnvLocatorServiceProxy extends BaseLocatorServiceProxy { - // This is only meant for consumption by PipEnvServiceProxy. - public readonly pipEnvService: IPipEnvService; - constructor(@inject(IServiceContainer) serviceContainer: IServiceContainer) { - super(new PipEnvService(serviceContainer)); - this.pipEnvService = (this.impl as unknown) as IPipEnvService; - } -} - -@injectable() -class WindowsRegistryServiceProxy extends BaseLocatorServiceProxy { - constructor( - @inject(IRegistry) registry: IRegistry, - @inject(IPlatformService) platform: IPlatformService, - @inject(IServiceContainer) serviceContainer: IServiceContainer, - @inject(IWindowsStoreInterpreter) windowsStoreInterpreter: IWindowsStoreInterpreter - ) { - super(new WindowsRegistryService(registry, platform, serviceContainer, windowsStoreInterpreter)); - } + serviceManager.addSingleton(IInterpreterWatcherBuilder, InterpreterWatcherBuilder); } diff --git a/src/test/interpreters/virtualEnvManager.unit.test.ts b/src/test/interpreters/virtualEnvManager.unit.test.ts index 64d672d349a5..d4c3de8c7851 100644 --- a/src/test/interpreters/virtualEnvManager.unit.test.ts +++ b/src/test/interpreters/virtualEnvManager.unit.test.ts @@ -10,7 +10,7 @@ import { Uri, WorkspaceFolder } from 'vscode'; import { IWorkspaceService } from '../../client/common/application/types'; import { IFileSystem } from '../../client/common/platform/types'; import { IProcessServiceFactory } from '../../client/common/process/types'; -import { IPipEnvService } from '../../client/interpreter/contracts'; +import { IInterpreterLocatorService, IPipEnvService, PIPENV_SERVICE } from '../../client/interpreter/contracts'; import { VirtualEnvironmentManager } from '../../client/interpreter/virtualEnvs'; import { IServiceContainer } from '../../client/ioc/types'; @@ -51,7 +51,9 @@ suite('Virtual environment manager', () => { serviceContainer .setup((s) => s.get(TypeMoq.It.isValue(IProcessServiceFactory))) .returns(() => TypeMoq.Mock.ofType().object); - serviceContainer.setup((s) => s.get(TypeMoq.It.isValue(IPipEnvService))).returns(() => pipEnvService.object); + serviceContainer + .setup((s) => s.get(TypeMoq.It.isValue(IInterpreterLocatorService), TypeMoq.It.isValue(PIPENV_SERVICE))) + .returns(() => pipEnvService.object); serviceContainer .setup((s) => s.get(TypeMoq.It.isValue(IFileSystem))) .returns(() => TypeMoq.Mock.ofType().object); @@ -83,7 +85,9 @@ suite('Virtual environment manager', () => { pipEnvService .setup((w) => w.isRelatedPipEnvironment(TypeMoq.It.isAny(), TypeMoq.It.isAny())) .returns(() => Promise.resolve(isPipEnvironment)); - serviceContainer.setup((s) => s.get(TypeMoq.It.isValue(IPipEnvService))).returns(() => pipEnvService.object); + serviceContainer + .setup((s) => s.get(TypeMoq.It.isValue(IInterpreterLocatorService), TypeMoq.It.isValue(PIPENV_SERVICE))) + .returns(() => pipEnvService.object); const workspaceService = TypeMoq.Mock.ofType(); workspaceService.setup((w) => w.hasWorkspaceFolders).returns(() => false); if (resource) { diff --git a/src/test/interpreters/virtualEnvs/index.unit.test.ts b/src/test/interpreters/virtualEnvs/index.unit.test.ts index 62d16eec7cca..3e8fefcffc1b 100644 --- a/src/test/interpreters/virtualEnvs/index.unit.test.ts +++ b/src/test/interpreters/virtualEnvs/index.unit.test.ts @@ -14,7 +14,7 @@ import { IFileSystem, IPlatformService } from '../../../client/common/platform/t import { IProcessService, IProcessServiceFactory } from '../../../client/common/process/types'; import { ITerminalActivationCommandProvider } from '../../../client/common/terminal/types'; import { ICurrentProcess, IPathUtils } from '../../../client/common/types'; -import { IPipEnvService } from '../../../client/interpreter/contracts'; +import { IInterpreterLocatorService, IPipEnvService, PIPENV_SERVICE } from '../../../client/interpreter/contracts'; import { VirtualEnvironmentManager } from '../../../client/interpreter/virtualEnvs'; import { IServiceContainer } from '../../../client/ioc/types'; @@ -51,7 +51,9 @@ suite('Virtual Environment Manager', () => { serviceContainer.setup((c) => c.get(TypeMoq.It.isValue(IPathUtils))).returns(() => pathUtils.object); serviceContainer.setup((c) => c.get(TypeMoq.It.isValue(IFileSystem))).returns(() => fs.object); serviceContainer.setup((c) => c.get(TypeMoq.It.isValue(IWorkspaceService))).returns(() => workspace.object); - serviceContainer.setup((c) => c.get(TypeMoq.It.isValue(IPipEnvService))).returns(() => pipEnvService.object); + serviceContainer + .setup((c) => c.get(TypeMoq.It.isValue(IInterpreterLocatorService), TypeMoq.It.isValue(PIPENV_SERVICE))) + .returns(() => pipEnvService.object); serviceContainer .setup((c) => c.get(TypeMoq.It.isValue(ITerminalActivationCommandProvider), TypeMoq.It.isAny())) .returns(() => terminalActivation.object); diff --git a/src/test/pythonEnvironments/discovery/locators/hasProviderFactory.unit.test.ts b/src/test/pythonEnvironments/discovery/locators/hasProviderFactory.unit.test.ts index 465c0c039f32..69ae6b318efa 100644 --- a/src/test/pythonEnvironments/discovery/locators/hasProviderFactory.unit.test.ts +++ b/src/test/pythonEnvironments/discovery/locators/hasProviderFactory.unit.test.ts @@ -13,7 +13,7 @@ import { ConfigurationService } from '../../../../client/common/configuration/se import { IConfigurationService } from '../../../../client/common/types'; import { IInterpreterHashProvider } from '../../../../client/interpreter/locators/types'; import { InterpreterHashProvider } from '../../../../client/pythonEnvironments/discovery/locators/services/hashProvider'; -import { InterpreterHashProviderFactory } from '../../../../client/pythonEnvironments/discovery/locators/services/hashProviderFactory'; +import { InterpeterHashProviderFactory } from '../../../../client/pythonEnvironments/discovery/locators/services/hashProviderFactory'; import { WindowsStoreInterpreter } from '../../../../client/pythonEnvironments/discovery/locators/services/windowsStoreInterpreter'; use(chaiAsPromised); @@ -22,14 +22,14 @@ suite('Interpretersx - Interpreter Hash Provider Factory', () => { let configService: IConfigurationService; let windowsStoreInterpreter: WindowsStoreInterpreter; let standardHashProvider: IInterpreterHashProvider; - let factory: InterpreterHashProviderFactory; + let factory: InterpeterHashProviderFactory; setup(() => { configService = mock(ConfigurationService); windowsStoreInterpreter = mock(WindowsStoreInterpreter); standardHashProvider = mock(InterpreterHashProvider); const windowsStoreInstance = instance(windowsStoreInterpreter); (windowsStoreInstance as any).then = undefined; - factory = new InterpreterHashProviderFactory( + factory = new InterpeterHashProviderFactory( instance(configService), windowsStoreInstance, windowsStoreInstance, diff --git a/src/test/pythonEnvironments/discovery/locators/interpreterWatcherBuilder.unit.test.ts b/src/test/pythonEnvironments/discovery/locators/interpreterWatcherBuilder.unit.test.ts index 729b90f8a201..07e31dd236c6 100644 --- a/src/test/pythonEnvironments/discovery/locators/interpreterWatcherBuilder.unit.test.ts +++ b/src/test/pythonEnvironments/discovery/locators/interpreterWatcherBuilder.unit.test.ts @@ -8,7 +8,7 @@ import { expect } from 'chai'; import { anything, instance, mock, when } from 'ts-mockito'; import { WorkspaceService } from '../../../../client/common/application/workspace'; -import { IInterpreterWatcherRegistry, WORKSPACE_VIRTUAL_ENV_SERVICE } from '../../../../client/interpreter/contracts'; +import { IInterpreterWatcher, WORKSPACE_VIRTUAL_ENV_SERVICE } from '../../../../client/interpreter/contracts'; import { ServiceContainer } from '../../../../client/ioc/container'; import { InterpreterWatcherBuilder } from '../../../../client/pythonEnvironments/discovery/locators/services/interpreterWatcherBuilder'; @@ -20,12 +20,9 @@ suite('Interpreters - Watcher Builder', () => { const watcher = { register: () => Promise.resolve() }; when(workspaceService.getWorkspaceFolder(anything())).thenReturn(); - when( - serviceContainer.get( - IInterpreterWatcherRegistry, - WORKSPACE_VIRTUAL_ENV_SERVICE - ) - ).thenReturn((watcher as any) as IInterpreterWatcherRegistry); + when(serviceContainer.get(IInterpreterWatcher, WORKSPACE_VIRTUAL_ENV_SERVICE)).thenReturn( + (watcher as any) as IInterpreterWatcher + ); const item = await builder.getWorkspaceVirtualEnvInterpreterWatcher(undefined); @@ -38,12 +35,9 @@ suite('Interpreters - Watcher Builder', () => { const watcher = { register: () => Promise.resolve() }; when(workspaceService.getWorkspaceFolder(anything())).thenReturn(); - when( - serviceContainer.get( - IInterpreterWatcherRegistry, - WORKSPACE_VIRTUAL_ENV_SERVICE - ) - ).thenReturn((watcher as any) as IInterpreterWatcherRegistry); + when(serviceContainer.get(IInterpreterWatcher, WORKSPACE_VIRTUAL_ENV_SERVICE)).thenReturn( + (watcher as any) as IInterpreterWatcher + ); const [item1, item2, item3] = await Promise.all([ builder.getWorkspaceVirtualEnvInterpreterWatcher(undefined), diff --git a/src/test/pythonEnvironments/legacyIOC.unit.test.ts b/src/test/pythonEnvironments/legacyIOC.unit.test.ts new file mode 100644 index 000000000000..218830370632 --- /dev/null +++ b/src/test/pythonEnvironments/legacyIOC.unit.test.ts @@ -0,0 +1,106 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +'use strict'; + +// tslint:disable: no-any + +import { instance, mock, verify } from 'ts-mockito'; +import { + CONDA_ENV_FILE_SERVICE, + CONDA_ENV_SERVICE, + CURRENT_PATH_SERVICE, + GLOBAL_VIRTUAL_ENV_SERVICE, + ICondaService, + IInterpreterLocatorHelper, + IInterpreterLocatorProgressService, + IInterpreterLocatorService, + IInterpreterWatcher, + IInterpreterWatcherBuilder, + IKnownSearchPathsForInterpreters, + INTERPRETER_LOCATOR_SERVICE, + IVirtualEnvironmentsSearchPathProvider, + KNOWN_PATH_SERVICE, + PIPENV_SERVICE, + WINDOWS_REGISTRY_SERVICE, + WORKSPACE_VIRTUAL_ENV_SERVICE +} from '../../client/interpreter/contracts'; +import { IPipEnvServiceHelper, IPythonInPathCommandProvider } from '../../client/interpreter/locators/types'; +import { ServiceManager } from '../../client/ioc/serviceManager'; +import { PythonInterpreterLocatorService } from '../../client/pythonEnvironments/discovery/locators'; +import { InterpreterLocatorHelper } from '../../client/pythonEnvironments/discovery/locators/helpers'; +import { InterpreterLocatorProgressService } from '../../client/pythonEnvironments/discovery/locators/progressService'; +import { CondaEnvFileService } from '../../client/pythonEnvironments/discovery/locators/services/condaEnvFileService'; +import { CondaEnvService } from '../../client/pythonEnvironments/discovery/locators/services/condaEnvService'; +import { CondaService } from '../../client/pythonEnvironments/discovery/locators/services/condaService'; +import { + CurrentPathService, + PythonInPathCommandProvider +} from '../../client/pythonEnvironments/discovery/locators/services/currentPathService'; +import { + GlobalVirtualEnvironmentsSearchPathProvider, + GlobalVirtualEnvService +} from '../../client/pythonEnvironments/discovery/locators/services/globalVirtualEnvService'; +import { InterpreterHashProvider } from '../../client/pythonEnvironments/discovery/locators/services/hashProvider'; +import { InterpeterHashProviderFactory } from '../../client/pythonEnvironments/discovery/locators/services/hashProviderFactory'; +import { InterpreterWatcherBuilder } from '../../client/pythonEnvironments/discovery/locators/services/interpreterWatcherBuilder'; +import { + KnownPathsService, + KnownSearchPathsForInterpreters +} from '../../client/pythonEnvironments/discovery/locators/services/KnownPathsService'; +import { PipEnvService } from '../../client/pythonEnvironments/discovery/locators/services/pipEnvService'; +import { PipEnvServiceHelper } from '../../client/pythonEnvironments/discovery/locators/services/pipEnvServiceHelper'; +import { WindowsRegistryService } from '../../client/pythonEnvironments/discovery/locators/services/windowsRegistryService'; +import { WindowsStoreInterpreter } from '../../client/pythonEnvironments/discovery/locators/services/windowsStoreInterpreter'; +import { + WorkspaceVirtualEnvironmentsSearchPathProvider, + WorkspaceVirtualEnvService +} from '../../client/pythonEnvironments/discovery/locators/services/workspaceVirtualEnvService'; +import { WorkspaceVirtualEnvWatcherService } from '../../client/pythonEnvironments/discovery/locators/services/workspaceVirtualEnvWatcherService'; +import { registerForIOC } from '../../client/pythonEnvironments/legacyIOC'; + +suite('Interpreters - Service Registry', () => { + test('Registrations', () => { + const serviceManager = mock(ServiceManager); + registerForIOC(instance(serviceManager)); + + [ + [IKnownSearchPathsForInterpreters, KnownSearchPathsForInterpreters], + [IVirtualEnvironmentsSearchPathProvider, GlobalVirtualEnvironmentsSearchPathProvider, 'global'], + [IVirtualEnvironmentsSearchPathProvider, WorkspaceVirtualEnvironmentsSearchPathProvider, 'workspace'], + + [ICondaService, CondaService], + [IPipEnvServiceHelper, PipEnvServiceHelper], + [IPythonInPathCommandProvider, PythonInPathCommandProvider], + + [IInterpreterWatcherBuilder, InterpreterWatcherBuilder], + + [IInterpreterLocatorService, PythonInterpreterLocatorService, INTERPRETER_LOCATOR_SERVICE], + [IInterpreterLocatorService, CondaEnvFileService, CONDA_ENV_FILE_SERVICE], + [IInterpreterLocatorService, CondaEnvService, CONDA_ENV_SERVICE], + [IInterpreterLocatorService, CurrentPathService, CURRENT_PATH_SERVICE], + [IInterpreterLocatorService, GlobalVirtualEnvService, GLOBAL_VIRTUAL_ENV_SERVICE], + [IInterpreterLocatorService, WorkspaceVirtualEnvService, WORKSPACE_VIRTUAL_ENV_SERVICE], + [IInterpreterLocatorService, PipEnvService, PIPENV_SERVICE], + + [IInterpreterLocatorService, WindowsRegistryService, WINDOWS_REGISTRY_SERVICE], + [IInterpreterLocatorService, KnownPathsService, KNOWN_PATH_SERVICE], + + [IInterpreterLocatorHelper, InterpreterLocatorHelper], + [IInterpreterLocatorProgressService, InterpreterLocatorProgressService], + + [WindowsStoreInterpreter, WindowsStoreInterpreter], + [InterpreterHashProvider, InterpreterHashProvider], + [InterpeterHashProviderFactory, InterpeterHashProviderFactory] + ].forEach((mapping) => { + verify(serviceManager.addSingleton.apply(serviceManager, mapping as any)).once(); + }); + verify( + serviceManager.add( + IInterpreterWatcher, + WorkspaceVirtualEnvWatcherService, + WORKSPACE_VIRTUAL_ENV_SERVICE + ) + ).once(); + }); +}); diff --git a/src/test/testing/pytest/pytest.discovery.test.ts b/src/test/testing/pytest/pytest.discovery.test.ts index 3ee16265b429..c1351e13ab33 100644 --- a/src/test/testing/pytest/pytest.discovery.test.ts +++ b/src/test/testing/pytest/pytest.discovery.test.ts @@ -22,9 +22,9 @@ import { IConfigurationService } from '../../../client/common/types'; import { IEnvironmentActivationService } from '../../../client/interpreter/activation/types'; import { ICondaService, IInterpreterService } from '../../../client/interpreter/contracts'; import { InterpreterService } from '../../../client/interpreter/interpreterService'; -import { IWindowsStoreInterpreter } from '../../../client/interpreter/locators/types'; import { IServiceContainer } from '../../../client/ioc/types'; import { CondaService } from '../../../client/pythonEnvironments/discovery/locators/services/condaService'; +import { WindowsStoreInterpreter } from '../../../client/pythonEnvironments/discovery/locators/services/windowsStoreInterpreter'; import { registerForIOC } from '../../../client/pythonEnvironments/legacyIOC'; import { CommandSource } from '../../../client/testing/common/constants'; import { ITestManagerFactory } from '../../../client/testing/common/types'; @@ -71,7 +71,7 @@ suite('Unit Tests - pytest - discovery with mocked process output', () => { @inject(IProcessServiceFactory) processServiceFactory: IProcessServiceFactory, @inject(IConfigurationService) private readonly _configService: IConfigurationService, @inject(ICondaService) condaService: ICondaService, - @inject(IWindowsStoreInterpreter) windowsStoreInterpreter: IWindowsStoreInterpreter, + @inject(WindowsStoreInterpreter) windowsStoreInterpreter: WindowsStoreInterpreter, @inject(IBufferDecoder) decoder: IBufferDecoder, @inject(IPlatformService) platformService: IPlatformService ) { diff --git a/src/test/testing/pytest/pytest.run.test.ts b/src/test/testing/pytest/pytest.run.test.ts index d4eca020f59c..d75a73869a8a 100644 --- a/src/test/testing/pytest/pytest.run.test.ts +++ b/src/test/testing/pytest/pytest.run.test.ts @@ -23,9 +23,9 @@ import { IConfigurationService } from '../../../client/common/types'; import { IEnvironmentActivationService } from '../../../client/interpreter/activation/types'; import { ICondaService, IInterpreterService } from '../../../client/interpreter/contracts'; import { InterpreterService } from '../../../client/interpreter/interpreterService'; -import { IWindowsStoreInterpreter } from '../../../client/interpreter/locators/types'; import { IServiceContainer } from '../../../client/ioc/types'; import { CondaService } from '../../../client/pythonEnvironments/discovery/locators/services/condaService'; +import { WindowsStoreInterpreter } from '../../../client/pythonEnvironments/discovery/locators/services/windowsStoreInterpreter'; import { registerForIOC } from '../../../client/pythonEnvironments/legacyIOC'; import { CommandSource } from '../../../client/testing/common/constants'; import { UnitTestDiagnosticService } from '../../../client/testing/common/services/unitTestDiagnosticService'; @@ -394,7 +394,7 @@ suite('Unit Tests - pytest - run with mocked process output', () => { @inject(IProcessServiceFactory) processServiceFactory: IProcessServiceFactory, @inject(IConfigurationService) private readonly _configService: IConfigurationService, @inject(ICondaService) condaService: ICondaService, - @inject(IWindowsStoreInterpreter) windowsStoreInterpreter: IWindowsStoreInterpreter, + @inject(WindowsStoreInterpreter) windowsStoreInterpreter: WindowsStoreInterpreter, @inject(IBufferDecoder) decoder: IBufferDecoder, @inject(IPlatformService) platformService: IPlatformService ) {