3
3
4
4
import { injectable } from 'inversify' ;
5
5
import * as vscode from 'vscode' ;
6
+ import { IExtensionSingleActivationService } from '../activation/types' ;
6
7
import { DiscoveryVariants } from '../common/experiments/groups' ;
7
8
import { getVersionString , parseVersion } from '../common/utils/version' ;
8
9
import {
@@ -135,21 +136,45 @@ function convertEnvInfo(info: PythonEnvInfo): PythonEnvironment {
135
136
export interface IPythonEnvironments extends ILocator { }
136
137
137
138
@injectable ( )
138
- class ComponentAdapter implements IComponentAdapter {
139
+ class ComponentAdapter implements IComponentAdapter , IExtensionSingleActivationService {
139
140
// 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 > ( ) ;
141
146
142
147
constructor (
143
148
// The adapter only wraps one thing: the component API.
144
149
private readonly api : IPythonEnvironments ,
145
150
private readonly environmentsSecurity : IEnvironmentsSecurity ,
146
151
) { }
147
152
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
+
148
173
// IInterpreterHelper
149
174
150
175
// A result of `undefined` means "Fall back to the old code!"
151
176
public async getInterpreterInformation ( pythonPath : string ) : Promise < undefined | Partial < PythonEnvironment > > {
152
- if ( ! ( await this . isEnabled ( ) ) ) {
177
+ if ( ! this . enabled ) {
153
178
return undefined ;
154
179
}
155
180
const env = await this . api . resolveEnv ( pythonPath ) ;
@@ -161,7 +186,7 @@ class ComponentAdapter implements IComponentAdapter {
161
186
162
187
// A result of `undefined` means "Fall back to the old code!"
163
188
public async isMacDefaultPythonPath ( pythonPath : string ) : Promise < boolean | undefined > {
164
- if ( ! ( await this . isEnabled ( ) ) ) {
189
+ if ( ! this . enabled ) {
165
190
return undefined ;
166
191
}
167
192
const env = await this . api . resolveEnv ( pythonPath ) ;
@@ -180,7 +205,7 @@ class ComponentAdapter implements IComponentAdapter {
180
205
pythonPath : string ,
181
206
resource ?: vscode . Uri ,
182
207
) : Promise < undefined | PythonEnvironment > {
183
- if ( ! ( await this . isEnabled ( ) ) ) {
208
+ if ( ! this . enabled ) {
184
209
return undefined ;
185
210
}
186
211
const info = buildEnvInfo ( { executable : pythonPath } ) ;
@@ -201,7 +226,7 @@ class ComponentAdapter implements IComponentAdapter {
201
226
202
227
// A result of `undefined` means "Fall back to the old code!"
203
228
public async isCondaEnvironment ( interpreterPath : string ) : Promise < boolean | undefined > {
204
- if ( ! ( await this . isEnabled ( ) ) ) {
229
+ if ( ! this . enabled ) {
205
230
return undefined ;
206
231
}
207
232
const env = await this . api . resolveEnv ( interpreterPath ) ;
@@ -213,7 +238,7 @@ class ComponentAdapter implements IComponentAdapter {
213
238
214
239
// A result of `undefined` means "Fall back to the old code!"
215
240
public async getCondaEnvironment ( interpreterPath : string ) : Promise < CondaEnvironmentInfo | undefined > {
216
- if ( ! ( await this . isEnabled ( ) ) ) {
241
+ if ( ! this . enabled ) {
217
242
return undefined ;
218
243
}
219
244
const env = await this . api . resolveEnv ( interpreterPath ) ;
@@ -234,7 +259,7 @@ class ComponentAdapter implements IComponentAdapter {
234
259
235
260
// A result of `undefined` means "Fall back to the old code!"
236
261
public async isWindowsStoreInterpreter ( pythonPath : string ) : Promise < boolean | undefined > {
237
- if ( ! ( await this . isEnabled ( ) ) ) {
262
+ if ( ! this . enabled ) {
238
263
return undefined ;
239
264
}
240
265
const env = await this . api . resolveEnv ( pythonPath ) ;
@@ -248,13 +273,11 @@ class ComponentAdapter implements IComponentAdapter {
248
273
249
274
// A result of `undefined` means "Fall back to the old code!"
250
275
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 ) ;
258
281
}
259
282
260
283
// A result of `undefined` means "Fall back to the old code!"
@@ -267,9 +290,10 @@ class ComponentAdapter implements IComponentAdapter {
267
290
// onSuggestion?: boolean;
268
291
// }
269
292
) : Promise < PythonEnvironment [ ] | undefined > {
270
- if ( ! ( await this . isEnabled ( ) ) ) {
293
+ if ( ! this . enabled ) {
271
294
return undefined ;
272
295
}
296
+ this . refreshing . fire ( ) ; // Notify locators are locating.
273
297
if ( options ?. onSuggestion ) {
274
298
// For now, until we have the concept of trusted workspaces, we assume all interpreters as safe
275
299
// to run once user has triggered discovery, i.e interacted with the extension.
@@ -288,20 +312,9 @@ class ComponentAdapter implements IComponentAdapter {
288
312
289
313
const iterator = this . api . iterEnvs ( query ) ;
290
314
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 ;
305
318
}
306
319
}
307
320
@@ -399,4 +412,5 @@ export function registerNewDiscoveryForIOC(
399
412
IComponentAdapter ,
400
413
new ComponentAdapter ( api , environmentsSecurity ) ,
401
414
) ;
415
+ serviceManager . addBinding ( IComponentAdapter , IExtensionSingleActivationService ) ;
402
416
}
0 commit comments