@@ -11,23 +11,44 @@ use indicatif::ProgressStyle;
11
11
use linked_hash_map:: LinkedHashMap ;
12
12
use regex:: RegexBuilder ;
13
13
use semver:: Version ;
14
+ use serde:: Deserialize ;
14
15
use std:: collections:: { BTreeMap , HashSet , HashMap } ;
15
16
use std:: env;
16
17
use std:: ffi:: OsStr ;
17
18
use std:: fs;
18
19
use std:: fs:: File ;
19
20
use std:: io:: BufReader ;
20
21
use std:: path:: { Path , PathBuf } ;
22
+ use std:: str:: FromStr ;
21
23
use tracing:: { debug, info, trace, warn, warn_span} ;
22
24
use tracing_indicatif:: span_ext:: IndicatifSpanExt ;
23
25
26
+ use crate :: util:: get_setting;
27
+
24
28
pub struct CommandDiscovery {
25
29
// use BTreeMap so that the results are sorted by the typename, the Vec is sorted by version
26
30
resources : BTreeMap < String , Vec < DscResource > > ,
27
31
adapters : BTreeMap < String , Vec < DscResource > > ,
28
32
adapted_resources : BTreeMap < String , Vec < DscResource > > ,
29
33
}
30
34
35
+ #[ derive( Deserialize ) ]
36
+ pub struct ResourcePathSetting {
37
+ allow_env_override : bool ,
38
+ append_env_path : bool ,
39
+ directories : Vec < String >
40
+ }
41
+
42
+ impl Default for ResourcePathSetting {
43
+ fn default ( ) -> ResourcePathSetting {
44
+ ResourcePathSetting {
45
+ allow_env_override : true ,
46
+ append_env_path : true ,
47
+ directories : vec ! [ ] ,
48
+ }
49
+ }
50
+ }
51
+
31
52
impl CommandDiscovery {
32
53
pub fn new ( ) -> CommandDiscovery {
33
54
CommandDiscovery {
@@ -37,31 +58,58 @@ impl CommandDiscovery {
37
58
}
38
59
}
39
60
61
+ fn get_resource_path_setting ( ) -> Result < ResourcePathSetting , DscError >
62
+ {
63
+ if let Ok ( v) = get_setting ( "resource_path" ) {
64
+ if let Ok ( resource_path_setting) = serde_json:: from_value ( v) {
65
+ return Ok ( resource_path_setting) ;
66
+ }
67
+ }
68
+
69
+ return Err ( DscError :: Operation ( "Could not read resource_path setting" . to_string ( ) ) ) ;
70
+ }
71
+
40
72
fn get_resource_paths ( ) -> Result < Vec < PathBuf > , DscError >
41
73
{
74
+ let mut resource_path_setting = ResourcePathSetting :: default ( ) ;
75
+ if let Ok ( v) = Self :: get_resource_path_setting ( ) {
76
+ resource_path_setting = v;
77
+ } else {
78
+ debug ! ( "Could not read resource_path setting" ) ;
79
+ }
80
+
42
81
let mut using_custom_path = false ;
82
+ let mut paths: Vec < PathBuf > = vec ! [ ] ;
43
83
44
- // try DSC_RESOURCE_PATH env var first otherwise use PATH
45
- let path_env = if let Some ( value) = env:: var_os ( "DSC_RESOURCE_PATH" ) {
84
+ let dsc_resource_path = env:: var_os ( "DSC_RESOURCE_PATH" ) ;
85
+ if resource_path_setting. allow_env_override && dsc_resource_path. is_some ( ) {
86
+ let value = dsc_resource_path. unwrap ( ) ;
46
87
debug ! ( "Using DSC_RESOURCE_PATH: {:?}" , value. to_string_lossy( ) ) ;
47
88
using_custom_path = true ;
48
- value
89
+ paths . append ( & mut env :: split_paths ( & value) . collect :: < Vec < _ > > ( ) ) ;
49
90
} else {
50
- trace ! ( "DSC_RESOURCE_PATH not set, trying PATH" ) ;
51
- match env:: var_os ( "PATH" ) {
52
- Some ( value) => {
53
- trace ! ( "Original PATH: {:?}" , value. to_string_lossy( ) ) ;
54
- value
55
- } ,
56
- None => {
57
- return Err ( DscError :: Operation ( "Failed to get PATH environment variable" . to_string ( ) ) ) ;
91
+ for p in resource_path_setting. directories {
92
+ if let Ok ( v) = PathBuf :: from_str ( & p) {
93
+ paths. push ( v) ;
58
94
}
59
95
}
60
- } ;
61
96
62
- let mut paths = env:: split_paths ( & path_env) . collect :: < Vec < _ > > ( ) ;
97
+ if resource_path_setting. append_env_path {
98
+ trace ! ( "Appending PATH to resource_path" ) ;
99
+ match env:: var_os ( "PATH" ) {
100
+ Some ( value) => {
101
+ trace ! ( "Original PATH: {:?}" , value. to_string_lossy( ) ) ;
102
+ paths. append ( & mut env:: split_paths ( & value) . collect :: < Vec < _ > > ( ) ) ;
103
+ } ,
104
+ None => {
105
+ return Err ( DscError :: Operation ( "Failed to get PATH environment variable" . to_string ( ) ) ) ;
106
+ }
107
+ }
108
+ }
109
+ }
110
+
63
111
// remove duplicate entries
64
- let mut uniques = HashSet :: new ( ) ;
112
+ let mut uniques: HashSet < PathBuf > = HashSet :: new ( ) ;
65
113
paths. retain ( |e|uniques. insert ( ( * e) . clone ( ) ) ) ;
66
114
67
115
// if exe home is not already in PATH env var then add it to env var and list of searched paths
@@ -75,13 +123,16 @@ impl CommandDiscovery {
75
123
paths. push ( exe_home_pb) ;
76
124
77
125
if let Ok ( new_path) = env:: join_paths ( paths. clone ( ) ) {
78
- debug ! ( "Using PATH: {:?}" , new_path. to_string_lossy( ) ) ;
79
126
env:: set_var ( "PATH" , & new_path) ;
80
127
}
81
128
}
82
129
}
83
130
} ;
84
131
132
+ if let Ok ( final_resource_path) = env:: join_paths ( paths. clone ( ) ) {
133
+ debug ! ( "Using Resource Path: {:?}" , final_resource_path. to_string_lossy( ) ) ;
134
+ }
135
+
85
136
Ok ( paths)
86
137
}
87
138
}
0 commit comments