diff --git a/src/env_var.rs b/src/env_var.rs index ccf1b5ca9f..3f20605603 100644 --- a/src/env_var.rs +++ b/src/env_var.rs @@ -1,6 +1,5 @@ -use std::collections::{HashSet, VecDeque}; +use std::collections::VecDeque; use std::env; -use std::ffi::OsStr; use std::path::PathBuf; use std::process::Command; @@ -8,43 +7,7 @@ use crate::process; pub const RUST_RECURSION_COUNT_MAX: u32 = 20; -/// This can be removed when https://github.com/rust-lang/rust/issues/44434 is -/// stablised. -pub(crate) trait ProcessEnvs { - fn env(&mut self, key: K, val: V) -> &mut Self - where - Self: Sized, - K: AsRef, - V: AsRef; -} - -impl ProcessEnvs for Command { - fn env(&mut self, key: K, val: V) -> &mut Self - where - Self: Sized, - K: AsRef, - V: AsRef, - { - self.env(key, val) - } -} - -#[allow(unused)] -fn append_path(name: &str, value: Vec, cmd: &mut E) { - let old_value = process().var_os(name); - let mut parts: Vec; - if let Some(ref v) = old_value { - let old_paths: Vec = env::split_paths(v).collect::>(); - parts = concat_uniq_paths(old_paths, value); - } else { - parts = value; - } - if let Ok(new_value) = env::join_paths(parts) { - cmd.env(name, new_value); - } -} - -pub(crate) fn prepend_path(name: &str, prepend: Vec, cmd: &mut E) { +pub(crate) fn prepend_path(name: &str, prepend: Vec, cmd: &mut Command) { let old_value = process().var_os(name); let parts = if let Some(ref v) = old_value { let mut tail = env::split_paths(v).collect::>(); @@ -73,117 +36,15 @@ pub(crate) fn inc(name: &str, cmd: &mut Command) { cmd.env(name, (old_value + 1).to_string()); } -fn concat_uniq_paths(fst_paths: Vec, snd_paths: Vec) -> Vec { - let deduped_fst_paths = dedupe_with_preserved_order(fst_paths); - let deduped_snd_paths = dedupe_with_preserved_order(snd_paths); - - let vec_fst_paths: Vec<_> = deduped_fst_paths.into_iter().collect(); - - let mut unified_paths; - unified_paths = vec_fst_paths.clone(); - unified_paths.extend( - deduped_snd_paths - .into_iter() - .filter(|v| !vec_fst_paths.contains(v)) - .collect::>(), - ); - - unified_paths -} - -fn dedupe_with_preserved_order(paths: Vec) -> Vec { - let mut uniq_paths: Vec = Vec::new(); - let mut seen_paths: HashSet = HashSet::new(); - - for path in &paths { - if !seen_paths.contains(path) { - seen_paths.insert(path.to_path_buf()); - uniq_paths.push(path.to_path_buf()); - } - } - - uniq_paths -} - #[cfg(test)] mod tests { use super::*; use crate::currentprocess; use crate::test::{with_saved_path, Env}; - use super::ProcessEnvs; use std::collections::HashMap; use std::ffi::{OsStr, OsString}; - #[derive(Default)] - struct TestCommand { - envs: HashMap>, - } - - impl ProcessEnvs for TestCommand { - fn env(&mut self, key: K, val: V) -> &mut Self - where - Self: Sized, - K: AsRef, - V: AsRef, - { - self.envs - .insert(key.as_ref().to_owned(), Some(val.as_ref().to_owned())); - self - } - } - - #[test] - fn deduplicate_and_concat_paths() { - let mut old_paths = vec![]; - - let z = OsString::from("/home/z/.cargo/bin"); - let path_z = PathBuf::from(z); - old_paths.push(path_z); - - let a = OsString::from("/home/a/.cargo/bin"); - let path_a = PathBuf::from(a); - old_paths.push(path_a); - - let _a = OsString::from("/home/a/.cargo/bin"); - let _path_a = PathBuf::from(_a); - old_paths.push(_path_a); - - let mut new_paths = vec![]; - - let n = OsString::from("/home/n/.cargo/bin"); - let path_n = PathBuf::from(n); - new_paths.push(path_n); - - let g = OsString::from("/home/g/.cargo/bin"); - let path_g = PathBuf::from(g); - new_paths.push(path_g); - - let _g = OsString::from("/home/g/.cargo/bin"); - let _path_g = PathBuf::from(_g); - new_paths.push(_path_g); - - let _z = OsString::from("/home/z/.cargo/bin"); - let path_z = PathBuf::from(_z); - old_paths.push(path_z); - - let mut unified_paths: Vec = vec![]; - let zpath = OsString::from("/home/z/.cargo/bin"); - let _zpath = PathBuf::from(zpath); - unified_paths.push(_zpath); - let apath = OsString::from("/home/a/.cargo/bin"); - let _apath = PathBuf::from(apath); - unified_paths.push(_apath); - let npath = OsString::from("/home/n/.cargo/bin"); - let _npath = PathBuf::from(npath); - unified_paths.push(_npath); - let gpath = OsString::from("/home/g/.cargo/bin"); - let _gpath = PathBuf::from(gpath); - unified_paths.push(_gpath); - - assert_eq!(concat_uniq_paths(old_paths, new_paths), unified_paths); - } - #[test] fn prepend_unique_path() { let mut vars = HashMap::new(); @@ -198,7 +59,7 @@ mod tests { with_saved_path(&|| { currentprocess::with(tp.clone(), || { let mut path_entries = vec![]; - let mut cmd = TestCommand::default(); + let mut cmd = Command::new("test"); let a = OsString::from("/home/a/.cargo/bin"); let path_a = PathBuf::from(a); @@ -213,13 +74,13 @@ mod tests { path_entries.push(path_z); prepend_path("PATH", path_entries, &mut cmd); - let envs: Vec<_> = cmd.envs.iter().collect(); + let envs: Vec<_> = cmd.get_envs().collect(); assert_eq!( envs, &[( - &OsString::from("PATH"), - &Some( + OsStr::new("PATH"), + Some( env::join_paths( vec![ "/home/z/.cargo/bin", @@ -229,6 +90,7 @@ mod tests { .iter() ) .unwrap() + .as_os_str() ) ),] );