33
44import { injectable } from 'inversify' ;
55import * as vscode from 'vscode' ;
6+ import { IExtensionSingleActivationService } from '../activation/types' ;
67import { DiscoveryVariants } from '../common/experiments/groups' ;
78import { getVersionString , parseVersion } from '../common/utils/version' ;
89import {
@@ -135,21 +136,45 @@ function convertEnvInfo(info: PythonEnvInfo): PythonEnvironment {
135136export interface IPythonEnvironments extends ILocator { }
136137
137138@injectable ( )
138- class ComponentAdapter implements IComponentAdapter {
139+ class ComponentAdapter implements IComponentAdapter , IExtensionSingleActivationService {
139140 // this will be set based on experiment
140- private _enabled ?: boolean ;
141+ private enabled ?: boolean ;
142+
143+ private readonly refreshing = new vscode . EventEmitter < void > ( ) ;
144+
145+ private readonly refreshed = new vscode . EventEmitter < void > ( ) ;
141146
142147 constructor (
143148 // The adapter only wraps one thing: the component API.
144149 private readonly api : IPythonEnvironments ,
145150 private readonly environmentsSecurity : IEnvironmentsSecurity ,
146151 ) { }
147152
153+ public async activate ( ) : Promise < void > {
154+ this . enabled = ( await Promise . all (
155+ [
156+ inExperiment ( DiscoveryVariants . discoverWithFileWatching ) ,
157+ inExperiment ( DiscoveryVariants . discoveryWithoutFileWatching ) ,
158+ ] ,
159+ ) ) . includes ( true ) ;
160+ }
161+
162+ // IInterpreterLocatorProgressHandler
163+
164+ // A result of `undefined` means "Fall back to the old code!"
165+ public get onRefreshing ( ) : vscode . Event < void > | undefined {
166+ return this . enabled ? this . refreshing . event : undefined ;
167+ }
168+
169+ public get onRefreshed ( ) : vscode . Event < void > | undefined {
170+ return this . enabled ? this . refreshing . event : undefined ;
171+ }
172+
148173 // IInterpreterHelper
149174
150175 // A result of `undefined` means "Fall back to the old code!"
151176 public async getInterpreterInformation ( pythonPath : string ) : Promise < undefined | Partial < PythonEnvironment > > {
152- if ( ! ( await this . isEnabled ( ) ) ) {
177+ if ( ! this . enabled ) {
153178 return undefined ;
154179 }
155180 const env = await this . api . resolveEnv ( pythonPath ) ;
@@ -161,7 +186,7 @@ class ComponentAdapter implements IComponentAdapter {
161186
162187 // A result of `undefined` means "Fall back to the old code!"
163188 public async isMacDefaultPythonPath ( pythonPath : string ) : Promise < boolean | undefined > {
164- if ( ! ( await this . isEnabled ( ) ) ) {
189+ if ( ! this . enabled ) {
165190 return undefined ;
166191 }
167192 const env = await this . api . resolveEnv ( pythonPath ) ;
@@ -180,7 +205,7 @@ class ComponentAdapter implements IComponentAdapter {
180205 pythonPath : string ,
181206 resource ?: vscode . Uri ,
182207 ) : Promise < undefined | PythonEnvironment > {
183- if ( ! ( await this . isEnabled ( ) ) ) {
208+ if ( ! this . enabled ) {
184209 return undefined ;
185210 }
186211 const info = buildEnvInfo ( { executable : pythonPath } ) ;
@@ -201,7 +226,7 @@ class ComponentAdapter implements IComponentAdapter {
201226
202227 // A result of `undefined` means "Fall back to the old code!"
203228 public async isCondaEnvironment ( interpreterPath : string ) : Promise < boolean | undefined > {
204- if ( ! ( await this . isEnabled ( ) ) ) {
229+ if ( ! this . enabled ) {
205230 return undefined ;
206231 }
207232 const env = await this . api . resolveEnv ( interpreterPath ) ;
@@ -213,7 +238,7 @@ class ComponentAdapter implements IComponentAdapter {
213238
214239 // A result of `undefined` means "Fall back to the old code!"
215240 public async getCondaEnvironment ( interpreterPath : string ) : Promise < CondaEnvironmentInfo | undefined > {
216- if ( ! ( await this . isEnabled ( ) ) ) {
241+ if ( ! this . enabled ) {
217242 return undefined ;
218243 }
219244 const env = await this . api . resolveEnv ( interpreterPath ) ;
@@ -234,7 +259,7 @@ class ComponentAdapter implements IComponentAdapter {
234259
235260 // A result of `undefined` means "Fall back to the old code!"
236261 public async isWindowsStoreInterpreter ( pythonPath : string ) : Promise < boolean | undefined > {
237- if ( ! ( await this . isEnabled ( ) ) ) {
262+ if ( ! this . enabled ) {
238263 return undefined ;
239264 }
240265 const env = await this . api . resolveEnv ( pythonPath ) ;
@@ -248,13 +273,11 @@ class ComponentAdapter implements IComponentAdapter {
248273
249274 // A result of `undefined` means "Fall back to the old code!"
250275 public get hasInterpreters ( ) : Promise < boolean | undefined > {
251- return this . isEnabled ( ) . then ( ( enabled ) => {
252- if ( enabled ) {
253- const iterator = this . api . iterEnvs ( ) ;
254- return iterator . next ( ) . then ( ( res ) => ! res . done ) ;
255- }
256- return undefined ;
257- } ) ;
276+ if ( ! this . enabled ) {
277+ return Promise . resolve ( undefined ) ;
278+ }
279+ const iterator = this . api . iterEnvs ( ) ;
280+ return iterator . next ( ) . then ( ( res ) => ! res . done ) ;
258281 }
259282
260283 // A result of `undefined` means "Fall back to the old code!"
@@ -267,9 +290,10 @@ class ComponentAdapter implements IComponentAdapter {
267290 // onSuggestion?: boolean;
268291 // }
269292 ) : Promise < PythonEnvironment [ ] | undefined > {
270- if ( ! ( await this . isEnabled ( ) ) ) {
293+ if ( ! this . enabled ) {
271294 return undefined ;
272295 }
296+ this . refreshing . fire ( ) ; // Notify locators are locating.
273297 if ( options ?. onSuggestion ) {
274298 // For now, until we have the concept of trusted workspaces, we assume all interpreters as safe
275299 // to run once user has triggered discovery, i.e interacted with the extension.
@@ -288,20 +312,9 @@ class ComponentAdapter implements IComponentAdapter {
288312
289313 const iterator = this . api . iterEnvs ( query ) ;
290314 const envs = await getEnvs ( iterator ) ;
291- return envs . map ( convertEnvInfo ) ;
292- }
293-
294- private async isEnabled ( ) : Promise < boolean > {
295- if ( this . _enabled === undefined ) {
296- this . _enabled = ( await Promise . all (
297- [
298- inExperiment ( DiscoveryVariants . discoverWithFileWatching ) ,
299- inExperiment ( DiscoveryVariants . discoveryWithoutFileWatching ) ,
300- ] ,
301- ) ) . includes ( true ) ;
302- }
303-
304- return this . _enabled ;
315+ const legacyEnvs = envs . map ( convertEnvInfo ) ;
316+ this . refreshed . fire ( ) ; // Notify all locators have completed locating.
317+ return legacyEnvs ;
305318 }
306319}
307320
@@ -399,4 +412,5 @@ export function registerNewDiscoveryForIOC(
399412 IComponentAdapter ,
400413 new ComponentAdapter ( api , environmentsSecurity ) ,
401414 ) ;
415+ serviceManager . addBinding ( IComponentAdapter , IExtensionSingleActivationService ) ;
402416}
0 commit comments