@@ -7,14 +7,15 @@ use crate::process::Process;
7
7
8
8
pub const RUST_RECURSION_COUNT_MAX : u32 = 20 ;
9
9
10
- pub ( crate ) fn prepend_path (
10
+ pub ( crate ) fn insert_path (
11
11
name : & str ,
12
12
prepend : Vec < PathBuf > ,
13
+ append : Option < PathBuf > ,
13
14
cmd : & mut Command ,
14
15
process : & Process ,
15
16
) {
16
17
let old_value = process. var_os ( name) ;
17
- let parts = if let Some ( ref v) = old_value {
18
+ let mut parts = if let Some ( ref v) = old_value {
18
19
let mut tail = env:: split_paths ( v) . collect :: < VecDeque < _ > > ( ) ;
19
20
for path in prepend. into_iter ( ) . rev ( ) {
20
21
if !tail. contains ( & path) {
@@ -26,6 +27,12 @@ pub(crate) fn prepend_path(
26
27
prepend. into ( )
27
28
} ;
28
29
30
+ if let Some ( path) = append {
31
+ if !parts. contains ( & path) {
32
+ parts. push_back ( path) ;
33
+ }
34
+ }
35
+
29
36
if let Ok ( new_value) = env:: join_paths ( parts) {
30
37
cmd. env ( name, new_value) ;
31
38
}
@@ -77,7 +84,7 @@ mod tests {
77
84
let path_z = PathBuf :: from ( z) ;
78
85
path_entries. push ( path_z) ;
79
86
80
- prepend_path ( "PATH" , path_entries, & mut cmd, & tp. process ) ;
87
+ insert_path ( "PATH" , path_entries, None , & mut cmd, & tp. process ) ;
81
88
let envs: Vec < _ > = cmd. get_envs ( ) . collect ( ) ;
82
89
83
90
assert_eq ! (
@@ -99,4 +106,82 @@ mod tests {
99
106
) , ]
100
107
) ;
101
108
}
109
+
110
+ #[ test]
111
+ fn append_unique_path ( ) {
112
+ let mut vars = HashMap :: new ( ) ;
113
+ vars. env (
114
+ "PATH" ,
115
+ env:: join_paths ( [ "/home/a/.cargo/bin" , "/home/b/.cargo/bin" ] . iter ( ) ) . unwrap ( ) ,
116
+ ) ;
117
+ let tp = TestProcess :: with_vars ( vars) ;
118
+ #[ cfg( windows) ]
119
+ let _path_guard = RegistryGuard :: new ( & USER_PATH ) . unwrap ( ) ;
120
+
121
+ #[ track_caller]
122
+ fn check ( tp : & TestProcess , path_entries : Vec < PathBuf > , append : & str , expected : & [ & str ] ) {
123
+ let mut cmd = Command :: new ( "test" ) ;
124
+
125
+ insert_path (
126
+ "PATH" ,
127
+ path_entries,
128
+ Some ( append. into ( ) ) ,
129
+ & mut cmd,
130
+ & tp. process ,
131
+ ) ;
132
+ let envs: Vec < _ > = cmd. get_envs ( ) . collect ( ) ;
133
+
134
+ assert_eq ! (
135
+ envs,
136
+ & [ (
137
+ OsStr :: new( "PATH" ) ,
138
+ Some ( env:: join_paths( expected. iter( ) ) . unwrap( ) . as_os_str( ) )
139
+ ) , ]
140
+ ) ;
141
+ }
142
+
143
+ check (
144
+ & tp,
145
+ Vec :: new ( ) ,
146
+ "/home/z/.cargo/bin" ,
147
+ & [
148
+ "/home/a/.cargo/bin" ,
149
+ "/home/b/.cargo/bin" ,
150
+ "/home/z/.cargo/bin" ,
151
+ ] ,
152
+ ) ;
153
+ check (
154
+ & tp,
155
+ Vec :: new ( ) ,
156
+ "/home/a/.cargo/bin" ,
157
+ & [ "/home/a/.cargo/bin" , "/home/b/.cargo/bin" ] ,
158
+ ) ;
159
+ check (
160
+ & tp,
161
+ Vec :: new ( ) ,
162
+ "/home/b/.cargo/bin" ,
163
+ & [ "/home/a/.cargo/bin" , "/home/b/.cargo/bin" ] ,
164
+ ) ;
165
+ check (
166
+ & tp,
167
+ Vec :: from ( [ "/home/c/.cargo/bin" . into ( ) ] ) ,
168
+ "/home/c/.cargo/bin" ,
169
+ & [
170
+ "/home/c/.cargo/bin" ,
171
+ "/home/a/.cargo/bin" ,
172
+ "/home/b/.cargo/bin" ,
173
+ ] ,
174
+ ) ;
175
+ check (
176
+ & tp,
177
+ Vec :: from ( [ "/home/c/.cargo/bin" . into ( ) ] ) ,
178
+ "/home/z/.cargo/bin" ,
179
+ & [
180
+ "/home/c/.cargo/bin" ,
181
+ "/home/a/.cargo/bin" ,
182
+ "/home/b/.cargo/bin" ,
183
+ "/home/z/.cargo/bin" ,
184
+ ] ,
185
+ ) ;
186
+ }
102
187
}
0 commit comments