-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Add home
crate to cargo crates
#11359
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 100 commits
25592d9
b1a9fe1
cf5dd41
759a15b
c643270
abf65ad
c10b8d2
1825f0a
bfaf1f1
d4d9ac8
5673c9a
152407f
2e01bd4
5744640
a0520b0
4f887cf
f5dd969
71afeb2
41fb21b
2a4ac15
72d8872
f39302f
51ec02e
97baa41
645457e
b4a6db2
2f74993
64de940
ddad9bf
c2a4f95
38ba4ef
2c718c9
2002aee
e658ff7
865e4b9
ae79f9f
e9d14ba
7bb09dd
180b334
623419d
46003d5
2f0fe8a
e40e332
08eec12
3e824d2
f44f3f2
6e7ea32
3f94c5a
ef18523
cfc445e
29d9c3c
1886c07
38c2d2b
23bc439
854cbf9
d1ffd6e
77ea3e8
a596a75
0d01112
fdca596
1c5772b
12645bc
2fbb290
d23fd46
c03a7bc
69258b0
f6cccd5
61576ab
0a52e71
410d426
c97f8f0
1d9393e
fd7d425
cd27296
5a577f7
4607d98
3a6eccd
af762b0
32044e5
0719a86
deefa5a
21df461
0467bc2
660ccbc
c77b640
e3e570d
38c610a
eed5978
6d79d95
0f6aad6
9afbd90
fb34fe9
de6dd85
e697b7b
f0d2362
dbb8dad
6a1a9ed
98a3d4e
ac9da4b
faa9b31
18a06cc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. SO I think for now it makes sense to keep these linked to brson, but on the next release we can update the tag. Not sure what the process in cargo is. That said, I doubt we will need a release for a long time so something that can be figured out then. The brson/home links should continue to work even if its archived iirc. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is no such a tagging policy for sub-crates in rust-lang/cargo. Tagging cargo itself is a separate process ran by Release team as well I believe (but currently broken 😅 #11345). |
||
[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 |
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", | ||
] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
../../LICENSE-APACHE |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
../../LICENSE-MIT |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
[](https://docs.rs/home) | ||
[](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 |
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")), | ||
} | ||
} |
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) | ||
} |
Uh oh!
There was an error while loading. Please reload this page.