diff --git a/src/libcmd/command.cc b/src/libcmd/command.cc index 6cc93306974..d57b7641132 100644 --- a/src/libcmd/command.cc +++ b/src/libcmd/command.cc @@ -325,7 +325,7 @@ void MixProfile::updateProfile(Store & store, const BuiltPaths & buildables) MixDefaultProfile::MixDefaultProfile() { - profile = getDefaultProfile().string(); + profile = getDefaultProfile(settings.getProfileDirsOptions()).string(); } static constexpr auto environmentVariablesCategory = "Options that change environment variables"; diff --git a/src/libexpr/eval-settings.cc b/src/libexpr/eval-settings.cc index 04c6193885e..286d588b07d 100644 --- a/src/libexpr/eval-settings.cc +++ b/src/libexpr/eval-settings.cc @@ -71,8 +71,9 @@ Strings EvalSettings::getDefaultNixPath() }; add(std::filesystem::path{getNixDefExpr()} / "channels"); - add(rootChannelsDir() / "nixpkgs", "nixpkgs"); - add(rootChannelsDir()); + auto profilesDirOpts = settings.getProfileDirsOptions(); + add(rootChannelsDir(profilesDirOpts) / "nixpkgs", "nixpkgs"); + add(rootChannelsDir(profilesDirOpts)); return res; } diff --git a/src/libstore/globals.cc b/src/libstore/globals.cc index 47086519ad3..6a0a8c97313 100644 --- a/src/libstore/globals.cc +++ b/src/libstore/globals.cc @@ -1,4 +1,5 @@ #include "nix/store/globals.hh" +#include "nix/store/profiles.hh" #include "nix/util/config-impl.hh" #include "nix/util/config-global.hh" #include "nix/util/current-process.hh" @@ -294,6 +295,14 @@ const ExternalBuilder * Settings::findExternalDerivationBuilderIfSupported(const return nullptr; } +ProfileDirsOptions Settings::getProfileDirsOptions() const +{ + return { + .nixStateDir = nixStateDir, + .useXDGBaseDirectories = useXDGBaseDirectories, + }; +} + std::string nixVersion = PACKAGE_VERSION; NLOHMANN_JSON_SERIALIZE_ENUM( diff --git a/src/libstore/include/nix/store/globals.hh b/src/libstore/include/nix/store/globals.hh index 44c45526f7e..1a428d3df8d 100644 --- a/src/libstore/include/nix/store/globals.hh +++ b/src/libstore/include/nix/store/globals.hh @@ -15,6 +15,8 @@ namespace nix { +struct ProfileDirsOptions; + struct LogFileSettings : public virtual Config { /** @@ -398,6 +400,11 @@ public: * derivation, or else returns a null pointer. */ const ExternalBuilder * findExternalDerivationBuilderIfSupported(const Derivation & drv); + + /** + * Get the options needed for profile directory functions. + */ + ProfileDirsOptions getProfileDirsOptions() const; }; // FIXME: don't use a global variable. diff --git a/src/libstore/include/nix/store/profiles.hh b/src/libstore/include/nix/store/profiles.hh index 1cc306744f7..11a3fbe89f0 100644 --- a/src/libstore/include/nix/store/profiles.hh +++ b/src/libstore/include/nix/store/profiles.hh @@ -209,32 +209,38 @@ void lockProfile(PathLocks & lock, const std::filesystem::path & profile); */ std::string optimisticLockProfile(const std::filesystem::path & profile); +struct ProfileDirsOptions +{ + const std::filesystem::path & nixStateDir; + bool useXDGBaseDirectories; +}; + /** * Create and return the path to a directory suitable for storing the user’s * profiles. */ -std::filesystem::path profilesDir(); +std::filesystem::path profilesDir(ProfileDirsOptions opts); /** * Return the path to the profile directory for root (but don't try creating it) */ -std::filesystem::path rootProfilesDir(); +std::filesystem::path rootProfilesDir(ProfileDirsOptions opts); /** * Create and return the path to the file used for storing the users's channels */ -std::filesystem::path defaultChannelsDir(); +std::filesystem::path defaultChannelsDir(ProfileDirsOptions opts); /** * Return the path to the channel directory for root (but don't try creating it) */ -std::filesystem::path rootChannelsDir(); +std::filesystem::path rootChannelsDir(ProfileDirsOptions opts); /** * 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 */ -std::filesystem::path getDefaultProfile(); +std::filesystem::path getDefaultProfile(ProfileDirsOptions opts); } // namespace nix diff --git a/src/libstore/profiles.cc b/src/libstore/profiles.cc index 983ba4e4156..b0126351a21 100644 --- a/src/libstore/profiles.cc +++ b/src/libstore/profiles.cc @@ -291,31 +291,32 @@ std::string optimisticLockProfile(const std::filesystem::path & profile) return pathExists(profile) ? readLink(profile).string() : ""; } -std::filesystem::path profilesDir() +std::filesystem::path profilesDir(ProfileDirsOptions settings) { - auto profileRoot = isRootUser() ? rootProfilesDir() : std::filesystem::path{createNixStateDir()} / "profiles"; + auto profileRoot = + isRootUser() ? rootProfilesDir(settings) : std::filesystem::path{createNixStateDir()} / "profiles"; createDirs(profileRoot); return profileRoot; } -std::filesystem::path rootProfilesDir() +std::filesystem::path rootProfilesDir(ProfileDirsOptions settings) { - return std::filesystem::path{settings.nixStateDir} / "profiles/per-user/root"; + return settings.nixStateDir / "profiles/per-user/root"; } -std::filesystem::path getDefaultProfile() +std::filesystem::path getDefaultProfile(ProfileDirsOptions settings) { std::filesystem::path profileLink = settings.useXDGBaseDirectories ? std::filesystem::path{createNixStateDir()} / "profile" : std::filesystem::path{getHome()} / ".nix-profile"; try { - auto profile = profilesDir() / "profile"; + auto profile = profilesDir(settings) / "profile"; if (!pathExists(profileLink)) { replaceSymlink(profile, profileLink); } // Backwards compatibility measure: Make root's profile available as // `.../default` as it's what NixOS and most of the init scripts expect - auto globalProfileLink = std::filesystem::path{settings.nixStateDir} / "profiles" / "default"; + auto globalProfileLink = settings.nixStateDir / "profiles" / "default"; if (isRootUser() && !pathExists(globalProfileLink)) { replaceSymlink(profile, globalProfileLink); } @@ -328,14 +329,14 @@ std::filesystem::path getDefaultProfile() } } -std::filesystem::path defaultChannelsDir() +std::filesystem::path defaultChannelsDir(ProfileDirsOptions settings) { - return profilesDir() / "channels"; + return profilesDir(settings) / "channels"; } -std::filesystem::path rootChannelsDir() +std::filesystem::path rootChannelsDir(ProfileDirsOptions settings) { - return rootProfilesDir() / "channels"; + return rootProfilesDir(settings) / "channels"; } } // namespace nix diff --git a/src/nix/nix-channel/nix-channel.cc b/src/nix/nix-channel/nix-channel.cc index 8fcd9db79f0..6c6a6356fc3 100644 --- a/src/nix/nix-channel/nix-channel.cc +++ b/src/nix/nix-channel/nix-channel.cc @@ -192,7 +192,7 @@ static int main_nix_channel(int argc, char ** argv) nixDefExpr = getNixDefExpr(); // Figure out the name of the channels profile. - profile = profilesDir() + "/channels"; + profile = profilesDir(settings.getProfileDirsOptions()) + "/channels"; createDirs(dirOf(profile)); enum { cNone, cAdd, cRemove, cList, cUpdate, cListGenerations, cRollback } cmd = cNone; diff --git a/src/nix/nix-collect-garbage/nix-collect-garbage.cc b/src/nix/nix-collect-garbage/nix-collect-garbage.cc index 29ca17a5de2..e93821cab6a 100644 --- a/src/nix/nix-collect-garbage/nix-collect-garbage.cc +++ b/src/nix/nix-collect-garbage/nix-collect-garbage.cc @@ -88,10 +88,11 @@ static int main_nix_collect_garbage(int argc, char ** argv) }); if (removeOld) { + auto profilesDirOpts = settings.getProfileDirsOptions(); std::set dirsToClean = { - profilesDir(), + profilesDir(profilesDirOpts), std::filesystem::path{settings.nixStateDir} / "profiles", - getDefaultProfile().parent_path(), + getDefaultProfile(profilesDirOpts).parent_path(), }; for (auto & dir : dirsToClean) removeOldGenerations(dir); diff --git a/src/nix/nix-env/nix-env.cc b/src/nix/nix-env/nix-env.cc index 8047fd30593..4a46e7ca65b 100644 --- a/src/nix/nix-env/nix-env.cc +++ b/src/nix/nix-env/nix-env.cc @@ -1414,10 +1414,11 @@ static int main_nix_env(int argc, char ** argv) if (!pathExists(nixExprPath)) { try { + auto profilesDirOpts = settings.getProfileDirsOptions(); createDirs(nixExprPath); - replaceSymlink(defaultChannelsDir(), nixExprPath / "channels"); + replaceSymlink(defaultChannelsDir(profilesDirOpts), nixExprPath / "channels"); if (!isRootUser()) - replaceSymlink(rootChannelsDir(), nixExprPath / "channels_root"); + replaceSymlink(rootChannelsDir(profilesDirOpts), nixExprPath / "channels_root"); } catch (std::filesystem::filesystem_error &) { } catch (Error &) { } @@ -1524,7 +1525,7 @@ static int main_nix_env(int argc, char ** argv) globals.profile = getEnv("NIX_PROFILE").value_or(""); if (globals.profile == "") - globals.profile = getDefaultProfile().string(); + globals.profile = getDefaultProfile(settings.getProfileDirsOptions()).string(); op(globals, std::move(opFlags), std::move(opArgs));