@@ -18,7 +18,12 @@ import {
1818 ResolveEnvironmentContext ,
1919 SetEnvironmentScope ,
2020} from '../../api' ;
21+ import { CondaStrings } from '../../common/localize' ;
22+ import { createDeferred , Deferred } from '../../common/utils/deferred' ;
23+ import { showErrorMessage , withProgress } from '../../common/window.apis' ;
24+ import { NativePythonFinder } from '../common/nativePythonFinder' ;
2125import {
26+ checkForNoPythonCondaEnvironment ,
2227 clearCondaCache ,
2328 createCondaEnvironment ,
2429 deleteCondaEnvironment ,
@@ -33,15 +38,10 @@ import {
3338 setCondaForWorkspace ,
3439 setCondaForWorkspaces ,
3540} from './condaUtils' ;
36- import { NativePythonFinder } from '../common/nativePythonFinder' ;
37- import { createDeferred , Deferred } from '../../common/utils/deferred' ;
38- import { showErrorMessage , withProgress } from '../../common/window.apis' ;
39- import { CondaStrings } from '../../common/localize' ;
4041
4142export class CondaEnvManager implements EnvironmentManager , Disposable {
4243 private collection : PythonEnvironment [ ] = [ ] ;
4344 private fsPathToEnv : Map < string , PythonEnvironment > = new Map ( ) ;
44- private disposablesMap : Map < string , Disposable > = new Map ( ) ;
4545 private globalEnv : PythonEnvironment | undefined ;
4646
4747 private readonly _onDidChangeEnvironment = new EventEmitter < DidChangeEnvironmentEventArgs > ( ) ;
@@ -70,7 +70,8 @@ export class CondaEnvManager implements EnvironmentManager, Disposable {
7070 iconPath ?: IconPath ;
7171
7272 public dispose ( ) {
73- this . disposablesMap . forEach ( ( d ) => d . dispose ( ) ) ;
73+ this . collection = [ ] ;
74+ this . fsPathToEnv . clear ( ) ;
7475 }
7576
7677 private _initialized : Deferred < void > | undefined ;
@@ -166,20 +167,7 @@ export class CondaEnvManager implements EnvironmentManager, Disposable {
166167 ) ;
167168 }
168169 if ( result ) {
169- this . disposablesMap . set (
170- result . envId . id ,
171- new Disposable ( ( ) => {
172- if ( result ) {
173- this . collection = this . collection . filter ( ( env ) => env . envId . id !== result ?. envId . id ) ;
174- Array . from ( this . fsPathToEnv . entries ( ) )
175- . filter ( ( [ , env ] ) => env . envId . id === result ?. envId . id )
176- . forEach ( ( [ uri ] ) => this . fsPathToEnv . delete ( uri ) ) ;
177- this . disposablesMap . delete ( result . envId . id ) ;
178- }
179- } ) ,
180- ) ;
181- this . collection . push ( result ) ;
182- this . _onDidChangeEnvironments . fire ( [ { kind : EnvironmentChangeKind . add , environment : result } ] ) ;
170+ this . addEnvironment ( result ) ;
183171 }
184172
185173 return result ;
@@ -189,12 +177,28 @@ export class CondaEnvManager implements EnvironmentManager, Disposable {
189177 }
190178 }
191179
180+ private addEnvironment ( environment : PythonEnvironment , raiseEvent : boolean = true ) : void {
181+ this . collection . push ( environment ) ;
182+ if ( raiseEvent ) {
183+ this . _onDidChangeEnvironments . fire ( [ { kind : EnvironmentChangeKind . add , environment : environment } ] ) ;
184+ }
185+ }
186+
187+ private removeEnvironment ( environment : PythonEnvironment , raiseEvent : boolean = true ) : void {
188+ this . collection = this . collection . filter ( ( env ) => env . envId . id !== environment . envId . id ) ;
189+ Array . from ( this . fsPathToEnv . entries ( ) )
190+ . filter ( ( [ , env ] ) => env . envId . id === environment . envId . id )
191+ . forEach ( ( [ uri ] ) => this . fsPathToEnv . delete ( uri ) ) ;
192+ if ( raiseEvent ) {
193+ this . _onDidChangeEnvironments . fire ( [ { kind : EnvironmentChangeKind . remove , environment } ] ) ;
194+ }
195+ }
196+
192197 async remove ( context : PythonEnvironment ) : Promise < void > {
193198 try {
194199 const projects = this . getProjectsForEnvironment ( context ) ;
200+ this . removeEnvironment ( context , false ) ;
195201 await deleteCondaEnvironment ( context , this . log ) ;
196- this . disposablesMap . get ( context . envId . id ) ?. dispose ( ) ;
197-
198202 setImmediate ( ( ) => {
199203 this . _onDidChangeEnvironments . fire ( [ { kind : EnvironmentChangeKind . remove , environment : context } ] ) ;
200204 projects . forEach ( ( project ) =>
@@ -207,9 +211,6 @@ export class CondaEnvManager implements EnvironmentManager, Disposable {
207211 }
208212 async refresh ( context : RefreshEnvironmentsScope ) : Promise < void > {
209213 if ( context === undefined ) {
210- this . disposablesMap . forEach ( ( d ) => d . dispose ( ) ) ;
211- this . disposablesMap . clear ( ) ;
212-
213214 await withProgress (
214215 {
215216 location : ProgressLocation . Window ,
@@ -252,18 +253,22 @@ export class CondaEnvManager implements EnvironmentManager, Disposable {
252253 }
253254
254255 async set ( scope : SetEnvironmentScope , environment ?: PythonEnvironment | undefined ) : Promise < void > {
256+ const checkedEnv = environment
257+ ? await checkForNoPythonCondaEnvironment ( this . nativeFinder , this , environment , this . api , this . log )
258+ : undefined ;
259+
255260 if ( scope === undefined ) {
256- await setCondaForGlobal ( environment ?. environmentPath ?. fsPath ) ;
261+ await setCondaForGlobal ( checkedEnv ?. environmentPath ?. fsPath ) ;
257262 } else if ( scope instanceof Uri ) {
258263 const folder = this . api . getPythonProject ( scope ) ;
259264 const fsPath = folder ?. uri ?. fsPath ?? scope . fsPath ;
260265 if ( fsPath ) {
261- if ( environment ) {
262- this . fsPathToEnv . set ( fsPath , environment ) ;
266+ if ( checkedEnv ) {
267+ this . fsPathToEnv . set ( fsPath , checkedEnv ) ;
263268 } else {
264269 this . fsPathToEnv . delete ( fsPath ) ;
265270 }
266- await setCondaForWorkspace ( fsPath , environment ?. environmentPath . fsPath ) ;
271+ await setCondaForWorkspace ( fsPath , checkedEnv ?. environmentPath . fsPath ) ;
267272 }
268273 } else if ( Array . isArray ( scope ) && scope . every ( ( u ) => u instanceof Uri ) ) {
269274 const projects : PythonProject [ ] = [ ] ;
@@ -278,25 +283,38 @@ export class CondaEnvManager implements EnvironmentManager, Disposable {
278283 const before : Map < string , PythonEnvironment | undefined > = new Map ( ) ;
279284 projects . forEach ( ( p ) => {
280285 before . set ( p . uri . fsPath , this . fsPathToEnv . get ( p . uri . fsPath ) ) ;
281- if ( environment ) {
282- this . fsPathToEnv . set ( p . uri . fsPath , environment ) ;
286+ if ( checkedEnv ) {
287+ this . fsPathToEnv . set ( p . uri . fsPath , checkedEnv ) ;
283288 } else {
284289 this . fsPathToEnv . delete ( p . uri . fsPath ) ;
285290 }
286291 } ) ;
287292
288293 await setCondaForWorkspaces (
289294 projects . map ( ( p ) => p . uri . fsPath ) ,
290- environment ?. environmentPath . fsPath ,
295+ checkedEnv ?. environmentPath . fsPath ,
291296 ) ;
292297
293298 projects . forEach ( ( p ) => {
294299 const b = before . get ( p . uri . fsPath ) ;
295- if ( b ?. envId . id !== environment ?. envId . id ) {
296- this . _onDidChangeEnvironment . fire ( { uri : p . uri , old : b , new : environment } ) ;
300+ if ( b ?. envId . id !== checkedEnv ?. envId . id ) {
301+ this . _onDidChangeEnvironment . fire ( { uri : p . uri , old : b , new : checkedEnv } ) ;
297302 }
298303 } ) ;
299304 }
305+
306+ if ( environment && checkedEnv && checkedEnv . envId . id !== environment . envId . id ) {
307+ this . removeEnvironment ( environment , false ) ;
308+ this . addEnvironment ( checkedEnv , false ) ;
309+ setImmediate ( ( ) => {
310+ this . _onDidChangeEnvironments . fire ( [
311+ { kind : EnvironmentChangeKind . remove , environment } ,
312+ { kind : EnvironmentChangeKind . add , environment : checkedEnv } ,
313+ ] ) ;
314+ const uri = scope ? ( scope instanceof Uri ? scope : scope [ 0 ] ) : undefined ;
315+ this . _onDidChangeEnvironment . fire ( { uri, old : environment , new : checkedEnv } ) ;
316+ } ) ;
317+ }
300318 }
301319
302320 async resolve ( context : ResolveEnvironmentContext ) : Promise < PythonEnvironment | undefined > {
0 commit comments