]>
Commit | Line | Data |
---|---|---|
064997fb FG |
1 | //! Canonical definitions of `home_dir`, `cargo_home`, and `rustup_home`. |
2 | //! | |
3 | //! This provides the definition of `home_dir` used by Cargo and | |
4 | //! rustup, as well functions to find the correct value of | |
5 | //! `CARGO_HOME` and `RUSTUP_HOME`. | |
6 | //! | |
7 | //! See also the [`dirs`](https://docs.rs/dirs) crate. | |
8 | //! | |
9 | //! _Note that as of 2019/08/06 it appears that cargo uses this crate. And | |
10 | //! rustup has used this crate since 2019/08/21._ | |
11 | //! | |
12 | //! The definition of `home_dir` provided by the standard library is | |
13 | //! incorrect because it considers the `HOME` environment variable on | |
14 | //! Windows. This causes surprising situations where a Rust program | |
15 | //! will behave differently depending on whether it is run under a | |
16 | //! Unix emulation environment like Cygwin or MinGW. Neither Cargo nor | |
17 | //! rustup use the standard libraries definition - they use the | |
18 | //! definition here. | |
19 | //! | |
20 | //! This crate further provides two functions, `cargo_home` and | |
21 | //! `rustup_home`, which are the canonical way to determine the | |
22 | //! location that Cargo and rustup store their data. | |
23 | //! | |
24 | //! See also this [discussion]. | |
25 | //! | |
26 | //! [discussion]: https://github.com/rust-lang/rust/pull/46799#issuecomment-361156935 | |
27 | ||
2b03887a | 28 | #![doc(html_root_url = "https://docs.rs/home/0.5.4")] |
064997fb FG |
29 | #![deny(rust_2018_idioms)] |
30 | ||
2b03887a FG |
31 | pub mod env; |
32 | ||
064997fb FG |
33 | #[cfg(windows)] |
34 | mod windows; | |
35 | ||
064997fb FG |
36 | use std::io; |
37 | use std::path::{Path, PathBuf}; | |
38 | ||
39 | /// Returns the path of the current user's home directory if known. | |
40 | /// | |
41 | /// # Unix | |
42 | /// | |
43 | /// Returns the value of the `HOME` environment variable if it is set | |
44 | /// and not equal to the empty string. Otherwise, it tries to determine the | |
45 | /// home directory by invoking the `getpwuid_r` function on the UID of the | |
46 | /// current user. | |
47 | /// | |
48 | /// # Windows | |
49 | /// | |
50 | /// Returns the value of the `USERPROFILE` environment variable if it | |
51 | /// is set and not equal to the empty string. If both do not exist, | |
2b03887a | 52 | /// [`SHGetFolderPathW`][msdn] is used to return the appropriate path. |
064997fb | 53 | /// |
2b03887a | 54 | /// [msdn]: https://docs.microsoft.com/en-us/windows/win32/api/shlobj_core/nf-shlobj_core-shgetfolderpathw |
064997fb FG |
55 | /// |
56 | /// # Examples | |
57 | /// | |
58 | /// ``` | |
59 | /// match home::home_dir() { | |
60 | /// Some(path) => println!("{}", path.display()), | |
61 | /// None => println!("Impossible to get your home dir!"), | |
62 | /// } | |
63 | /// ``` | |
64 | pub fn home_dir() -> Option<PathBuf> { | |
2b03887a | 65 | env::home_dir_with_env(&env::OS_ENV) |
064997fb FG |
66 | } |
67 | ||
68 | #[cfg(windows)] | |
69 | use windows::home_dir_inner; | |
70 | ||
71 | #[cfg(any(unix, target_os = "redox"))] | |
72 | fn home_dir_inner() -> Option<PathBuf> { | |
73 | #[allow(deprecated)] | |
2b03887a | 74 | std::env::home_dir() |
064997fb FG |
75 | } |
76 | ||
77 | /// Returns the storage directory used by Cargo, often knowns as | |
78 | /// `.cargo` or `CARGO_HOME`. | |
79 | /// | |
80 | /// It returns one of the following values, in this order of | |
81 | /// preference: | |
82 | /// | |
83 | /// - The value of the `CARGO_HOME` environment variable, if it is | |
84 | /// an absolute path. | |
85 | /// - The value of the current working directory joined with the value | |
86 | /// of the `CARGO_HOME` environment variable, if `CARGO_HOME` is a | |
87 | /// relative directory. | |
88 | /// - The `.cargo` directory in the user's home directory, as reported | |
89 | /// by the `home_dir` function. | |
90 | /// | |
91 | /// # Errors | |
92 | /// | |
93 | /// This function fails if it fails to retrieve the current directory, | |
94 | /// or if the home directory cannot be determined. | |
95 | /// | |
96 | /// # Examples | |
97 | /// | |
98 | /// ``` | |
99 | /// match home::cargo_home() { | |
100 | /// Ok(path) => println!("{}", path.display()), | |
101 | /// Err(err) => eprintln!("Cannot get your cargo home dir: {:?}", err), | |
102 | /// } | |
103 | /// ``` | |
104 | pub fn cargo_home() -> io::Result<PathBuf> { | |
2b03887a | 105 | env::cargo_home_with_env(&env::OS_ENV) |
064997fb FG |
106 | } |
107 | ||
108 | /// Returns the storage directory used by Cargo within `cwd`. | |
109 | /// For more details, see [`cargo_home`](fn.cargo_home.html). | |
110 | pub fn cargo_home_with_cwd(cwd: &Path) -> io::Result<PathBuf> { | |
2b03887a | 111 | env::cargo_home_with_cwd_env(&env::OS_ENV, cwd) |
064997fb FG |
112 | } |
113 | ||
114 | /// Returns the storage directory used by rustup, often knowns as | |
115 | /// `.rustup` or `RUSTUP_HOME`. | |
116 | /// | |
117 | /// It returns one of the following values, in this order of | |
118 | /// preference: | |
119 | /// | |
120 | /// - The value of the `RUSTUP_HOME` environment variable, if it is | |
121 | /// an absolute path. | |
122 | /// - The value of the current working directory joined with the value | |
123 | /// of the `RUSTUP_HOME` environment variable, if `RUSTUP_HOME` is a | |
124 | /// relative directory. | |
125 | /// - The `.rustup` directory in the user's home directory, as reported | |
126 | /// by the `home_dir` function. | |
127 | /// | |
128 | /// # Errors | |
129 | /// | |
130 | /// This function fails if it fails to retrieve the current directory, | |
131 | /// or if the home directory cannot be determined. | |
132 | /// | |
133 | /// # Examples | |
134 | /// | |
135 | /// ``` | |
136 | /// match home::rustup_home() { | |
137 | /// Ok(path) => println!("{}", path.display()), | |
138 | /// Err(err) => eprintln!("Cannot get your rustup home dir: {:?}", err), | |
139 | /// } | |
140 | /// ``` | |
141 | pub fn rustup_home() -> io::Result<PathBuf> { | |
2b03887a | 142 | env::rustup_home_with_env(&env::OS_ENV) |
064997fb FG |
143 | } |
144 | ||
145 | /// Returns the storage directory used by rustup within `cwd`. | |
146 | /// For more details, see [`rustup_home`](fn.rustup_home.html). | |
147 | pub fn rustup_home_with_cwd(cwd: &Path) -> io::Result<PathBuf> { | |
2b03887a | 148 | env::rustup_home_with_cwd_env(&env::OS_ENV, cwd) |
064997fb | 149 | } |