@@ -10,6 +10,7 @@ import { getWorkspaceStateValue, updateWorkspaceStateValue } from '../../common/
10
10
import { traceError } from '../../logging' ;
11
11
import { IExtensionActivationService } from '../../activation/types' ;
12
12
import { StopWatch } from '../../common/utils/stopWatch' ;
13
+ import { isParentPath } from '../../common/platform/fs-paths' ;
13
14
14
15
const MEMENTO_KEY = 'userSelectedEnvPath' ;
15
16
@@ -75,13 +76,24 @@ export class RecommendedEnvironmentService implements IRecommendedEnvironmentSer
75
76
if ( recommendedEnv ) {
76
77
return { environment : recommendedEnv , reason : preferred . reason } ;
77
78
}
79
+ const globalEnv = await this . api . resolveEnvironment ( this . api . getActiveEnvironmentPath ( ) ) ;
80
+ if ( activeEnv && globalEnv ?. path !== activeEnv ?. path ) {
81
+ // User has definitely got a workspace specific environment selected.
82
+ // Given the fact that global !== workspace env, we can safely assume that
83
+ // at some time, the user has selected a workspace specific environment.
84
+ // This applies to cases where the user has selected a workspace specific environment before this version of the extension
85
+ // and we did not store it in the workspace state.
86
+ // So we can safely return the global environment as the recommended environment.
87
+ return { environment : activeEnv , reason : 'workspaceUserSelected' } ;
88
+ }
78
89
return undefined ;
79
90
}
80
- getRecommededInternal (
91
+ async getRecommededInternal (
81
92
resource : Resource ,
82
- ) :
93
+ ) : Promise <
83
94
| { environmentPath : string ; reason : 'globalUserSelected' | 'workspaceUserSelected' | 'defaultRecommended' }
84
- | undefined {
95
+ | undefined
96
+ > {
85
97
let workspaceState : string | undefined = undefined ;
86
98
try {
87
99
workspaceState = getWorkspaceStateValue < string > ( MEMENTO_KEY ) ;
@@ -106,6 +118,16 @@ export class RecommendedEnvironmentService implements IRecommendedEnvironmentSer
106
118
}
107
119
}
108
120
121
+ if ( workspace . workspaceFolders ?. length && this . api ) {
122
+ // Check if we have a .venv or .conda environment in the workspace
123
+ // This is required for cases where user has selected a workspace specific environment
124
+ // but before this version of the extension, we did not store it in the workspace state.
125
+ const workspaceEnv = await getWorkspaceSpecificVirtualEnvironment ( this . api , resource ) ;
126
+ if ( workspaceEnv ) {
127
+ return { environmentPath : workspaceEnv . path , reason : 'workspaceUserSelected' } ;
128
+ }
129
+ }
130
+
109
131
const globalSelectedEnvPath = this . extensionContext . globalState . get < string | undefined > ( MEMENTO_KEY ) ;
110
132
if ( globalSelectedEnvPath ) {
111
133
return { environmentPath : globalSelectedEnvPath , reason : 'globalUserSelected' } ;
@@ -119,6 +141,37 @@ export class RecommendedEnvironmentService implements IRecommendedEnvironmentSer
119
141
}
120
142
}
121
143
144
+ async function getWorkspaceSpecificVirtualEnvironment ( api : PythonExtension [ 'environments' ] , resource : Resource ) {
145
+ const workspaceUri =
146
+ ( resource ? workspace . getWorkspaceFolder ( resource ) ?. uri : undefined ) ||
147
+ ( workspace . workspaceFolders ?. length ? workspace . workspaceFolders [ 0 ] . uri : undefined ) ;
148
+ if ( ! workspaceUri ) {
149
+ return undefined ;
150
+ }
151
+ let workspaceEnv = api . known . find ( ( env ) => {
152
+ if ( ! env . environment ?. folderUri ) {
153
+ return false ;
154
+ }
155
+ if ( env . environment . type !== 'VirtualEnvironment' && env . environment . type !== 'Conda' ) {
156
+ return false ;
157
+ }
158
+ return isParentPath ( env . environment . folderUri . fsPath , workspaceUri . fsPath ) ;
159
+ } ) ;
160
+ let resolvedEnv = workspaceEnv ? api . resolveEnvironment ( workspaceEnv ) : undefined ;
161
+ if ( resolvedEnv ) {
162
+ return resolvedEnv ;
163
+ }
164
+ workspaceEnv = api . known . find ( ( env ) => {
165
+ // Look for any other type of env thats inside this workspace
166
+ // Or look for an env thats associated with this workspace (pipenv or the like).
167
+ return (
168
+ ( env . environment ?. folderUri && isParentPath ( env . environment . folderUri . fsPath , workspaceUri . fsPath ) ) ||
169
+ ( env . environment ?. workspaceFolder && env . environment . workspaceFolder . uri . fsPath === workspaceUri . fsPath )
170
+ ) ;
171
+ } ) ;
172
+ return workspaceEnv ? api . resolveEnvironment ( workspaceEnv ) : undefined ;
173
+ }
174
+
122
175
function getDataToStore ( environmentPath : string | undefined , uri : Uri | undefined ) : string | undefined {
123
176
if ( ! workspace . workspaceFolders ?. length ) {
124
177
return environmentPath ;
0 commit comments