Use envvars NIX_CACHE_HOME, NIX_CONFIG_HOME, NIX_DATA_HOME, NIX_STATE_HOME if defined
Motivation
Currently Nix uses the XDG environment variables XDG_{CACHE,CONFIG,DATA,STATE}_HOME for locating files. I suggest to also look for environment variables NIX_{CACHE,CONFIG,DATA,STATE}_HOME, and if they exist, use them instead of the XDG_* ones.
This allows more fine-grained control over where Nix looks for files. This allows to have a stand-alone Nix environment, which only uses files in a specific directory, and doesn't touch any global user configuration. Specifically, this makes Nixsa possible, a project I'm working on, which allows you to extract a tarball and immediately get a standalone working Nix environment.
Context
A detail: Nix always uses the nix directory inside the XDG_*_HOME variables (for example, the profile is at $XDG_STATE_HOME/nix/profile, the configuration is at $XDG_CONFIG_HOME/nix/nix.conf). If NIX_*_HOME is defined, there's no point in adding /nix to it.
This means that this PR can be split into two simpler commits (let me know if you want me to modify it): one commit which is pure refactoring, which makes the get*Dir() functions return directories ending with /nix, and a second commit which makes the get*Dir() functions first look for a NIX_*_HOME envvar.
I don't see any backwards-compatibility issues with this change, since if the NIX_*_HOME envvars don't exist the behavior doesn't change.
Priorities and Process
Add :+1: to pull requests you find important.
The Nix maintainer team uses a GitHub project board to schedule and track reviews.
Why does Nixsa need separate variables for this? Can it not substitute in a wrapper for nix that sets the XDG_ variables for that process?
Why does Nixsa need separate variables for this? Can it not substitute in a wrapper for
nixthat sets the XDG_ variables for that process?
I think it will basically work, however the problem is that Nix can run other commands, certainly when using nix run, and the XDG envvars will be inherited by the child process.
I'm not sure if _HOME is the right suffix here. I think _HOME in XDG is meant to refer to a replacement of the role $HOME used to play for dotfiles. Notably these environment variables that have in common that they are generic locations where each application is expected to pick a subdirectory name, but NIX_*_HOME variables do not have this subdirectory behavior. Perhaps it should just be _DIR instead of _HOME?
Could you document these environment variables in doc/manual/src/command-ref/env-common.md?
I'm not sure if
_HOMEis the right suffix here. I think_HOMEin XDG is meant to refer to a replacement of the role$HOMEused to play for dotfiles. Notably these environment variables that have in common that they are generic locations where each application is expected to pick a subdirectory name, butNIX_*_HOMEvariables do not have this subdirectory behavior. Perhaps it should just be_DIRinstead of_HOME?Could you document these environment variables in
doc/manual/src/command-ref/env-common.md?
Thanks for the suggestion, it makes a lot of sense.
It's such a good suggestion, that it raises a question. I looked at env-common.md and it mentions NIX_CONF_DIR , NIX_DATA_DIR, and NIX_STATE_DIR (3 of the 4 suggested new variables, ignoring the difference between CONF and CONFIG). If those envvars are not set, they are taken to be /nix/etc/nix, /nix/share, /nix/var/nix. But I still don't understand how they relate to how nix uses XDG_CONFIG_HOME, XDG_DATA_HOME and XDG_STATE_HOME. Are they only used when Nix is run as root, or when use-xdg-base-directories is not set?
@roberth Ok, I dug a bit in the code. From what I see, NIX_STATE_DIR and NIX_CONF_DIR are used for various things, treating them as being global for the system. NIX_STATE_DIR is also used only for the root user to get the profiles directory. I didn't see any uses of NIX_DATA_DIR, it seems to have no effect.
So, I don't want to touch NIX_STATE_DIR and NIX_CONF_DIR.
Therefore, I don't think that the suffix _DIR can work, since it's already used for something else.
I still think that the _HOME suffix is a reasonable choice, as it makes the relation to the XDG_*_HOME envvars clearer, and since the default is really in the home dir.
Another alternative can be NIX_USER_CACHE_DIR, NIX_USER_STATE_DIR etc, to differentiate those envvars from the system ones.
What do you think?
I didn't realise the names collided. Sorry for the red herring.
NIX_USER_CACHE_DIR
Also reasonable. I think I'm fine with either of your proposed naming schemes.
@roberth sorry it took me so long. I updated env-common.md with a description of the NIX_*_HOME envvars.
What are the next steps?
Thanks!
@fricklerhandwerk Thanks! I committed your suggestions, they improve my text. I added a changelog. How does it look?
This pull request has been mentioned on NixOS Discourse. There might be relevant details there:
https://discourse.nixos.org/t/nix-2-25-released/55994/1