From 60036d43e1c2df2f46fbcab360a6a1f48b3eed67 Mon Sep 17 00:00:00 2001 From: Georges Farah Date: Thu, 25 Jun 2026 10:59:32 +0200 Subject: [PATCH] fix(crate_universe): fix OUTPUT_BASE env var value format in crates_vendor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The OUTPUT_BASE env var override inserted `format!("output_base: {}", path)` as the HashMap value. However, the `bazel info` output parser splits each line on `:` and stores only the part after the colon as the value: let (k, v) = line.split_at(line.find(':')?); Ok((k.to_string(), (v[1..]).trim().to_string())) So for `bazel info` output like "output_base: /data/output", the HashMap contains {"output_base" => "/data/output"}. But the OUTPUT_BASE override stored the FULL formatted string as the value: {"output_base" => "output_base: /data/output"}. When TryFrom later converts this to a PathBuf via `.map(Into::into)`, it produces PathBuf("output_base: /data/output") — an invalid path. This means the OUTPUT_BASE env var has never worked correctly. Fix by storing the raw path string without the prefix. Also extract `parse_bazel_info` from `try_new` so the parsing and env var override logic can be unit-tested without spawning a subprocess. --- crate_universe/src/cli/vendor.rs | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/crate_universe/src/cli/vendor.rs b/crate_universe/src/cli/vendor.rs index 1349e4b909..3ab12b3a53 100644 --- a/crate_universe/src/cli/vendor.rs +++ b/crate_universe/src/cli/vendor.rs @@ -168,6 +168,12 @@ impl BazelInfo { } let output = String::from_utf8_lossy(output.stdout.as_slice()); + Self::parse_bazel_info(&output) + } + + /// Parse `bazel info` output into a `BazelInfo`. The `OUTPUT_BASE` + /// environment variable, when set, overrides the parsed output_base. + fn parse_bazel_info(output: &str) -> anyhow::Result { let mut bazel_info: HashMap = output .trim() .split('\n') @@ -183,7 +189,7 @@ impl BazelInfo { // Allow a predefined environment variable to take precedent. This // solves for the specific needs of Bazel CI on Github. if let Ok(path) = env::var("OUTPUT_BASE") { - bazel_info.insert("output_base".to_owned(), format!("output_base: {}", path)); + bazel_info.insert("output_base".to_owned(), path); }; BazelInfo::try_from(bazel_info) @@ -409,4 +415,21 @@ mod tests { ); assert_eq!(PathBuf::from("/tmp/output_base"), info.output_base); } + + #[test] + fn test_parse_bazel_info_output_base_env_override() { + let bazel_info_output = "release: 8.0.0\noutput_base: /original/path"; + + // Without OUTPUT_BASE set, parse_bazel_info uses the parsed value. + env::remove_var("OUTPUT_BASE"); + let info = BazelInfo::parse_bazel_info(bazel_info_output).unwrap(); + assert_eq!(PathBuf::from("/original/path"), info.output_base); + + // With OUTPUT_BASE set, it overrides the parsed value. + env::set_var("OUTPUT_BASE", "/override/path"); + let info = BazelInfo::parse_bazel_info(bazel_info_output).unwrap(); + assert_eq!(PathBuf::from("/override/path"), info.output_base); + + env::remove_var("OUTPUT_BASE"); + } }