-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Auto merge of #11359 - LucioFranco:lucio/home-crate, r=ehuss
Add `home` crate to cargo crates ### What does this PR try to resolve? The `home` crate is the crate used by both `rustup` and `cargo` to define their home directories. The crate is quite small but plays an important role in gluing rust tooling together. This PR adds this crate the `crates` folder within cargo to allow the cargo team and the rust project to maintain this small crate. ### Additional information I've also added both `rust-lang-owners` and `ehuss` as owners of the crate. Once, merged I will archive the old repo. Reference zulip conversation: https://rust-lang.zulipchat.com/#narrow/stream/246057-t-cargo/topic/Moving.20the.20home.20crate.20into.20rust-lang.20and.20under.20cargo/near/299975263 cc `@weihanglo` `@ehuss`
- Loading branch information
Showing
9 changed files
with
430 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
# Changelog | ||
All notable changes to this project will be documented in this file. | ||
|
||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), | ||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). | ||
|
||
<!-- ## [Unreleased] --> | ||
|
||
## [0.5.4] - 2022-10-10 | ||
- Add `_with_env` variants of functions to support in-process threaded tests for | ||
rustup. | ||
|
||
## [0.5.3] - 2020-01-07 | ||
|
||
Use Rust 1.36.0 as minimum Rust version. | ||
|
||
## [0.5.2] - 2020-01-05 | ||
|
||
*YANKED since it cannot be built on Rust 1.36.0* | ||
|
||
### Changed | ||
- Check for emptiness of `CARGO_HOME` and `RUSTUP_HOME` environment variables. | ||
- Windows: Use `SHGetFolderPath` to replace `GetUserProfileDirectory` syscall. | ||
* Remove `scopeguard` dependency. | ||
|
||
## [0.5.1] - 2019-10-12 | ||
### Changed | ||
- Disable unnecessary features for `scopeguard`. Thanks @mati865. | ||
|
||
## [0.5.0] - 2019-08-21 | ||
### Added | ||
- Add `home_dir` implementation for Windows UWP platforms. | ||
|
||
### Fixed | ||
- Fix `rustup_home` implementation when `RUSTUP_HOME` is an absolute directory. | ||
- Fix `cargo_home` implementation when `CARGO_HOME` is an absolute directory. | ||
|
||
### Removed | ||
- Remove support for `multirust` folder used in old version of `rustup`. | ||
|
||
[Unreleased]: https://github.com/brson/home/compare/v0.5.4...HEAD | ||
[0.5.4]: https://github.com/brson/home/compare/v0.5.3...v0.5.4 | ||
[0.5.3]: https://github.com/brson/home/compare/v0.5.2...v0.5.3 | ||
[0.5.2]: https://github.com/brson/home/compare/v0.5.1...v0.5.2 | ||
[0.5.1]: https://github.com/brson/home/compare/v0.5.0...v0.5.1 | ||
[0.5.0]: https://github.com/brson/home/compare/0.4.2...v0.5.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
[package] | ||
name = "home" | ||
version = "0.5.4" # also update `html_root_url` in `src/lib.rs` | ||
authors = [ "Brian Anderson <[email protected]>" ] | ||
documentation = "https://docs.rs/home" | ||
edition = "2018" | ||
include = [ | ||
"/src", | ||
"/Cargo.toml", | ||
"/CHANGELOG", | ||
"/LICENSE-*", | ||
"/README.md", | ||
] | ||
license = "MIT OR Apache-2.0" | ||
readme = "README.md" | ||
repository = "https://github.com/brson/home" | ||
description = "Shared definitions of home directories" | ||
|
||
[target."cfg(windows)".dependencies.winapi] | ||
version = "0.3" | ||
features = [ | ||
"shlobj", | ||
"std", | ||
"winerror", | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
../../LICENSE-APACHE |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
../../LICENSE-MIT |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
[![Documentation](https://docs.rs/home/badge.svg)](https://docs.rs/home) | ||
[![Crates.io](https://img.shields.io/crates/v/home.svg)](https://crates.io/crates/home) | ||
|
||
Canonical definitions of `home_dir`, `cargo_home`, and `rustup_home`. | ||
|
||
This provides the definition of `home_dir` used by Cargo and rustup, | ||
as well functions to find the correct value of `CARGO_HOME` and | ||
`RUSTUP_HOME`. | ||
|
||
The definition of `home_dir` provided by the standard library is | ||
incorrect because it considers the `HOME` environment variable on | ||
Windows. This causes surprising situations where a Rust program will | ||
behave differently depending on whether it is run under a Unix | ||
emulation environment like Cygwin or MinGW. Neither Cargo nor rustup | ||
use the standard libraries definition - they use the definition here. | ||
|
||
This crate further provides two functions, `cargo_home` and | ||
`rustup_home`, which are the canonical way to determine the location | ||
that Cargo and rustup store their data. | ||
|
||
See [rust-lang/rust#43321]. | ||
|
||
[rust-lang/rust#43321]: https://github.com/rust-lang/rust/issues/43321 | ||
|
||
## License | ||
|
||
MIT OR Apache-2.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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")), | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
//! Canonical definitions of `home_dir`, `cargo_home`, and `rustup_home`. | ||
//! | ||
//! This provides the definition of `home_dir` used by Cargo and | ||
//! rustup, as well functions to find the correct value of | ||
//! `CARGO_HOME` and `RUSTUP_HOME`. | ||
//! | ||
//! See also the [`dirs`](https://docs.rs/dirs) crate. | ||
//! | ||
//! _Note that as of 2019/08/06 it appears that cargo uses this crate. And | ||
//! rustup has used this crate since 2019/08/21._ | ||
//! | ||
//! The definition of `home_dir` provided by the standard library is | ||
//! incorrect because it considers the `HOME` environment variable on | ||
//! Windows. This causes surprising situations where a Rust program | ||
//! will behave differently depending on whether it is run under a | ||
//! Unix emulation environment like Cygwin or MinGW. Neither Cargo nor | ||
//! rustup use the standard libraries definition - they use the | ||
//! definition here. | ||
//! | ||
//! This crate further provides two functions, `cargo_home` and | ||
//! `rustup_home`, which are the canonical way to determine the | ||
//! location that Cargo and rustup store their data. | ||
//! | ||
//! See also this [discussion]. | ||
//! | ||
//! [discussion]: https://github.com/rust-lang/rust/pull/46799#issuecomment-361156935 | ||
|
||
#![doc(html_root_url = "https://docs.rs/home/0.5.4")] | ||
#![deny(rust_2018_idioms)] | ||
|
||
pub mod env; | ||
|
||
#[cfg(windows)] | ||
mod windows; | ||
|
||
use std::io; | ||
use std::path::{Path, PathBuf}; | ||
|
||
/// Returns the path of the current user's home directory if known. | ||
/// | ||
/// # Unix | ||
/// | ||
/// Returns the value of the `HOME` environment variable if it is set | ||
/// and not equal to the empty string. Otherwise, it tries to determine the | ||
/// home directory by invoking the `getpwuid_r` function on the UID of the | ||
/// current user. | ||
/// | ||
/// # Windows | ||
/// | ||
/// Returns the value of the `USERPROFILE` environment variable if it | ||
/// is set and not equal to the empty string. If both do not exist, | ||
/// [`SHGetFolderPathW`][msdn] is used to return the appropriate path. | ||
/// | ||
/// [msdn]: https://docs.microsoft.com/en-us/windows/win32/api/shlobj_core/nf-shlobj_core-shgetfolderpathw | ||
/// | ||
/// # Examples | ||
/// | ||
/// ``` | ||
/// match home::home_dir() { | ||
/// Some(path) => println!("{}", path.display()), | ||
/// None => println!("Impossible to get your home dir!"), | ||
/// } | ||
/// ``` | ||
pub fn home_dir() -> Option<PathBuf> { | ||
env::home_dir_with_env(&env::OS_ENV) | ||
} | ||
|
||
#[cfg(windows)] | ||
use windows::home_dir_inner; | ||
|
||
#[cfg(any(unix, target_os = "redox"))] | ||
fn home_dir_inner() -> Option<PathBuf> { | ||
#[allow(deprecated)] | ||
std::env::home_dir() | ||
} | ||
|
||
/// Returns the storage directory used by Cargo, often knowns as | ||
/// `.cargo` or `CARGO_HOME`. | ||
/// | ||
/// It returns one of the following values, in this order of | ||
/// preference: | ||
/// | ||
/// - The value of the `CARGO_HOME` environment variable, if it is | ||
/// an absolute path. | ||
/// - The value of the current working directory joined with the value | ||
/// of the `CARGO_HOME` environment variable, if `CARGO_HOME` is a | ||
/// relative directory. | ||
/// - The `.cargo` directory in the user's home directory, as reported | ||
/// by the `home_dir` function. | ||
/// | ||
/// # Errors | ||
/// | ||
/// This function fails if it fails to retrieve the current directory, | ||
/// or if the home directory cannot be determined. | ||
/// | ||
/// # Examples | ||
/// | ||
/// ``` | ||
/// match home::cargo_home() { | ||
/// Ok(path) => println!("{}", path.display()), | ||
/// Err(err) => eprintln!("Cannot get your cargo home dir: {:?}", err), | ||
/// } | ||
/// ``` | ||
pub fn cargo_home() -> io::Result<PathBuf> { | ||
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> { | ||
env::cargo_home_with_cwd_env(&env::OS_ENV, cwd) | ||
} | ||
|
||
/// Returns the storage directory used by rustup, often knowns as | ||
/// `.rustup` or `RUSTUP_HOME`. | ||
/// | ||
/// It returns one of the following values, in this order of | ||
/// preference: | ||
/// | ||
/// - The value of the `RUSTUP_HOME` environment variable, if it is | ||
/// an absolute path. | ||
/// - The value of the current working directory joined with the value | ||
/// of the `RUSTUP_HOME` environment variable, if `RUSTUP_HOME` is a | ||
/// relative directory. | ||
/// - The `.rustup` directory in the user's home directory, as reported | ||
/// by the `home_dir` function. | ||
/// | ||
/// # Errors | ||
/// | ||
/// This function fails if it fails to retrieve the current directory, | ||
/// or if the home directory cannot be determined. | ||
/// | ||
/// # Examples | ||
/// | ||
/// ``` | ||
/// match home::rustup_home() { | ||
/// Ok(path) => println!("{}", path.display()), | ||
/// Err(err) => eprintln!("Cannot get your rustup home dir: {:?}", err), | ||
/// } | ||
/// ``` | ||
pub fn rustup_home() -> io::Result<PathBuf> { | ||
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> { | ||
env::rustup_home_with_cwd_env(&env::OS_ENV, cwd) | ||
} |
Oops, something went wrong.