Add new std::env::user_home_dir
API returning Option<PathBuf>
.
This API is a replacement for the deprecated std::env::home_dir
which
provides a platform agnostic method for identifying the user's home directory
via environment variables ('HOME' on Unix, 'USERPROFILE' on Windows).
This implementation will be much simpler than std::env::home_dir
as it will only
search the environment and not fallback to calling platform APIs
(e.g. getpwuid_r, GetUserProfileDirectoryW) when the environment variables are unset.
std::env::home_dir
remains unchanged.
-
The
std::env::home_dir
API is deprecated and fixing it would be a breaking API change.Deprecated since 1.29.0: This function’s behavior may be unexpected on Windows. Consider using a crate from crates.io instead. (See: rust-lang/rust#51656)
-
In most
home_dir
implementations, (includingstd::env::home_dir
) if the 'HOME' / 'USERPROFILE' environment variables are unset, there is fallback implementation that calls one/multiple platform APIs in order to guess the user's home directory. This is potentially surprising behavior, as it is not call anenv::
function may magically get you a value which differs from the process environment.- home_dir() on windows uses 'GetUserProfileDirectoryW'
- home_dir() on unix uses 'getpwuid_r()'.
-
The
std::env::home_dir
API may return a value which is not usable as a Path (""
). This occurs when HOME set to an empty string, which is not uncommon in restricted shell environments (sudo, cron jobs, etc). Callers thus must check for None and for an empty string before using the returned value. Earlier documentation forstd::env::home_dir
suggests this may have been the original intended behavior:"Returns the value of the 'HOME' environment variable if it is set and not equal to the empty string."
-
Users looking for a replacement for
std::env::home_dir
are forced to evaluate and choose amongst a number of 3rd party crates:- The 'home' crate, maintained by the Cargo team, is the very popular and used by (nearly 500 crates but the Cargo team has stated they do not wish to maintain it as a general purpose 'home_dir' replacement and they consider it only an internal Cargo and Rustup dependency.
- The 'home' crate generates a compile time error on wasm and other non-Unix/Windows platforms. The Cargo team has signaled they do not intend to fix this. See: rust-lang/cargo#12297
- Many crates do not just provide a
std::env::home_dir
replacement but also provide additional abstractions over other platform-specific APIs (XDG, Windows Known Folders API, etc) - Many crates have platform specific dependencies (libc, windows-sys, etc)
which are entirely unused in the common case (environment has
HOME
set).
Programmer wishes determine the current user home directory via inspecting environment variables in a platform agnostic way.
Basically the same use case as std::env::home_dir
but without the bugs or fallback behavior
when the environment variables are unset.
Ideally without instroducing platform specific dependencies (e.g. dirs crate depends on libc and windows-sys).
Create the API which covers the most common use of std::env::user_home_dir
getting a PathBuf
with of user's home directory, if available,
by inspecting environment variables:
- New
user_home_dir
function that returnsOption<PathBuf>
. - Checks for
USERPROFILE
environment variable on Windows. - Checks for
HOME
environment variable variable on Unix. - Return None if variable is unset.
- Return None if variable set to an empty string.
- Return None if platform does not have a concept of a home directory (wasi, etc)
- Do not attempt to guess the user's home directory when environment variables are unset (principle of least surprise)
See: env_home lib.rs for a potential implementation.
Naming is hard, especially when a deprecated API has good name.
I prefer std::env::user_home_dir
as it does not collide with
std::env::home_dir
or home_dir
provided by other crates.
-
Do nothing. Require users to evaluate and choose a 3rd party crate which provides a
home_dir
API with better behavior on Windows (usually including extra APIs):- dirs
- dirs2 - fork of 'dirs' crate
- directories - previously abandoned, revived
- directories-next - fork of 'directories' crate
- home - Won't compile on unsupported platforms (WONTFIX)
- env_home - Created as POC for this proposal.
-
Extract the current cargo implementation of
home_dir
from thehome
and Trivial fixes so it compiles as a no-op on unsupported platforms. Publish as a stand-alone crate and recommend it as a replacement forstd::env::home_dir
. -
Create an implementation of
home_dir
that only relies on the platform specific APIs and does not inspect environment variables. This would make it trivial to implement the platform API fallback behavior ofstd::env::home_dir
when environment variables are unset.
Discussions:
- Internals: Deprecate (or break-fix) std::env::home_dir
- GitHub PR #51656: Deprecate std::env::home_dir and fix incorrect documentation
- GitHub PR #46799: Fix windows home dir implementation
- Reddit: Why env::home_dir() returns Option instead Result
Languages whose standard library provides a platform independent home_dir abstraction:
- GoLang os.UserHomeDir()
- Python Path.home()
- Ruby Dir.home
- Java System.getProperty("user.home")
- Swift FileManager.default.homeDirectoryForCurrentUser
- ObjC NSHomeDirectory()
Languages which do not have a home_dir abstraction in the standard library:
- Perl File::HomeDir->my_home (CPAN module)
- Zig
- PHP
- DART