2
2
// Licensed under the MIT License.
3
3
4
4
use crate :: known;
5
+ use crate :: known:: Environment ;
6
+ use crate :: locator:: Locator ;
5
7
use crate :: messaging;
8
+ use crate :: messaging:: EnvManager ;
6
9
use crate :: messaging:: EnvManagerType ;
10
+ use crate :: messaging:: MessageDispatcher ;
11
+ use crate :: messaging:: PythonEnvironment ;
7
12
use crate :: utils:: find_python_binary_path;
13
+ use crate :: utils:: PythonEnv ;
8
14
use regex:: Regex ;
15
+ use std:: collections:: HashMap ;
9
16
use std:: env;
10
17
use std:: path:: { Path , PathBuf } ;
11
18
@@ -129,7 +136,7 @@ fn get_conda_bin_names() -> Vec<&'static str> {
129
136
}
130
137
131
138
/// Find the conda binary on the PATH environment variable
132
- fn find_conda_binary_on_path ( environment : & impl known:: Environment ) -> Option < PathBuf > {
139
+ fn find_conda_binary_on_path ( environment : & dyn known:: Environment ) -> Option < PathBuf > {
133
140
let paths = environment. get_env_var ( "PATH" . to_string ( ) ) ?;
134
141
for path in env:: split_paths ( & paths) {
135
142
for bin in get_conda_bin_names ( ) {
@@ -148,7 +155,7 @@ fn find_conda_binary_on_path(environment: &impl known::Environment) -> Option<Pa
148
155
}
149
156
150
157
#[ cfg( windows) ]
151
- fn get_known_conda_locations ( environment : & impl known:: Environment ) -> Vec < PathBuf > {
158
+ fn get_known_conda_locations ( environment : & dyn known:: Environment ) -> Vec < PathBuf > {
152
159
let user_profile = environment. get_env_var ( "USERPROFILE" . to_string ( ) ) . unwrap ( ) ;
153
160
let program_data = environment. get_env_var ( "PROGRAMDATA" . to_string ( ) ) . unwrap ( ) ;
154
161
let all_user_profile = environment
@@ -170,7 +177,7 @@ fn get_known_conda_locations(environment: &impl known::Environment) -> Vec<PathB
170
177
}
171
178
172
179
#[ cfg( unix) ]
173
- fn get_known_conda_locations ( environment : & impl known:: Environment ) -> Vec < PathBuf > {
180
+ fn get_known_conda_locations ( environment : & dyn known:: Environment ) -> Vec < PathBuf > {
174
181
let mut known_paths = vec ! [
175
182
PathBuf :: from( "/opt/anaconda3/bin" ) ,
176
183
PathBuf :: from( "/opt/miniconda3/bin" ) ,
@@ -192,7 +199,7 @@ fn get_known_conda_locations(environment: &impl known::Environment) -> Vec<PathB
192
199
}
193
200
194
201
/// Find conda binary in known locations
195
- fn find_conda_binary_in_known_locations ( environment : & impl known:: Environment ) -> Option < PathBuf > {
202
+ fn find_conda_binary_in_known_locations ( environment : & dyn known:: Environment ) -> Option < PathBuf > {
196
203
let conda_bin_names = get_conda_bin_names ( ) ;
197
204
let known_locations = get_known_conda_locations ( environment) ;
198
205
for location in known_locations {
@@ -209,7 +216,7 @@ fn find_conda_binary_in_known_locations(environment: &impl known::Environment) -
209
216
}
210
217
211
218
/// Find the conda binary on the system
212
- pub fn find_conda_binary ( environment : & impl known:: Environment ) -> Option < PathBuf > {
219
+ pub fn find_conda_binary ( environment : & dyn known:: Environment ) -> Option < PathBuf > {
213
220
let conda_binary_on_path = find_conda_binary_on_path ( environment) ;
214
221
match conda_binary_on_path {
215
222
Some ( conda_binary_on_path) => Some ( conda_binary_on_path) ,
@@ -232,7 +239,7 @@ pub fn get_conda_version(conda_binary: &PathBuf) -> Option<String> {
232
239
get_version_from_meta_json ( & conda_python_json_path)
233
240
}
234
241
235
- fn get_conda_envs_from_environment_txt ( environment : & impl known:: Environment ) -> Vec < String > {
242
+ fn get_conda_envs_from_environment_txt ( environment : & dyn known:: Environment ) -> Vec < String > {
236
243
let mut envs = vec ! [ ] ;
237
244
let home = environment. get_user_home ( ) ;
238
245
match home {
@@ -255,7 +262,7 @@ fn get_conda_envs_from_environment_txt(environment: &impl known::Environment) ->
255
262
256
263
fn get_known_env_locations (
257
264
conda_bin : & PathBuf ,
258
- environment : & impl known:: Environment ,
265
+ environment : & dyn known:: Environment ,
259
266
) -> Vec < String > {
260
267
let mut paths = vec ! [ ] ;
261
268
let home = environment. get_user_home ( ) ;
@@ -290,7 +297,7 @@ fn get_known_env_locations(
290
297
291
298
fn get_conda_envs_from_known_env_locations (
292
299
conda_bin : & PathBuf ,
293
- environment : & impl known:: Environment ,
300
+ environment : & dyn known:: Environment ,
294
301
) -> Vec < String > {
295
302
let mut envs = vec ! [ ] ;
296
303
for location in get_known_env_locations ( conda_bin, environment) {
@@ -333,7 +340,7 @@ struct CondaEnv {
333
340
334
341
fn get_distinct_conda_envs (
335
342
conda_bin : & PathBuf ,
336
- environment : & impl known:: Environment ,
343
+ environment : & dyn known:: Environment ,
337
344
) -> Vec < CondaEnv > {
338
345
let mut envs = get_conda_envs_from_environment_txt ( environment) ;
339
346
let mut known_envs = get_conda_envs_from_known_env_locations ( conda_bin, environment) ;
@@ -377,52 +384,91 @@ fn get_distinct_conda_envs(
377
384
conda_envs
378
385
}
379
386
380
- pub fn find_and_report (
381
- dispatcher : & mut impl messaging:: MessageDispatcher ,
382
- environment : & impl known:: Environment ,
383
- ) {
384
- let conda_binary = find_conda_binary ( environment) ;
385
- match conda_binary {
386
- Some ( conda_binary) => {
387
- let env_manager = messaging:: EnvManager :: new (
388
- conda_binary. clone ( ) ,
389
- get_conda_version ( & conda_binary) ,
390
- EnvManagerType :: Conda ,
387
+ pub struct Conda < ' a > {
388
+ pub environments : HashMap < String , PythonEnvironment > ,
389
+ pub manager : Option < EnvManager > ,
390
+ pub environment : & ' a dyn Environment ,
391
+ }
392
+
393
+ impl Conda < ' _ > {
394
+ pub fn with < ' a > ( environment : & ' a impl Environment ) -> Conda {
395
+ Conda {
396
+ environments : HashMap :: new ( ) ,
397
+ environment,
398
+ manager : None ,
399
+ }
400
+ }
401
+ }
402
+
403
+ impl Locator for Conda < ' _ > {
404
+ fn is_known ( & self , python_executable : & PathBuf ) -> bool {
405
+ self . environments
406
+ . contains_key ( python_executable. to_str ( ) . unwrap_or_default ( ) )
407
+ }
408
+
409
+ fn track_if_compatible ( & mut self , _env : & PythonEnv ) -> bool {
410
+ // We will find everything in gather
411
+ false
412
+ }
413
+
414
+ fn gather ( & mut self ) -> Option < ( ) > {
415
+ let conda_binary = find_conda_binary ( self . environment ) ?;
416
+ let manager = EnvManager :: new (
417
+ conda_binary. clone ( ) ,
418
+ get_conda_version ( & conda_binary) ,
419
+ EnvManagerType :: Conda ,
420
+ ) ;
421
+ self . manager = Some ( manager. clone ( ) ) ;
422
+
423
+ let envs = get_distinct_conda_envs ( & conda_binary, self . environment ) ;
424
+ for env in envs {
425
+ let executable = find_python_binary_path ( Path :: new ( & env. path ) ) ;
426
+ let env = messaging:: PythonEnvironment :: new (
427
+ Some ( env. name . to_string ( ) ) ,
428
+ executable. clone ( ) ,
429
+ messaging:: PythonEnvironmentCategory :: Conda ,
430
+ get_conda_python_version ( & env. path ) ,
431
+ Some ( env. path . clone ( ) ) ,
432
+ Some ( env. path . clone ( ) ) ,
433
+ Some ( manager. clone ( ) ) ,
434
+ if env. named {
435
+ Some ( vec ! [
436
+ conda_binary. to_string_lossy( ) . to_string( ) ,
437
+ "run" . to_string( ) ,
438
+ "-n" . to_string( ) ,
439
+ env. name. to_string( ) ,
440
+ "python" . to_string( ) ,
441
+ ] )
442
+ } else {
443
+ Some ( vec ! [
444
+ conda_binary. to_string_lossy( ) . to_string( ) ,
445
+ "run" . to_string( ) ,
446
+ "-p" . to_string( ) ,
447
+ env. path. to_string_lossy( ) . to_string( ) ,
448
+ "python" . to_string( ) ,
449
+ ] )
450
+ } ,
391
451
) ;
392
- dispatcher. report_environment_manager ( env_manager. clone ( ) ) ;
393
-
394
- let envs = get_distinct_conda_envs ( & conda_binary, environment) ;
395
- for env in envs {
396
- let executable = find_python_binary_path ( Path :: new ( & env. path ) ) ;
397
- let params = messaging:: PythonEnvironment :: new (
398
- Some ( env. name . to_string ( ) ) ,
399
- executable,
400
- messaging:: PythonEnvironmentCategory :: Conda ,
401
- get_conda_python_version ( & env. path ) ,
402
- Some ( env. path . clone ( ) ) ,
403
- Some ( env. path . clone ( ) ) ,
404
- Some ( env_manager. clone ( ) ) ,
405
- if env. named {
406
- Some ( vec ! [
407
- conda_binary. to_string_lossy( ) . to_string( ) ,
408
- "run" . to_string( ) ,
409
- "-n" . to_string( ) ,
410
- env. name. to_string( ) ,
411
- "python" . to_string( ) ,
412
- ] )
413
- } else {
414
- Some ( vec ! [
415
- conda_binary. to_string_lossy( ) . to_string( ) ,
416
- "run" . to_string( ) ,
417
- "-p" . to_string( ) ,
418
- env. path. to_string_lossy( ) . to_string( ) ,
419
- "python" . to_string( ) ,
420
- ] )
421
- } ,
422
- ) ;
423
- dispatcher. report_environment ( params) ;
452
+
453
+ if let Some ( exe) = executable {
454
+ self . environments
455
+ . insert ( exe. to_str ( ) . unwrap_or_default ( ) . to_string ( ) , env) ;
456
+ } else if let Some ( env_path) = env. env_path . clone ( ) {
457
+ self . environments
458
+ . insert ( env_path. to_str ( ) . unwrap ( ) . to_string ( ) , env) ;
424
459
}
425
460
}
426
- None => ( ) ,
461
+
462
+ Some ( ( ) )
463
+ }
464
+
465
+ fn report ( & self , reporter : & mut dyn MessageDispatcher ) {
466
+ if let Some ( manager) = & self . manager {
467
+ reporter. report_environment_manager ( manager. clone ( ) ) ;
468
+ }
469
+
470
+ for env in self . environments . values ( ) {
471
+ reporter. report_environment ( env. clone ( ) ) ;
472
+ }
427
473
}
428
474
}
0 commit comments