-
Notifications
You must be signed in to change notification settings - Fork 20
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
ACP: env::home_dir replacement #372
Comments
How often would you want |
I appreciate the work that the Cross-Desktop Group (XDG) did on XDG Base Directory Specification to define some standardized directories. In practice none of the three environments I use daily (Windows, MacOS, Linux CLI) have XDG_CONFIG_HOME $HOME/.config
XDG_CACHE_HOME $HOME/.cache
XDG_DATA_HOME $HOME/.local/share
XDG_STATE_HOME $HOME/.local/state But those still require determining Nudging developers away from blindly creating homedir dotfiles is a worthy cause, but I actually think the docs for As for my non-config use cases, it's mostly reading/writing config/data for the known location used by another app which I do not control. For example checking the default install directory of a proprietary SDK ( In the end it's just an ergonomics thing. What prompted this rabbit hole was finding out an app was broken because it checked multiple locations searching for a file, one of which was under It'd be nice if others, especially developers new to rust, didn't have to go through the same effort and pain. |
Note that XDG says nothing about Windows. When porting the spec to Windows it's typical to implement it in terms of |
@m-ou-se so do you think this proposal would be more likely to be accepted if it also proposed including (I think @notpeter would you be interested in helping to drive that forward? (See also some discussion in https://internals.rust-lang.org/t/pre-rfc-split-cargo-home/19747.) |
@djc I've implemented this on a branch. See: notpeter/env-home@more_dirs
Notes:
Supporting other well-known directories (Downloads, Documents, etc) on Windows requires the platform APIs because these folders may be relocated. This increases complexity, but One side benefit the name |
As a macOS user, I definitely think we should go with the platform-specific behavior here. |
I've implemented this behavior on an alternate branch. See: notpeter@env-home@more_dirs_mac Adds MacOS specific behaviors:
|
The iterations on this are already demonstrating that this gets substantially more complex and bikesheddable the more we extend it. Could we please just add a function to return the home directory, first, and then consider whether we want the full complexity of defining a cross-platform suite of named directories to store things? |
@joshtriplett I agree. I tried to write as narrow a proposal for Having explored user_{cache,config,etc}_dir a bit, there are design decisions that need to be hashed out. I will try and draft something which explores that space, so for now let's stick to |
I wonder if the concept of a home directory is not even cross platform enough to warrant a generic API. E.g. on iOS it can't return anything sensible. Maybe on Android too, and I'm not sure about Fuchsia. Maybe it would make more sense to jump straight to platform specific APIs? I don't know the answer; just wondering. |
I think there's a reasonable concept on many platforms, and on those where it doesn't exist, it can return an error. On Android platforms it would probably be reasonable to return something in the application's directory. |
The point in #372 (comment) really resonates with me -- what can I actually do correctly, in a cross-platform way, by knowing just the home directory? If returning something in the application's directory is reasonable for android, would it maybe make sense to return something under an app-specific AppData in Windows? Is there a survey of what people want to do with the result of this? The motivation in the OP here is just the circular "Developer wishes determine the current user home directory", but that's only part of the means to a more specific end. (Are they just trying to translate |
maybe look at https://wiki.libsdl.org/SDL3/SDL_Folder and https://wiki.libsdl.org/SDL3/SDL_GetUserFolder for inspiration |
Excellent question. We should look on https://grep.app to see how people have used the existing APIs/crates. |
I spent a few hours spelunking through open source code with SoureGraph Search (example query) for usage of env::home_dir and the popular crates (home, dirs, directories). This was largely manual and certainly not scientific, but I was able to observe a number of patterns of use:
After seeing hundreds of call sites, I realized there is no "technically correct" platform-specific method for resolving the path of various directories -- because the locations themselves are API via 'well-known-paths'. Historically, this is just
I've come around on this. There's nothing wrong with using It's not sexy, but most POSIX software looks for configuration inside at a statically defined location in a user's home directory. Accessing the existing clutter of dotfiles and dirs is actually the compelling use-case for user_home_dir. 🙃 |
To reinforce that point with a concrete example: in safe-rm, I have migrated the config file to the "right" location (i.e. At the moment, I'm looking at |
this _could_ use the home crate (as suggested in rust-lang/libs-team#372) but theres no reason to attempt to be cross-platform; this depends on so many mac things anyway
Proposal
Add new API:
std::env::user_home_dir
returningOption<PathBuf>
.This is a replacement for the deprecated
std::env::home_dir
, providing a platform agnostic method for identifying the user's home directory checking platform-specific environment variables ('HOME' on Unix, 'USERPROFILE' on Windows) as required.The proposed implementation is simpler than
std::env::home_dir
as only searches the environment and does not attempt call one/multiple platform APIs (e.g.getpwuid_r
,GetUserProfileDirectoryW
, etc) as fallback when the appropriate environment variables are unset.The existing
env::home_dir
remains unchanged.Problem statement
The
std::env::home_dir
API is deprecated. Fixing it would be a breaking API change. (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 is nowhere in the process environment.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:Users looking for a replacement for
std::env::home_dir
are forced to evaluate and choose amongst a number of 3rd party crates:std::env::home_dir
replacement but also provide additional abstractions over other platform-specific APIs (XDG, Windows Known Folders API, etc)HOME
orUSERPROFILE
set.Motivating examples or use cases
Developer wishes determine the current user home directory via inspecting environment variables in a platform agnostic way.
The same use case as
std::env::home_dir
but without the bugs or fallback behavior when environment variables are unset.Solution sketch
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:
user_home_dir
function that returnsOption<PathBuf>
.USERPROFILE
environment variable on Windows.HOME
environment variable variable on Unix.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 withstd::env::home_dir
orhome_dir
provided by other crates.Alternatives
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):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.Links and related work
Discussions:
std::env::home_dir
and fix incorrect documentation rust#51656Languages whose standard library provides a platform independent home_dir abstraction:
Languages which do not have a home_dir abstraction in the standard library:
Notes
I am particularly interested to hear of real-world use cases or systems where $HOME is unset and the directory provided via platform-specific APIs is available/appropriate for use. In my experience
$HOME
being unset is a signal that there there is nothing like a unix home directory available to my process and my app should behave accordingly.This is my first attempt at drafting an API Change Proposal, so please be kind.
Thanks!
The text was updated successfully, but these errors were encountered: