aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2017-04-20 14:58:16 +0200
committerEelco Dolstra <edolstra@gmail.com>2017-04-20 14:58:16 +0200
commitf05d5f89ff4ec52ed2f6d576b2b2323b5292f815 (patch)
tree86912765d3dbe77b0e810ad3169dc364015fa71a
parent562585e901d9e5f2ef62be11c2e74badcacb1f50 (diff)
Read per-user settings from ~/.config/nix/nix.conf
-rw-r--r--doc/manual/command-ref/conf-file.xml36
-rw-r--r--src/libstore/globals.cc12
-rw-r--r--src/libstore/globals.hh4
-rw-r--r--src/libstore/remote-store.cc2
-rw-r--r--src/libutil/config.cc13
-rw-r--r--src/libutil/config.hh10
-rw-r--r--src/libutil/util.cc12
-rw-r--r--src/libutil/util.hh5
8 files changed, 70 insertions, 24 deletions
diff --git a/doc/manual/command-ref/conf-file.xml b/doc/manual/command-ref/conf-file.xml
index 79e18de9b..616983bc7 100644
--- a/doc/manual/command-ref/conf-file.xml
+++ b/doc/manual/command-ref/conf-file.xml
@@ -17,13 +17,32 @@
<refsection><title>Description</title>
-<para>A number of persistent settings of Nix are stored in the file
-<filename><replaceable>sysconfdir</replaceable>/nix/nix.conf</filename> or
-<filename>$NIX_CONF_DIR/nix.conf</filename> if <envar>NIX_CONF_DIR</envar> is set.
-This file is a list of <literal><replaceable>name</replaceable> =
+<para>Nix reads settings from two configuration files:</para>
+
+<itemizedlist>
+
+ <listitem>
+ <para>The system-wide configuration file
+ <filename><replaceable>sysconfdir</replaceable>/nix/nix.conf</filename>
+ (i.e. <filename>/etc/nix/nix.conf</filename> on most systems), or
+ <filename>$NIX_CONF_DIR/nix.conf</filename> if
+ <envar>NIX_CONF_DIR</envar> is set.</para>
+ </listitem>
+
+ <listitem>
+ <para>The user configuration file
+ <filename>$XDG_CONFIG_HOME/nix/nix.conf</filename>, or
+ <filename>~/.config/nix/nix.conf</filename> if
+ <envar>XDG_CONFIG_HOME</envar> is not set.</para>
+ </listitem>
+
+</itemizedlist>
+
+<para>The configuration files consist of
+<literal><replaceable>name</replaceable> =
<replaceable>value</replaceable></literal> pairs, one per line.
-Comments start with a <literal>#</literal> character. Here is an example
-configuration file:</para>
+Comments start with a <literal>#</literal> character. Here is an
+example configuration file:</para>
<programlisting>
gc-keep-outputs = true # Nice for developers
@@ -31,8 +50,9 @@ gc-keep-derivations = true # Idem
env-keep-derivations = false
</programlisting>
-<para>You can override settings using the <option>--option</option>
-flag, e.g. <literal>--option gc-keep-outputs false</literal>.</para>
+<para>You can override settings on the command line using the
+<option>--option</option> flag, e.g. <literal>--option gc-keep-outputs
+false</literal>.</para>
<para>The following settings are currently available:
diff --git a/src/libstore/globals.cc b/src/libstore/globals.cc
index bb61daa51..6b9d07746 100644
--- a/src/libstore/globals.cc
+++ b/src/libstore/globals.cc
@@ -53,19 +53,19 @@ Settings::Settings()
void Settings::loadConfFile()
{
applyConfigFile(nixConfDir + "/nix.conf");
+
+ /* We only want to send overrides to the daemon, i.e. stuff from
+ ~/.nix/nix.conf or the command line. */
+ resetOverriden();
+
+ applyConfigFile(getConfigDir() + "/nix/nix.conf");
}
void Settings::set(const string & name, const string & value)
{
- overrides[name] = value;
Config::set(name, value);
}
-StringMap Settings::getOverrides()
-{
- return overrides;
-}
-
unsigned int Settings::getDefaultCores()
{
return std::max(1U, std::thread::hardware_concurrency());
diff --git a/src/libstore/globals.hh b/src/libstore/globals.hh
index de64e9826..d3ecaadb6 100644
--- a/src/libstore/globals.hh
+++ b/src/libstore/globals.hh
@@ -15,8 +15,6 @@ extern bool useCaseHack; // FIXME
class Settings : public Config {
- StringMap overrides;
-
unsigned int getDefaultCores();
public:
@@ -27,8 +25,6 @@ public:
void set(const string & name, const string & value);
- StringMap getOverrides();
-
Path nixPrefix;
/* The directory where we store sources and derived files. */
diff --git a/src/libstore/remote-store.cc b/src/libstore/remote-store.cc
index da3c8eb8d..bc9ef3d47 100644
--- a/src/libstore/remote-store.cc
+++ b/src/libstore/remote-store.cc
@@ -166,7 +166,7 @@ void RemoteStore::setOptions(Connection & conn)
<< settings.useSubstitutes;
if (GET_PROTOCOL_MINOR(conn.daemonVersion) >= 12) {
- StringMap overrides = settings.getOverrides();
+ auto overrides = settings.getSettings(true);
conn.to << overrides.size();
for (auto & i : overrides)
conn.to << i.first << i.second;
diff --git a/src/libutil/config.cc b/src/libutil/config.cc
index e7a810cec..bf1372997 100644
--- a/src/libutil/config.cc
+++ b/src/libutil/config.cc
@@ -9,6 +9,7 @@ void Config::set(const std::string & name, const std::string & value)
if (i == _settings.end())
throw UsageError("unknown setting '%s'", name);
i->second.setting->set(value);
+ i->second.setting->overriden = true;
}
void Config::addSetting(AbstractSetting * setting)
@@ -22,6 +23,7 @@ void Config::addSetting(AbstractSetting * setting)
auto i = initials.find(setting->name);
if (i != initials.end()) {
setting->set(i->second);
+ setting->overriden = true;
initials.erase(i);
set = true;
}
@@ -34,6 +36,7 @@ void Config::addSetting(AbstractSetting * setting)
alias, setting->name);
else {
setting->set(i->second);
+ setting->overriden = true;
initials.erase(i);
set = true;
}
@@ -47,11 +50,11 @@ void Config::warnUnknownSettings()
warn("unknown setting '%s'", i.first);
}
-StringMap Config::getSettings()
+StringMap Config::getSettings(bool overridenOnly)
{
StringMap res;
for (auto & opt : _settings)
- if (!opt.second.isAlias)
+ if (!opt.second.isAlias && (!overridenOnly || opt.second.setting->overriden))
res.emplace(opt.first, opt.second.setting->to_string());
return res;
}
@@ -94,6 +97,12 @@ void Config::applyConfigFile(const Path & path, bool fatal)
} catch (SysError &) { }
}
+void Config::resetOverriden()
+{
+ for (auto & s : _settings)
+ s.second.setting->overriden = false;
+}
+
AbstractSetting::AbstractSetting(
const std::string & name,
const std::string & description,
diff --git a/src/libutil/config.hh b/src/libutil/config.hh
index 6c8612f67..952bf04b8 100644
--- a/src/libutil/config.hh
+++ b/src/libutil/config.hh
@@ -51,9 +51,11 @@ public:
void warnUnknownSettings();
- StringMap getSettings();
+ StringMap getSettings(bool overridenOnly = false);
void applyConfigFile(const Path & path, bool fatal = false);
+
+ void resetOverriden();
};
class AbstractSetting
@@ -68,6 +70,8 @@ public:
int created = 123;
+ bool overriden = false;
+
protected:
AbstractSetting(
@@ -78,7 +82,7 @@ protected:
virtual ~AbstractSetting()
{
// Check against a gcc miscompilation causing our constructor
- // not to run.
+ // not to run (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80431).
assert(created == 123);
}
@@ -88,6 +92,8 @@ protected:
bool parseBool(const std::string & str);
std::string printBool(bool b);
+
+ bool isOverriden() { return overriden; }
};
struct DefaultSettingTag { };
diff --git a/src/libutil/util.cc b/src/libutil/util.cc
index 0bd51afd1..37dfccd06 100644
--- a/src/libutil/util.cc
+++ b/src/libutil/util.cc
@@ -429,6 +429,18 @@ Path getCacheDir()
}
+Path getConfigDir()
+{
+ Path configDir = getEnv("XDG_CONFIG_HOME");
+ if (configDir.empty()) {
+ Path homeDir = getEnv("HOME");
+ if (homeDir.empty()) throw Error("$XDG_CONFIG_HOME and $HOME are not set");
+ configDir = homeDir + "/.config";
+ }
+ return configDir;
+}
+
+
Paths createDirs(const Path & path)
{
Paths created;
diff --git a/src/libutil/util.hh b/src/libutil/util.hh
index 0e6941e4a..121423cda 100644
--- a/src/libutil/util.hh
+++ b/src/libutil/util.hh
@@ -110,9 +110,12 @@ void deletePath(const Path & path, unsigned long long & bytesFreed);
Path createTempDir(const Path & tmpRoot = "", const Path & prefix = "nix",
bool includePid = true, bool useGlobalCounter = true, mode_t mode = 0755);
-/* Return the path to $XDG_CACHE_HOME/.cache. */
+/* Return $XDG_CACHE_HOME or $HOME/.cache. */
Path getCacheDir();
+/* Return $XDG_CONFIG_HOME or $HOME/.config. */
+Path getConfigDir();
+
/* Create a directory and all its parents, if necessary. Returns the
list of created directories, in order of creation. */
Paths createDirs(const Path & path);