Read per-user settings from ~/.config/nix/nix.conf
This commit is contained in:
		
							parent
							
								
									562585e901
								
							
						
					
					
						commit
						f05d5f89ff
					
				
					 8 changed files with 70 additions and 24 deletions
				
			
		|  | @ -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…
	
	Add table
		Add a link
		
	
		Reference in a new issue