diff options
author | Alexander Bantyev <balsoft@balsoft.ru> | 2021-11-17 23:35:21 +0300 |
---|---|---|
committer | Alexander Bantyev <balsoft@balsoft.ru> | 2023-02-10 20:14:06 +0400 |
commit | 2384d360839e27edb3c928da858ec911415c8b4d (patch) | |
tree | 95e5360fc7016b9d171f4bad320486eda168bbb1 /src | |
parent | a31d7d4e5e5eeeb7ca12ca798dc383045e5be1a1 (diff) |
A setting to follow XDG Base Directory standard
XDG Base Directory is a standard for locations for storing various
files. Nix has a few files which seem to fit in the standard, but
currently use a custom location directly in the user's ~, polluting
it:
- ~/.nix-profile
- ~/.nix-defexpr
- ~/.nix-channels
This commit adds a config option (use-xdg-base-directories) to follow
the XDG spec and instead use the following locations:
- $XDG_STATE_HOME/nix/profile
- $XDG_STATE_HOME/nix/defexpr
- $XDG_STATE_HOME/nix/channels
If $XDG_STATE_HOME is not set, it is assumed to be ~/.local/state.
Co-authored-by: Théophane Hufschmitt <7226587+thufschmitt@users.noreply.github.com>
Co-authored-by: Tim Fenney <kodekata@gmail.com>
Co-authored-by: pasqui23 <pasqui23@users.noreply.github.com>
Co-authored-by: Artturin <Artturin@artturin.com>
Co-authored-by: John Ericson <Ericson2314@Yahoo.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/libexpr/eval.cc | 2 | ||||
-rw-r--r-- | src/libstore/globals.hh | 21 | ||||
-rw-r--r-- | src/libstore/profiles.cc | 4 | ||||
-rw-r--r-- | src/libstore/profiles.hh | 5 | ||||
-rw-r--r-- | src/libutil/util.cc | 13 | ||||
-rw-r--r-- | src/libutil/util.hh | 6 | ||||
-rwxr-xr-x | src/nix-channel/nix-channel.cc | 4 | ||||
-rw-r--r-- | src/nix-env/nix-env.cc | 7 |
8 files changed, 53 insertions, 9 deletions
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index a48968656..3e37c7f60 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -2496,7 +2496,7 @@ Strings EvalSettings::getDefaultNixPath() res.push_back(s ? *s + "=" + p : p); }; - add(getHome() + "/.nix-defexpr/channels"); + add(settings.useXDGBaseDirectories ? getStateDir() + "/nix/defexpr/channels" : getHome() + "/.nix-defexpr/channels"); add(settings.nixStateDir + "/profiles/per-user/root/channels/nixpkgs", "nixpkgs"); add(settings.nixStateDir + "/profiles/per-user/root/channels"); diff --git a/src/libstore/globals.hh b/src/libstore/globals.hh index c3ccb5e11..40f10fde3 100644 --- a/src/libstore/globals.hh +++ b/src/libstore/globals.hh @@ -975,6 +975,27 @@ public: resolves to a different location from that of the build machine. You can enable this setting if you are sure you're not going to do that. )"}; + + Setting<bool> useXDGBaseDirectories{ + this, false, "use-xdg-base-directories", + R"( + If set to `true`, Nix will conform to the [XDG Base Directory Specification] for files in `$HOME`. + The environment variables used to implement this are documented in the [Environment Variables section](@docroot@/installation/env-variables.md). + + [XDG Base Directory Specification]: https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html + + > **Warning** + > This changes the location of some well-known symlinks that Nix creates, which might break tools that rely on the old, non-XDG-conformant locations. + + In particular, the following locations change: + + | Old | New | + |-------------------|--------------------------------| + | `~/.nix-profile` | `$XDG_STATE_HOME/nix/profile` | + | `~/.nix-defexpr` | `$XDG_STATE_HOME/nix/defexpr` | + | `~/.nix-channels` | `$XDG_STATE_HOME/nix/channels` | + )" + }; }; diff --git a/src/libstore/profiles.cc b/src/libstore/profiles.cc index b202351ce..c551c5f3e 100644 --- a/src/libstore/profiles.cc +++ b/src/libstore/profiles.cc @@ -282,7 +282,7 @@ std::string optimisticLockProfile(const Path & profile) Path profilesDir() { - auto profileRoot = getDataDir() + "/nix/profiles"; + auto profileRoot = createNixStateDir() + "/profiles"; createDirs(profileRoot); return profileRoot; } @@ -290,7 +290,7 @@ Path profilesDir() Path getDefaultProfile() { - Path profileLink = getHome() + "/.nix-profile"; + Path profileLink = settings.useXDGBaseDirectories ? createNixStateDir() + "/profile" : getHome() + "/.nix-profile"; try { auto profile = getuid() == 0 diff --git a/src/libstore/profiles.hh b/src/libstore/profiles.hh index 73667a798..fbf95b850 100644 --- a/src/libstore/profiles.hh +++ b/src/libstore/profiles.hh @@ -72,8 +72,9 @@ std::string optimisticLockProfile(const Path & profile); profiles. */ Path profilesDir(); -/* Resolve ~/.nix-profile. If ~/.nix-profile doesn't exist yet, create - it. */ +/* Resolve the default profile (~/.nix-profile by default, $XDG_STATE_HOME/ + nix/profile if XDG Base Directory Support is enabled), and create if doesn't + exist */ Path getDefaultProfile(); } diff --git a/src/libutil/util.cc b/src/libutil/util.cc index 40faa4bf2..40a54b010 100644 --- a/src/libutil/util.cc +++ b/src/libutil/util.cc @@ -608,6 +608,19 @@ Path getDataDir() return dataDir ? *dataDir : getHome() + "/.local/share"; } +Path getStateDir() +{ + auto stateDir = getEnv("XDG_STATE_HOME"); + return stateDir ? *stateDir : getHome() + "/.local/state"; +} + +Path createNixStateDir() +{ + Path dir = getStateDir() + "/nix"; + createDirs(dir); + return dir; +} + std::optional<Path> getSelfExe() { diff --git a/src/libutil/util.hh b/src/libutil/util.hh index 266da0ae3..4fadafaf2 100644 --- a/src/libutil/util.hh +++ b/src/libutil/util.hh @@ -158,6 +158,12 @@ Path getDataDir(); /* Return the path of the current executable. */ std::optional<Path> getSelfExe(); +/* Return $XDG_STATE_HOME or $HOME/.local/state. */ +Path getStateDir(); + +/* Create the Nix state directory and return the path to it. */ +Path createNixStateDir(); + /* Create a directory and all its parents, if necessary. Returns the list of created directories, in order of creation. */ Paths createDirs(const Path & path); diff --git a/src/nix-channel/nix-channel.cc b/src/nix-channel/nix-channel.cc index 263d85eea..338a7d18e 100755 --- a/src/nix-channel/nix-channel.cc +++ b/src/nix-channel/nix-channel.cc @@ -164,8 +164,8 @@ static int main_nix_channel(int argc, char ** argv) { // Figure out the name of the `.nix-channels' file to use auto home = getHome(); - channelsList = home + "/.nix-channels"; - nixDefExpr = home + "/.nix-defexpr"; + channelsList = settings.useXDGBaseDirectories ? createNixStateDir() + "/channels" : home + "/.nix-channels"; + nixDefExpr = settings.useXDGBaseDirectories ? createNixStateDir() + "/defexpr" : home + "/.nix-defexpr"; // Figure out the name of the channels profile. profile = profilesDir() + "/channels"; diff --git a/src/nix-env/nix-env.cc b/src/nix-env/nix-env.cc index 406e548c0..0daf374de 100644 --- a/src/nix-env/nix-env.cc +++ b/src/nix-env/nix-env.cc @@ -1289,7 +1289,7 @@ static void opSwitchProfile(Globals & globals, Strings opFlags, Strings opArgs) throw UsageError("exactly one argument expected"); Path profile = absPath(opArgs.front()); - Path profileLink = getHome() + "/.nix-profile"; + Path profileLink = settings.useXDGBaseDirectories ? createNixStateDir() + "/profile" : getHome() + "/.nix-profile"; switchLink(profileLink, profile); } @@ -1393,7 +1393,10 @@ static int main_nix_env(int argc, char * * argv) Globals globals; globals.instSource.type = srcUnknown; - globals.instSource.nixExprPath = getHome() + "/.nix-defexpr"; + { + Path nixExprPath = settings.useXDGBaseDirectories ? createNixStateDir() + "/defexpr" : getHome() + "/.nix-defexpr"; + globals.instSource.nixExprPath = nixExprPath; + } globals.instSource.systemFilter = "*"; if (!pathExists(globals.instSource.nixExprPath)) { |