From 3b7446fdf38ef80f0eebce3d1382b916167f1e9c Mon Sep 17 00:00:00 2001 From: David Knaack Date: Fri, 31 Dec 2021 01:24:21 +0100 Subject: [PATCH] fix(rust): fix overrides on windows and set cwd (#3359) --- src/modules/rust.rs | 72 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 55 insertions(+), 17 deletions(-) diff --git a/src/modules/rust.rs b/src/modules/rust.rs index 58a75ad3..c28e847b 100644 --- a/src/modules/rust.rs +++ b/src/modules/rust.rs @@ -79,7 +79,7 @@ fn get_module_version(context: &Context, config: &RustConfig) -> Option .or_else(|| find_rust_toolchain_file(context)) .or_else(|| execute_rustup_default(context)) { - match execute_rustup_run_rustc_version(&toolchain) { + match execute_rustup_run_rustc_version(context, &toolchain) { RustupRunRustcVersionOutcome::RustcVersion(rustc_version) => { format_rustc_version(&rustc_version, config.version_format) } @@ -87,12 +87,12 @@ fn get_module_version(context: &Context, config: &RustConfig) -> Option RustupRunRustcVersionOutcome::RustupNotWorking => { // If `rustup` is not in `$PATH` or cannot be executed for other reasons, we can // safely execute `rustc --version`. - format_rustc_version(&execute_rustc_version()?, config.version_format) + format_rustc_version(&execute_rustc_version(context)?, config.version_format) } RustupRunRustcVersionOutcome::Err => None, } } else { - format_rustc_version(&execute_rustc_version()?, config.version_format) + format_rustc_version(&execute_rustc_version(context)?, config.version_format) } } @@ -123,15 +123,21 @@ fn extract_toolchain_from_rustup_override_list(stdout: &str, cwd: &Path) -> Opti if stdout == "no overrides\n" { return None; } + // use display version of path, also allows stripping \\?\ + let cwd = cwd.to_string_lossy(); + // rustup strips \\?\ prefix + #[cfg(windows)] + let cwd = cwd.strip_prefix(r"\\?\").unwrap_or(&cwd); + stdout .lines() .filter_map(|line| { - let mut words = line.split_whitespace(); - let dir = words.next()?; - let toolchain = words.next()?; - Some((dir, toolchain)) + let (dir, toolchain) = line.split_once('\t')?; + Some((dir.trim(), toolchain.trim())) }) - .find(|(dir, _)| cwd.starts_with(dir)) + // find most specific match + .filter(|(dir, _)| cwd.starts_with(dir)) + .max_by_key(|(dir, _)| dir.len()) .map(|(_, toolchain)| toolchain.to_owned()) } @@ -199,9 +205,16 @@ fn find_rust_toolchain_file(context: &Context) -> Option { } } -fn execute_rustup_run_rustc_version(toolchain: &str) -> RustupRunRustcVersionOutcome { +fn execute_rustup_run_rustc_version( + context: &Context, + toolchain: &str, +) -> RustupRunRustcVersionOutcome { create_command("rustup") - .and_then(|mut cmd| cmd.args(&["run", toolchain, "rustc", "--version"]).output()) + .and_then(|mut cmd| { + cmd.args(&["run", toolchain, "rustc", "--version"]) + .current_dir(&context.current_dir) + .output() + }) .map(extract_toolchain_from_rustup_run_rustc_version) .unwrap_or(RustupRunRustcVersionOutcome::RustupNotWorking) } @@ -222,11 +235,11 @@ fn extract_toolchain_from_rustup_run_rustc_version(output: Output) -> RustupRunR RustupRunRustcVersionOutcome::Err } -fn execute_rustc_version() -> Option { - match create_command("rustc").ok()?.arg("--version").output() { - Ok(output) => Some(String::from_utf8(output.stdout).unwrap()), - Err(_) => None, - } +fn execute_rustc_version(context: &Context) -> Option { + context + .exec_cmd("rustc", &["--version"]) + .map(|o| o.stdout) + .filter(|s| !s.is_empty()) } fn format_rustc_version(rustc_version: &str, version_format: &str) -> Option { @@ -275,11 +288,13 @@ mod tests { ); static OVERRIDES_INPUT: &str = - "/home/user/src/a beta-x86_64-unknown-linux-gnu\n\ - /home/user/src/b nightly-x86_64-unknown-linux-gnu\n"; + "/home/user/src/a \t beta-x86_64-unknown-linux-gnu\n\ + /home/user/src/b \t nightly-x86_64-unknown-linux-gnu\n\ + /home/user/src/b/d c \t stable-x86_64-pc-windows-msvc\n"; static OVERRIDES_CWD_A: &str = "/home/user/src/a/src"; static OVERRIDES_CWD_B: &str = "/home/user/src/b/tests"; static OVERRIDES_CWD_C: &str = "/home/user/src/c/examples"; + static OVERRIDES_CWD_D: &str = "/home/user/src/b/d c/spaces"; assert_eq!( extract_toolchain_from_rustup_override_list(OVERRIDES_INPUT, OVERRIDES_CWD_A.as_ref()), Some("beta-x86_64-unknown-linux-gnu".to_owned()), @@ -292,6 +307,29 @@ mod tests { extract_toolchain_from_rustup_override_list(OVERRIDES_INPUT, OVERRIDES_CWD_C.as_ref()), None, ); + assert_eq!( + extract_toolchain_from_rustup_override_list(OVERRIDES_INPUT, OVERRIDES_CWD_D.as_ref()), + Some("stable-x86_64-pc-windows-msvc".to_owned()), + ); + } + + #[test] + #[cfg(windows)] + fn test_extract_toolchain_from_rustup_override_list_win() { + static OVERRIDES_INPUT: &str = + "C:\\src \t beta-x86_64-unknown-linux-gnu\n"; + static OVERRIDES_CWD_A: &str = r"\\?\C:\src"; + static OVERRIDES_CWD_B: &str = r"C:\src"; + + assert_eq!( + extract_toolchain_from_rustup_override_list(OVERRIDES_INPUT, OVERRIDES_CWD_A.as_ref()), + Some("beta-x86_64-unknown-linux-gnu".to_owned()), + ); + + assert_eq!( + extract_toolchain_from_rustup_override_list(OVERRIDES_INPUT, OVERRIDES_CWD_B.as_ref()), + Some("beta-x86_64-unknown-linux-gnu".to_owned()), + ); } #[cfg(any(unix, windows))]