aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/libexpr/eval.cc2
-rw-r--r--src/libstore/globals.hh21
-rw-r--r--src/libstore/profiles.cc4
-rw-r--r--src/libstore/profiles.hh5
-rw-r--r--src/libutil/util.cc13
-rw-r--r--src/libutil/util.hh6
-rwxr-xr-xsrc/nix-channel/nix-channel.cc4
-rw-r--r--src/nix-env/nix-env.cc7
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)) {