diff options
Diffstat (limited to 'vendor/home/src')
-rw-r--r-- | vendor/home/src/env.rs | 106 | ||||
-rw-r--r-- | vendor/home/src/lib.rs | 48 |
2 files changed, 117 insertions, 37 deletions
diff --git a/vendor/home/src/env.rs b/vendor/home/src/env.rs new file mode 100644 index 000000000..e47273bc8 --- /dev/null +++ b/vendor/home/src/env.rs @@ -0,0 +1,106 @@ +//! Lower-level utilities for mocking the process environment. + +use std::{ + ffi::OsString, + io, + path::{Path, PathBuf}, +}; + +/// Permits parameterizing the home functions via the _from variants - used for +/// in-process unit testing by rustup. +pub trait Env { + /// Return the path to the the users home dir, or None if any error occurs: + /// see home_inner. + fn home_dir(&self) -> Option<PathBuf>; + /// Return the current working directory. + fn current_dir(&self) -> io::Result<PathBuf>; + /// Get an environment variable, as per std::env::var_os. + fn var_os(&self, key: &str) -> Option<OsString>; +} + +/// Implements Env for the OS context, both Unix style and Windows. +/// +/// This is trait permits in-process testing by providing a control point to +/// allow in-process divergence on what is normally process wide state. +/// +/// Implementations should be provided by whatever testing framework the caller +/// is using. Code that is not performing in-process threaded testing requiring +/// isolated rustup/cargo directories does not need this trait or the _from +/// functions. +pub struct OsEnv; +impl Env for OsEnv { + fn home_dir(&self) -> Option<PathBuf> { + crate::home_dir_inner() + } + fn current_dir(&self) -> io::Result<PathBuf> { + std::env::current_dir() + } + fn var_os(&self, key: &str) -> Option<OsString> { + std::env::var_os(key) + } +} + +pub const OS_ENV: OsEnv = OsEnv {}; + +/// Returns the path of the current user's home directory from [`Env::home_dir`]. +pub fn home_dir_with_env(env: &dyn Env) -> Option<PathBuf> { + env.home_dir() +} + +/// Variant of cargo_home where the environment source is parameterized. This is +/// specifically to support in-process testing scenarios as environment +/// variables and user home metadata are normally process global state. See the +/// [`Env`] trait. +pub fn cargo_home_with_env(env: &dyn Env) -> io::Result<PathBuf> { + let cwd = env.current_dir()?; + cargo_home_with_cwd_env(env, &cwd) +} + +/// Variant of cargo_home_with_cwd where the environment source is +/// parameterized. This is specifically to support in-process testing scenarios +/// as environment variables and user home metadata are normally process global +/// state. See the OsEnv trait. +pub fn cargo_home_with_cwd_env(env: &dyn Env, cwd: &Path) -> io::Result<PathBuf> { + match env.var_os("CARGO_HOME").filter(|h| !h.is_empty()) { + Some(home) => { + let home = PathBuf::from(home); + if home.is_absolute() { + Ok(home) + } else { + Ok(cwd.join(&home)) + } + } + _ => home_dir_with_env(env) + .map(|p| p.join(".cargo")) + .ok_or_else(|| io::Error::new(io::ErrorKind::Other, "could not find cargo home dir")), + } +} + +/// Variant of cargo_home_with_cwd where the environment source is +/// parameterized. This is specifically to support in-process testing scenarios +/// as environment variables and user home metadata are normally process global +/// state. See the OsEnv trait. +pub fn rustup_home_with_env(env: &dyn Env) -> io::Result<PathBuf> { + let cwd = env.current_dir()?; + rustup_home_with_cwd_env(env, &cwd) +} + +/// Variant of cargo_home_with_cwd where the environment source is +/// parameterized. This is specifically to support in-process testing scenarios +/// as environment variables and user home metadata are normally process global +/// state. See the OsEnv trait. +pub fn rustup_home_with_cwd_env(env: &dyn Env, cwd: &Path) -> io::Result<PathBuf> { + match env.var_os("RUSTUP_HOME").filter(|h| !h.is_empty()) { + Some(home) => { + let home = PathBuf::from(home); + if home.is_absolute() { + Ok(home) + } else { + Ok(cwd.join(&home)) + } + } + _ => home_dir_with_env(env) + .map(|d| d.join(".rustup")) + .ok_or_else(|| io::Error::new(io::ErrorKind::Other, "could not find rustup home dir")), + } +} diff --git a/vendor/home/src/lib.rs b/vendor/home/src/lib.rs index ad31d3d2e..ad254ca3b 100644 --- a/vendor/home/src/lib.rs +++ b/vendor/home/src/lib.rs @@ -25,13 +25,14 @@ //! //! [discussion]: https://github.com/rust-lang/rust/pull/46799#issuecomment-361156935 -#![doc(html_root_url = "https://docs.rs/home/0.5.3")] +#![doc(html_root_url = "https://docs.rs/home/0.5.4")] #![deny(rust_2018_idioms)] +pub mod env; + #[cfg(windows)] mod windows; -use std::env; use std::io; use std::path::{Path, PathBuf}; @@ -48,10 +49,9 @@ use std::path::{Path, PathBuf}; /// /// Returns the value of the `USERPROFILE` environment variable if it /// is set and not equal to the empty string. If both do not exist, -/// [`GetUserProfileDirectory`][msdn] is used to return the -/// appropriate path. +/// [`SHGetFolderPathW`][msdn] is used to return the appropriate path. /// -/// [msdn]: https://docs.microsoft.com/en-us/windows/win32/api/userenv/nf-userenv-getuserprofiledirectoryw +/// [msdn]: https://docs.microsoft.com/en-us/windows/win32/api/shlobj_core/nf-shlobj_core-shgetfolderpathw /// /// # Examples /// @@ -62,7 +62,7 @@ use std::path::{Path, PathBuf}; /// } /// ``` pub fn home_dir() -> Option<PathBuf> { - home_dir_inner() + env::home_dir_with_env(&env::OS_ENV) } #[cfg(windows)] @@ -71,7 +71,7 @@ use windows::home_dir_inner; #[cfg(any(unix, target_os = "redox"))] fn home_dir_inner() -> Option<PathBuf> { #[allow(deprecated)] - env::home_dir() + std::env::home_dir() } /// Returns the storage directory used by Cargo, often knowns as @@ -102,26 +102,13 @@ fn home_dir_inner() -> Option<PathBuf> { /// } /// ``` pub fn cargo_home() -> io::Result<PathBuf> { - let cwd = env::current_dir()?; - cargo_home_with_cwd(&cwd) + env::cargo_home_with_env(&env::OS_ENV) } /// Returns the storage directory used by Cargo within `cwd`. /// For more details, see [`cargo_home`](fn.cargo_home.html). pub fn cargo_home_with_cwd(cwd: &Path) -> io::Result<PathBuf> { - match env::var_os("CARGO_HOME").filter(|h| !h.is_empty()) { - Some(home) => { - let home = PathBuf::from(home); - if home.is_absolute() { - Ok(home) - } else { - Ok(cwd.join(&home)) - } - } - _ => home_dir() - .map(|p| p.join(".cargo")) - .ok_or_else(|| io::Error::new(io::ErrorKind::Other, "could not find cargo home dir")), - } + env::cargo_home_with_cwd_env(&env::OS_ENV, cwd) } /// Returns the storage directory used by rustup, often knowns as @@ -152,24 +139,11 @@ pub fn cargo_home_with_cwd(cwd: &Path) -> io::Result<PathBuf> { /// } /// ``` pub fn rustup_home() -> io::Result<PathBuf> { - let cwd = env::current_dir()?; - rustup_home_with_cwd(&cwd) + env::rustup_home_with_env(&env::OS_ENV) } /// Returns the storage directory used by rustup within `cwd`. /// For more details, see [`rustup_home`](fn.rustup_home.html). pub fn rustup_home_with_cwd(cwd: &Path) -> io::Result<PathBuf> { - match env::var_os("RUSTUP_HOME").filter(|h| !h.is_empty()) { - Some(home) => { - let home = PathBuf::from(home); - if home.is_absolute() { - Ok(home) - } else { - Ok(cwd.join(&home)) - } - } - _ => home_dir() - .map(|d| d.join(".rustup")) - .ok_or_else(|| io::Error::new(io::ErrorKind::Other, "could not find rustup home dir")), - } + env::rustup_home_with_cwd_env(&env::OS_ENV, cwd) } |