whitequark / rust-xdg

A library that makes it easy to follow the X Desktop Group specifications
https://wiki.freedesktop.org/www/Specifications/
Apache License 2.0
154 stars 30 forks source link

Add config/data dirs support for users with no home directory #47

Closed julianandrews closed 1 year ago

julianandrews commented 1 year ago

The XDG spec supports system-wide fallbacks if a home directory doesn't exist (for instance /etc/xdg for config files or /usr/local/share for data), and also supports a list of directories via that XDG_CONFIG_DIRS and XDG_DATA_DIRS env vars. The xdg crate will happily find files in those directories for users with a home directory, but will error out if home is missing.

I find myself writing tools that can be used directly by users with a home directory, but also work well as a systemd service running as a system user with no home directory, but right now at least, I can't really use the xdg crate effectively for those tools.

For most of the XDG spec I think the decision to fail if a home directory doesn't exist makes sense. But for find_data_file and find_config_file specifically there's perfectly well defined behavior that could succeed even without a home directory. It would be really useful if there were a way to access those files through the xdg crate for tools running as system users with no home directory.

whitequark commented 1 year ago

I think this would be useful. I'm happy to accept a PR implementing this behavior; if you're interested in implementing it, please discuss the approach with me first.

julianandrews commented 1 year ago

I'd be happy to have a go at this.

Digging into the code, I realized there are actually a bunch more methods that should probably work without a home dir if the right env vars are set. For instance if XDG_CONFIG_HOME is set, then create_config_directory() is a totally sensible thing to do even without a HOME but will currently fail. I'm inclined to try to fix that issue at the same time since it seems related. But since any subset of env vars can be set, there's no good way to handle this at BaseDirectory construction time.

So my first instinct is to move the failure point to call time rather than BaseDirectory creation. This would definitely be a breaking change, but I think it makes sense.

I went through all the public methods to get a sense of what this would look like, and it's not as bad as I initially thought it would be. Only the get_*_file, get_*_home and constructor methods would need a signature change. Here's the list of changes I was looking at:

I've got ideas for less intrusive approaches if this is too big a change, so let me know what you think.

whitequark commented 1 year ago

I'm OK with a breaking change per se.

I'm unsure about moving errors later in the chain. It's good because the software that does not depend on the home directory being present will transparently (sans a breaking change) start working with no home being available, but there is also the risk of making software crash after performing some other expensive/critical operation because suddenly it turns out there's no home directory.

I'm leaning towards it being a good idea after all because the signatures make this very explicit.

julianandrews commented 1 year ago

I'll try to put together a draft of the change some time this week!

whitequark commented 1 year ago

Fixed by #64.