Skip to content

Commit 450092e

Browse files
Merge pull request #1559 from nicholasbishop/bishop-fix-rebuilds
Fix unwanted rebuilds in xtask commands
2 parents 848be99 + 1970393 commit 450092e

File tree

2 files changed

+31
-15
lines changed

2 files changed

+31
-15
lines changed

xtask/src/cargo.rs

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -216,12 +216,28 @@ fn sanitized_path(orig_path: OsString) -> OsString {
216216
env::join_paths(sanitized_paths).expect("invalid PATH")
217217
}
218218

219-
/// Cargo automatically sets some env vars that can prevent the
220-
/// channel arg (e.g. "+nightly") from working. Unset them in the
221-
/// child's environment.
222-
pub fn fix_nested_cargo_env(cmd: &mut Command) {
219+
/// Update a command env to make nested cargo invocations work correctly.
220+
///
221+
/// Cargo automatically sets some env vars that cause problems with nested cargo
222+
/// invocations. In particular, these env vars can:
223+
/// * Cause unwanted rebuilds, e.g. running `cargo xtask test` multiple times
224+
/// will rebuild every time because cached dependencies are marked as stale.
225+
/// * Prevent channels args (e.g. "+nightly") from working.
226+
///
227+
/// Some related issues:
228+
/// * <https://github.com/rust-lang/cargo/issues/15099>
229+
/// * <https://github.com/rust-lang/rustup/issues/3031>
230+
fn fix_nested_cargo_env(cmd: &mut Command) {
223231
cmd.env_remove("RUSTC");
224232
cmd.env_remove("RUSTDOC");
233+
234+
// Clear all vars starting with `CARGO`.
235+
for (name, _) in env::vars() {
236+
if name.starts_with("CARGO") {
237+
cmd.env_remove(name);
238+
}
239+
}
240+
225241
let orig_path = env::var_os("PATH").unwrap_or_default();
226242
cmd.env("PATH", sanitized_path(orig_path));
227243
}

xtask/src/util.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,15 @@ use std::process::Command;
88
/// Example: "VAR=val program --arg1 arg2".
99
pub fn command_to_string(cmd: &Command) -> String {
1010
// Format env vars as "name=val".
11-
let ignore_var = ["PATH", "RUSTC", "RUSTDOC"];
1211
let mut parts = cmd
1312
.get_envs()
14-
// Filter out some internally-set variables that would just
15-
// clutter the output.
16-
.filter(|(name, _)| !ignore_var.contains(&name.to_str().unwrap_or_default()))
13+
// Filter out variables that are set or cleared by
14+
// `fix_nested_cargo_env`, as they would clutter the output.
15+
.filter(|(name, val)| {
16+
*name != "PATH"
17+
// Exclude any variables cleared with `Command::env_remove`.
18+
&& val.is_some()
19+
})
1720
.map(|(name, val)| {
1821
format!(
1922
"{}={}",
@@ -53,13 +56,10 @@ mod tests {
5356
#[test]
5457
fn test_command_to_string() {
5558
let mut cmd = Command::new("MyCommand");
56-
cmd.args(["abc", "123"]).envs([
57-
("VAR1", "val1"),
58-
("VAR2", "val2"),
59-
("PATH", "pathval"),
60-
("RUSTC", "rustcval"),
61-
("RUSTDOC", "rustdocval"),
62-
]);
59+
cmd.args(["abc", "123"])
60+
.envs([("VAR1", "val1"), ("VAR2", "val2"), ("PATH", "pathval")])
61+
.env_remove("RUSTC")
62+
.env_remove("CARGO");
6363
assert_eq!(
6464
command_to_string(&cmd),
6565
"VAR1=val1 VAR2=val2 MyCommand abc 123"

0 commit comments

Comments
 (0)