11// Copyright (c) Microsoft Corporation.
22// Licensed under the MIT License.
33
4- use std:: { env, path:: PathBuf } ;
4+ use std:: {
5+ env,
6+ path:: PathBuf ,
7+ sync:: { Arc , Mutex } ,
8+ } ;
59
610use pet_fs:: path:: norm_case;
711
@@ -14,10 +18,14 @@ pub trait Environment {
1418 fn get_know_global_search_locations ( & self ) -> Vec < PathBuf > ;
1519}
1620
17- pub struct EnvironmentApi { }
21+ pub struct EnvironmentApi {
22+ global_search_locations : Arc < Mutex < Vec < PathBuf > > > ,
23+ }
1824impl EnvironmentApi {
1925 pub fn new ( ) -> Self {
20- EnvironmentApi { }
26+ EnvironmentApi {
27+ global_search_locations : Arc :: new ( Mutex :: new ( vec ! [ ] ) ) ,
28+ }
2129 }
2230}
2331impl Default for EnvironmentApi {
@@ -38,7 +46,19 @@ impl Environment for EnvironmentApi {
3846 get_env_var ( key)
3947 }
4048 fn get_know_global_search_locations ( & self ) -> Vec < PathBuf > {
41- vec ! [ ]
49+ if self . global_search_locations . lock ( ) . unwrap ( ) . is_empty ( ) {
50+ let mut paths =
51+ env:: split_paths ( & self . get_env_var ( "PATH" . to_string ( ) ) . unwrap_or_default ( ) )
52+ . into_iter ( )
53+ . filter ( |p| p. exists ( ) )
54+ . collect :: < Vec < PathBuf > > ( ) ;
55+
56+ self . global_search_locations
57+ . lock ( )
58+ . unwrap ( )
59+ . append ( & mut paths) ;
60+ }
61+ self . global_search_locations . lock ( ) . unwrap ( ) . clone ( )
4262 }
4363}
4464
@@ -54,51 +74,62 @@ impl Environment for EnvironmentApi {
5474 get_env_var ( key)
5575 }
5676 fn get_know_global_search_locations ( & self ) -> Vec < PathBuf > {
57- let mut paths = env:: split_paths ( & self . get_env_var ( "PATH" . to_string ( ) ) . unwrap_or_default ( ) )
58- . collect :: < Vec < PathBuf > > ( ) ;
77+ if self . global_search_locations . lock ( ) . unwrap ( ) . is_empty ( ) {
78+ let mut paths =
79+ env:: split_paths ( & self . get_env_var ( "PATH" . to_string ( ) ) . unwrap_or_default ( ) )
80+ . collect :: < Vec < PathBuf > > ( ) ;
5981
60- vec ! [
61- PathBuf :: from( "/bin" ) ,
62- PathBuf :: from( "/etc" ) ,
63- PathBuf :: from( "/lib" ) ,
64- PathBuf :: from( "/lib/x86_64-linux-gnu" ) ,
65- PathBuf :: from( "/lib64" ) ,
66- PathBuf :: from( "/sbin" ) ,
67- PathBuf :: from( "/snap/bin" ) ,
68- PathBuf :: from( "/usr/bin" ) ,
69- PathBuf :: from( "/usr/games" ) ,
70- PathBuf :: from( "/usr/include" ) ,
71- PathBuf :: from( "/usr/lib" ) ,
72- PathBuf :: from( "/usr/lib/x86_64-linux-gnu" ) ,
73- PathBuf :: from( "/usr/lib64" ) ,
74- PathBuf :: from( "/usr/libexec" ) ,
75- PathBuf :: from( "/usr/local" ) ,
76- PathBuf :: from( "/usr/local/bin" ) ,
77- PathBuf :: from( "/usr/local/etc" ) ,
78- PathBuf :: from( "/usr/local/games" ) ,
79- PathBuf :: from( "/usr/local/lib" ) ,
80- PathBuf :: from( "/usr/local/sbin" ) ,
81- PathBuf :: from( "/usr/sbin" ) ,
82- PathBuf :: from( "/usr/share" ) ,
83- PathBuf :: from( "/home/bin" ) ,
84- PathBuf :: from( "/home/sbin" ) ,
85- PathBuf :: from( "/opt" ) ,
86- PathBuf :: from( "/opt/bin" ) ,
87- PathBuf :: from( "/opt/sbin" ) ,
88- ]
89- . iter ( )
90- . for_each ( |p| {
91- if !paths. contains ( p) {
92- paths. push ( p. clone ( ) ) ;
82+ vec ! [
83+ PathBuf :: from( "/bin" ) ,
84+ PathBuf :: from( "/etc" ) ,
85+ PathBuf :: from( "/lib" ) ,
86+ PathBuf :: from( "/lib/x86_64-linux-gnu" ) ,
87+ PathBuf :: from( "/lib64" ) ,
88+ PathBuf :: from( "/sbin" ) ,
89+ PathBuf :: from( "/snap/bin" ) ,
90+ PathBuf :: from( "/usr/bin" ) ,
91+ PathBuf :: from( "/usr/games" ) ,
92+ PathBuf :: from( "/usr/include" ) ,
93+ PathBuf :: from( "/usr/lib" ) ,
94+ PathBuf :: from( "/usr/lib/x86_64-linux-gnu" ) ,
95+ PathBuf :: from( "/usr/lib64" ) ,
96+ PathBuf :: from( "/usr/libexec" ) ,
97+ PathBuf :: from( "/usr/local" ) ,
98+ PathBuf :: from( "/usr/local/bin" ) ,
99+ PathBuf :: from( "/usr/local/etc" ) ,
100+ PathBuf :: from( "/usr/local/games" ) ,
101+ PathBuf :: from( "/usr/local/lib" ) ,
102+ PathBuf :: from( "/usr/local/sbin" ) ,
103+ PathBuf :: from( "/usr/sbin" ) ,
104+ PathBuf :: from( "/usr/share" ) ,
105+ PathBuf :: from( "/home/bin" ) ,
106+ PathBuf :: from( "/home/sbin" ) ,
107+ PathBuf :: from( "/opt" ) ,
108+ PathBuf :: from( "/opt/bin" ) ,
109+ PathBuf :: from( "/opt/sbin" ) ,
110+ ]
111+ . iter ( )
112+ . for_each ( |p| {
113+ if !paths. contains ( p) {
114+ paths. push ( p. clone ( ) ) ;
115+ }
116+ } ) ;
117+
118+ if let Some ( home) = self . get_user_home ( ) {
119+ paths. push ( home. join ( ".local" ) . join ( "bin" ) ) ;
93120 }
94- } ) ;
95121
96- if let Some ( home ) = self . get_user_home ( ) {
97- // PathBuf::from("~/.local/bin"),
98- paths . push ( home . join ( ".local" ) . join ( "bin" ) ) ;
99- }
122+ let mut paths = paths
123+ . into_iter ( )
124+ . filter ( |p| p . exists ( ) )
125+ . collect :: < Vec < PathBuf > > ( ) ;
100126
101- paths
127+ self . global_search_locations
128+ . lock ( )
129+ . unwrap ( )
130+ . append ( & mut paths) ;
131+ }
132+ self . global_search_locations . lock ( ) . unwrap ( ) . clone ( )
102133 }
103134}
104135
0 commit comments