Read per-user settings from ~/.config/nix/nix.conf
This commit is contained in:
parent
562585e901
commit
f05d5f89ff
|
@ -17,13 +17,32 @@
|
||||||
|
|
||||||
<refsection><title>Description</title>
|
<refsection><title>Description</title>
|
||||||
|
|
||||||
<para>A number of persistent settings of Nix are stored in the file
|
<para>Nix reads settings from two configuration files:</para>
|
||||||
<filename><replaceable>sysconfdir</replaceable>/nix/nix.conf</filename> or
|
|
||||||
<filename>$NIX_CONF_DIR/nix.conf</filename> if <envar>NIX_CONF_DIR</envar> is set.
|
<itemizedlist>
|
||||||
This file is a list of <literal><replaceable>name</replaceable> =
|
|
||||||
|
<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.
|
<replaceable>value</replaceable></literal> pairs, one per line.
|
||||||
Comments start with a <literal>#</literal> character. Here is an example
|
Comments start with a <literal>#</literal> character. Here is an
|
||||||
configuration file:</para>
|
example configuration file:</para>
|
||||||
|
|
||||||
<programlisting>
|
<programlisting>
|
||||||
gc-keep-outputs = true # Nice for developers
|
gc-keep-outputs = true # Nice for developers
|
||||||
|
@ -31,8 +50,9 @@ gc-keep-derivations = true # Idem
|
||||||
env-keep-derivations = false
|
env-keep-derivations = false
|
||||||
</programlisting>
|
</programlisting>
|
||||||
|
|
||||||
<para>You can override settings using the <option>--option</option>
|
<para>You can override settings on the command line using the
|
||||||
flag, e.g. <literal>--option gc-keep-outputs false</literal>.</para>
|
<option>--option</option> flag, e.g. <literal>--option gc-keep-outputs
|
||||||
|
false</literal>.</para>
|
||||||
|
|
||||||
<para>The following settings are currently available:
|
<para>The following settings are currently available:
|
||||||
|
|
||||||
|
|
|
@ -53,19 +53,19 @@ Settings::Settings()
|
||||||
void Settings::loadConfFile()
|
void Settings::loadConfFile()
|
||||||
{
|
{
|
||||||
applyConfigFile(nixConfDir + "/nix.conf");
|
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)
|
void Settings::set(const string & name, const string & value)
|
||||||
{
|
{
|
||||||
overrides[name] = value;
|
|
||||||
Config::set(name, value);
|
Config::set(name, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
StringMap Settings::getOverrides()
|
|
||||||
{
|
|
||||||
return overrides;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int Settings::getDefaultCores()
|
unsigned int Settings::getDefaultCores()
|
||||||
{
|
{
|
||||||
return std::max(1U, std::thread::hardware_concurrency());
|
return std::max(1U, std::thread::hardware_concurrency());
|
||||||
|
|
|
@ -15,8 +15,6 @@ extern bool useCaseHack; // FIXME
|
||||||
|
|
||||||
class Settings : public Config {
|
class Settings : public Config {
|
||||||
|
|
||||||
StringMap overrides;
|
|
||||||
|
|
||||||
unsigned int getDefaultCores();
|
unsigned int getDefaultCores();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -27,8 +25,6 @@ public:
|
||||||
|
|
||||||
void set(const string & name, const string & value);
|
void set(const string & name, const string & value);
|
||||||
|
|
||||||
StringMap getOverrides();
|
|
||||||
|
|
||||||
Path nixPrefix;
|
Path nixPrefix;
|
||||||
|
|
||||||
/* The directory where we store sources and derived files. */
|
/* The directory where we store sources and derived files. */
|
||||||
|
|
|
@ -166,7 +166,7 @@ void RemoteStore::setOptions(Connection & conn)
|
||||||
<< settings.useSubstitutes;
|
<< settings.useSubstitutes;
|
||||||
|
|
||||||
if (GET_PROTOCOL_MINOR(conn.daemonVersion) >= 12) {
|
if (GET_PROTOCOL_MINOR(conn.daemonVersion) >= 12) {
|
||||||
StringMap overrides = settings.getOverrides();
|
auto overrides = settings.getSettings(true);
|
||||||
conn.to << overrides.size();
|
conn.to << overrides.size();
|
||||||
for (auto & i : overrides)
|
for (auto & i : overrides)
|
||||||
conn.to << i.first << i.second;
|
conn.to << i.first << i.second;
|
||||||
|
|
|
@ -9,6 +9,7 @@ void Config::set(const std::string & name, const std::string & value)
|
||||||
if (i == _settings.end())
|
if (i == _settings.end())
|
||||||
throw UsageError("unknown setting '%s'", name);
|
throw UsageError("unknown setting '%s'", name);
|
||||||
i->second.setting->set(value);
|
i->second.setting->set(value);
|
||||||
|
i->second.setting->overriden = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Config::addSetting(AbstractSetting * setting)
|
void Config::addSetting(AbstractSetting * setting)
|
||||||
|
@ -22,6 +23,7 @@ void Config::addSetting(AbstractSetting * setting)
|
||||||
auto i = initials.find(setting->name);
|
auto i = initials.find(setting->name);
|
||||||
if (i != initials.end()) {
|
if (i != initials.end()) {
|
||||||
setting->set(i->second);
|
setting->set(i->second);
|
||||||
|
setting->overriden = true;
|
||||||
initials.erase(i);
|
initials.erase(i);
|
||||||
set = true;
|
set = true;
|
||||||
}
|
}
|
||||||
|
@ -34,6 +36,7 @@ void Config::addSetting(AbstractSetting * setting)
|
||||||
alias, setting->name);
|
alias, setting->name);
|
||||||
else {
|
else {
|
||||||
setting->set(i->second);
|
setting->set(i->second);
|
||||||
|
setting->overriden = true;
|
||||||
initials.erase(i);
|
initials.erase(i);
|
||||||
set = true;
|
set = true;
|
||||||
}
|
}
|
||||||
|
@ -47,11 +50,11 @@ void Config::warnUnknownSettings()
|
||||||
warn("unknown setting '%s'", i.first);
|
warn("unknown setting '%s'", i.first);
|
||||||
}
|
}
|
||||||
|
|
||||||
StringMap Config::getSettings()
|
StringMap Config::getSettings(bool overridenOnly)
|
||||||
{
|
{
|
||||||
StringMap res;
|
StringMap res;
|
||||||
for (auto & opt : _settings)
|
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());
|
res.emplace(opt.first, opt.second.setting->to_string());
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -94,6 +97,12 @@ void Config::applyConfigFile(const Path & path, bool fatal)
|
||||||
} catch (SysError &) { }
|
} catch (SysError &) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Config::resetOverriden()
|
||||||
|
{
|
||||||
|
for (auto & s : _settings)
|
||||||
|
s.second.setting->overriden = false;
|
||||||
|
}
|
||||||
|
|
||||||
AbstractSetting::AbstractSetting(
|
AbstractSetting::AbstractSetting(
|
||||||
const std::string & name,
|
const std::string & name,
|
||||||
const std::string & description,
|
const std::string & description,
|
||||||
|
|
|
@ -51,9 +51,11 @@ public:
|
||||||
|
|
||||||
void warnUnknownSettings();
|
void warnUnknownSettings();
|
||||||
|
|
||||||
StringMap getSettings();
|
StringMap getSettings(bool overridenOnly = false);
|
||||||
|
|
||||||
void applyConfigFile(const Path & path, bool fatal = false);
|
void applyConfigFile(const Path & path, bool fatal = false);
|
||||||
|
|
||||||
|
void resetOverriden();
|
||||||
};
|
};
|
||||||
|
|
||||||
class AbstractSetting
|
class AbstractSetting
|
||||||
|
@ -68,6 +70,8 @@ public:
|
||||||
|
|
||||||
int created = 123;
|
int created = 123;
|
||||||
|
|
||||||
|
bool overriden = false;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
AbstractSetting(
|
AbstractSetting(
|
||||||
|
@ -78,7 +82,7 @@ protected:
|
||||||
virtual ~AbstractSetting()
|
virtual ~AbstractSetting()
|
||||||
{
|
{
|
||||||
// Check against a gcc miscompilation causing our constructor
|
// 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);
|
assert(created == 123);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,6 +92,8 @@ protected:
|
||||||
|
|
||||||
bool parseBool(const std::string & str);
|
bool parseBool(const std::string & str);
|
||||||
std::string printBool(bool b);
|
std::string printBool(bool b);
|
||||||
|
|
||||||
|
bool isOverriden() { return overriden; }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DefaultSettingTag { };
|
struct DefaultSettingTag { };
|
||||||
|
|
|
@ -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 createDirs(const Path & path)
|
||||||
{
|
{
|
||||||
Paths created;
|
Paths created;
|
||||||
|
|
|
@ -110,9 +110,12 @@ void deletePath(const Path & path, unsigned long long & bytesFreed);
|
||||||
Path createTempDir(const Path & tmpRoot = "", const Path & prefix = "nix",
|
Path createTempDir(const Path & tmpRoot = "", const Path & prefix = "nix",
|
||||||
bool includePid = true, bool useGlobalCounter = true, mode_t mode = 0755);
|
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();
|
Path getCacheDir();
|
||||||
|
|
||||||
|
/* Return $XDG_CONFIG_HOME or $HOME/.config. */
|
||||||
|
Path getConfigDir();
|
||||||
|
|
||||||
/* Create a directory and all its parents, if necessary. Returns the
|
/* Create a directory and all its parents, if necessary. Returns the
|
||||||
list of created directories, in order of creation. */
|
list of created directories, in order of creation. */
|
||||||
Paths createDirs(const Path & path);
|
Paths createDirs(const Path & path);
|
||||||
|
|
Loading…
Reference in a new issue