@@ -7,7 +7,8 @@ use environments::{get_conda_environment_info, CondaEnvironment};
7
7
use log:: error;
8
8
use manager:: CondaManager ;
9
9
use pet_core:: {
10
- os_environment:: Environment , python_environment:: PythonEnvironment , Locator , LocatorResult ,
10
+ os_environment:: Environment , python_environment:: PythonEnvironment , reporter:: Reporter ,
11
+ Locator , LocatorResult ,
11
12
} ;
12
13
use pet_utils:: env:: PythonEnv ;
13
14
use std:: {
@@ -147,73 +148,86 @@ impl Locator for Conda {
147
148
None
148
149
}
149
150
150
- fn find ( & self ) -> Option < LocatorResult > {
151
- // 1. Get a list of all know conda environments
152
- let known_conda_envs =
153
- get_conda_environments ( & get_conda_environment_paths ( & self . env_vars ) , & None ) ;
154
- let mut new_managers = vec ! [ ] ;
155
- {
156
- let mut managers = self . managers . lock ( ) . unwrap ( ) ;
157
- // 2. Go through all conda dirs and build the conda managers.
158
- for env in & known_conda_envs {
159
- if let Some ( conda_dir) = & env. conda_dir {
160
- if managers. contains_key ( conda_dir) {
161
- continue ;
151
+ fn find ( & self , reporter : & dyn Reporter ) {
152
+ let env_vars = self . env_vars . clone ( ) ;
153
+ thread:: scope ( |s| {
154
+ // 1. Get a list of all know conda environments file paths
155
+ let possible_conda_envs = get_conda_environment_paths ( & env_vars) ;
156
+ for path in possible_conda_envs {
157
+ s. spawn ( move || {
158
+ // 2. Get the details of the conda environment
159
+ // This we do not get any details, then its not a conda environment
160
+ let env = get_conda_environment_info ( & path, & None ) ?;
161
+
162
+ // 3. If we have a conda environment without a conda_dir
163
+ // Then we will not be able to get the manager.
164
+ // Either way report this environment
165
+ if env. conda_dir . is_none ( ) {
166
+ // We will still return the conda env even though we do not have the manager.
167
+ // This might seem incorrect, however the tool is about discovering environments.
168
+ // The client can activate this env either using another conda manager or using the activation scripts
169
+ error ! ( "Unable to find Conda Manager for the Conda env: {:?}" , env) ;
170
+ let prefix = env. prefix . clone ( ) ;
171
+ let env = env. to_python_environment ( None , None ) ;
172
+ let mut environments = self . environments . lock ( ) . unwrap ( ) ;
173
+ environments. insert ( prefix, env. clone ( ) ) ;
174
+ reporter. report_environment ( & env) ;
175
+ return None ;
162
176
}
163
- if let Some ( manager) = CondaManager :: from ( conda_dir) {
164
- new_managers. push ( manager. to_manager ( ) ) ;
165
- managers. insert ( conda_dir. clone ( ) , manager) ;
177
+
178
+ // 3. We have a conda environment with a conda_dir (above we handled the case when its not found)
179
+ // We will try to get the manager for this conda_dir
180
+ let prefix = env. clone ( ) . prefix . clone ( ) ;
181
+
182
+ {
183
+ // 3.1 Check if we have already reported this environment.
184
+ // Closure to quickly release lock
185
+ let environments = self . environments . lock ( ) . unwrap ( ) ;
186
+ if environments. contains_key ( & env. prefix ) {
187
+ return None ;
188
+ }
166
189
}
167
- }
168
- }
169
- }
170
190
171
- let mut environments = self . environments . lock ( ) . unwrap ( ) ;
172
- let mut new_environments: Vec < PythonEnvironment > = vec ! [ ] ;
173
- // 3. Go through each environment we know of and build the python environments.
174
- for known_env in & known_conda_envs {
175
- if environments. contains_key ( & known_env. prefix ) {
176
- continue ;
177
- }
178
- if let Some ( conda_dir) = & known_env. conda_dir {
179
- if let Some ( manager) = self . get_manager ( conda_dir) {
180
- let env = known_env. to_python_environment (
181
- Some ( manager. conda_dir . clone ( ) ) ,
182
- Some ( manager. to_manager ( ) ) ,
183
- ) ;
184
- environments. insert ( known_env. prefix . clone ( ) , env. clone ( ) ) ;
185
- new_environments. push ( env) ;
186
- } else {
187
- // We will still return the conda env even though we do not have the manager.
188
- // This might seem incorrect, however the tool is about discovering environments.
189
- // The client can activate this env either using another conda manager or using the activation scripts
190
- error ! ( "Unable to find Conda Manager for Conda env (even though we have a conda_dir {:?}): Env Details = {:?}" , conda_dir, known_env) ;
191
- let env = known_env. to_python_environment ( Some ( conda_dir. clone ( ) ) , None ) ;
192
- environments. insert ( known_env. prefix . clone ( ) , env. clone ( ) ) ;
193
- new_environments. push ( env) ;
194
- }
195
- } else {
196
- // We will still return the conda env even though we do not have the manager.
197
- // This might seem incorrect, however the tool is about discovering environments.
198
- // The client can activate this env either using another conda manager or using the activation scripts
199
- error ! (
200
- "Unable to find Conda Manager for the Conda env: {:?}" ,
201
- known_env
202
- ) ;
203
- let env = known_env. to_python_environment ( None , None ) ;
204
- environments. insert ( known_env. prefix . clone ( ) , env. clone ( ) ) ;
205
- new_environments. push ( env) ;
206
- }
207
- }
208
191
209
- if new_managers. is_empty ( ) && new_environments. is_empty ( ) {
210
- return None ;
211
- }
192
+ // 4 Get the manager for this env.
193
+ let conda_dir = & env. conda_dir . clone ( ) ?;
194
+ let managers = self . managers . lock ( ) . unwrap ( ) ;
195
+ let mut manager = managers. get ( conda_dir) . cloned ( ) ;
196
+ drop ( managers) ;
212
197
213
- Some ( LocatorResult {
214
- managers : new_managers,
215
- environments : new_environments,
216
- } )
198
+ if manager. is_none ( ) {
199
+ // 4.1 Build the manager from the conda dir if we do not have it.
200
+ if let Some ( conda_manager) = CondaManager :: from ( conda_dir) {
201
+ reporter. report_manager ( & conda_manager. to_manager ( ) ) ;
202
+ let mut managers = self . managers . lock ( ) . unwrap ( ) ;
203
+ managers. insert ( conda_dir. to_path_buf ( ) . clone ( ) , conda_manager. clone ( ) ) ;
204
+ manager = Some ( conda_manager) ;
205
+ }
206
+ }
207
+
208
+ // 5. Report this env.
209
+ if let Some ( manager) = manager {
210
+ let env = env. to_python_environment (
211
+ Some ( manager. conda_dir . clone ( ) ) ,
212
+ Some ( manager. to_manager ( ) ) ,
213
+ ) ;
214
+ let mut environments = self . environments . lock ( ) . unwrap ( ) ;
215
+ environments. insert ( prefix. clone ( ) , env. clone ( ) ) ;
216
+ reporter. report_environment ( & env) ;
217
+ } else {
218
+ // We will still return the conda env even though we do not have the manager.
219
+ // This might seem incorrect, however the tool is about discovering environments.
220
+ // The client can activate this env either using another conda manager or using the activation scripts
221
+ error ! ( "Unable to find Conda Manager for Conda env (even though we have a conda_dir {:?}): Env Details = {:?}" , conda_dir, env) ;
222
+ let env = env. to_python_environment ( Some ( conda_dir. clone ( ) ) , None ) ;
223
+ let mut environments = self . environments . lock ( ) . unwrap ( ) ;
224
+ environments. insert ( prefix. clone ( ) , env. clone ( ) ) ;
225
+ reporter. report_environment ( & env) ;
226
+ }
227
+ Option :: < ( ) > :: Some ( ( ) )
228
+ } ) ;
229
+ }
230
+ } ) ;
217
231
}
218
232
}
219
233
0 commit comments