1
1
use crate :: arch:: UefiArch ;
2
2
use anyhow:: { bail, Result } ;
3
+ use std:: env;
4
+ use std:: ffi:: OsString ;
3
5
use std:: process:: Command ;
4
6
5
7
#[ derive( Clone , Copy , Debug ) ]
@@ -86,6 +88,32 @@ pub enum CargoAction {
86
88
Test ,
87
89
}
88
90
91
+ /// Get a modified PATH to remove entries added by rustup. This is
92
+ /// necessary on Windows, see
93
+ /// https://github.com/rust-lang/rustup/issues/3031.
94
+ fn sanitized_path ( orig_path : OsString ) -> OsString {
95
+ // Modify the PATH to remove entries added by rustup. This is
96
+ // necessary on Windows, see https://github.com/rust-lang/rustup/issues/3031.
97
+ let paths = env:: split_paths ( & orig_path) ;
98
+ let sanitized_paths = paths. filter ( |path| {
99
+ !path
100
+ . components ( )
101
+ . any ( |component| component. as_os_str ( ) == ".rustup" )
102
+ } ) ;
103
+
104
+ env:: join_paths ( sanitized_paths) . expect ( "invalid PATH" )
105
+ }
106
+
107
+ /// Cargo automatically sets some env vars that can prevent the
108
+ /// channel arg (e.g. "+nightly") from working. Unset them in the
109
+ /// child's environment.
110
+ pub fn fix_nested_cargo_env ( cmd : & mut Command ) {
111
+ cmd. env_remove ( "RUSTC" ) ;
112
+ cmd. env_remove ( "RUSTDOC" ) ;
113
+ let orig_path = env:: var_os ( "PATH" ) . unwrap_or_default ( ) ;
114
+ cmd. env ( "PATH" , sanitized_path ( orig_path) ) ;
115
+ }
116
+
89
117
#[ derive( Debug ) ]
90
118
pub struct Cargo {
91
119
pub action : CargoAction ,
@@ -101,6 +129,8 @@ impl Cargo {
101
129
pub fn command ( & self ) -> Result < Command > {
102
130
let mut cmd = Command :: new ( "cargo" ) ;
103
131
132
+ fix_nested_cargo_env ( & mut cmd) ;
133
+
104
134
if let Some ( toolchain) = & self . toolchain {
105
135
cmd. arg ( & format ! ( "+{}" , toolchain) ) ;
106
136
}
@@ -193,6 +223,17 @@ mod tests {
193
223
) ;
194
224
}
195
225
226
+ #[ test]
227
+ fn test_sanitize_path ( ) {
228
+ let ( input, expected) = match env:: consts:: FAMILY {
229
+ "unix" => ( "Abc:/path/.rustup/cargo:Xyz" , "Abc:Xyz" ) ,
230
+ "windows" => ( "Abc;/path/.rustup/cargo;Xyz" , "Abc;Xyz" ) ,
231
+ _ => unimplemented ! ( ) ,
232
+ } ;
233
+
234
+ assert_eq ! ( sanitized_path( input. into( ) ) , expected) ;
235
+ }
236
+
196
237
#[ test]
197
238
fn test_cargo_command ( ) {
198
239
let cargo = Cargo {
0 commit comments