Skip to content

Commit bc36f20

Browse files
committed
cargo/config: Don't canonicalize joined [env] relative paths
Cargo doesn't do this either, and canonicalization requires the path to exist which it does not have to.
1 parent adc955f commit bc36f20

File tree

1 file changed

+17
-40
lines changed

1 file changed

+17
-40
lines changed

xbuild/src/cargo/config.rs

+17-40
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use anyhow::{Context, Result};
1+
use anyhow::Result;
22
use serde::Deserialize;
33
use std::{
44
borrow::Cow,
@@ -104,7 +104,7 @@ pub enum EnvOption {
104104
}
105105

106106
impl EnvOption {
107-
/// Retrieve the value and canonicalize it relative to `config_parent` when [`EnvOption::Value::relative`] is set.
107+
/// Retrieve the value and join it to `config_parent` when [`EnvOption::Value::relative`] is set.
108108
///
109109
/// `config_parent` is the directory containing `.cargo/config.toml` where this was parsed from.
110110
pub fn resolve_value(&self, config_parent: impl AsRef<Path>) -> Result<Cow<'_, str>> {
@@ -113,16 +113,13 @@ impl EnvOption {
113113
value,
114114
relative: true,
115115
force: _,
116-
} => {
117-
let value = config_parent.as_ref().join(value);
118-
let value = dunce::canonicalize(&value)
119-
.with_context(|| format!("Failed to canonicalize `{}`", value.display()))?;
120-
value
121-
.into_os_string()
122-
.into_string()
123-
.map_err(VarError::NotUnicode)?
124-
.into()
125-
}
116+
} => config_parent
117+
.as_ref()
118+
.join(value)
119+
.into_os_string()
120+
.into_string()
121+
.map_err(VarError::NotUnicode)?
122+
.into(),
126123
Self::String(value) | Self::Value { value, .. } => value.into(),
127124
})
128125
}
@@ -225,46 +222,26 @@ CARGO_SUBCOMMAND_TEST_ENV_FORCED = { value = "forced", force = true }"#;
225222
}
226223

227224
#[test]
228-
fn test_env_canonicalization() {
229-
use std::ffi::OsStr;
230-
225+
fn test_env_relative() {
231226
let toml = r#"
232227
[env]
233228
CARGO_SUBCOMMAND_TEST_ENV_SRC_DIR = { value = "src", force = true, relative = true }
234229
"#;
235230

236231
let config = LocalizedConfig {
237232
config: toml::from_str::<Config>(toml).unwrap(),
238-
workspace: PathBuf::new(),
233+
// Path does not have to exist
234+
workspace: PathBuf::from("my/work/space"),
239235
};
240236

241237
config.set_env_vars().unwrap();
242238

243239
let path = std::env::var("CARGO_SUBCOMMAND_TEST_ENV_SRC_DIR")
244-
.expect("Canonicalization for a known-to-exist ./src folder should not fail");
240+
.expect("Relative env var should always be set");
245241
let path = PathBuf::from(path);
246-
assert!(path.is_absolute());
247-
assert!(path.is_dir());
248-
assert_eq!(path.file_name(), Some(OsStr::new("src")));
249-
250-
let toml = r#"
251-
[env]
252-
CARGO_SUBCOMMAND_TEST_ENV_INEXISTENT_DIR = { value = "blahblahthisfolderdoesntexist", force = true, relative = true }
253-
"#;
254-
255-
let config = LocalizedConfig {
256-
config: toml::from_str::<Config>(toml).unwrap(),
257-
workspace: PathBuf::new(),
258-
};
259-
260-
let e = config.set_env_vars().unwrap_err();
261-
262-
assert_eq!(
263-
e.to_string(),
264-
"Failed to canonicalize `blahblahthisfolderdoesntexist`"
265-
);
266-
assert_eq!(
267-
e.root_cause().to_string(),
268-
"No such file or directory (os error 2)"
242+
assert!(
243+
path.is_relative(),
244+
"Workspace was not absolute so this shouldn't either"
269245
);
246+
assert_eq!(path, Path::new("my/work/space/src"));
270247
}

0 commit comments

Comments
 (0)