about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorShea Levy <shea@shealevy.com>2018-02-13T19·43-0500
committerShea Levy <shea@shealevy.com>2018-02-13T19·43-0500
commitde4934ab3b26aa851b7044e9884102cc054dc092 (patch)
tree94e333d35b7d48d93bfb70f132023d6b8d3d5752 /src
parent3fe9767dd33499c2560d209dc13a01f5fcead1f0 (diff)
Allow plugins to define new settings.
Diffstat (limited to 'src')
-rw-r--r--src/libstore/globals.cc16
-rw-r--r--src/libstore/globals.hh7
-rw-r--r--src/libstore/store-api.cc2
-rw-r--r--src/libutil/config.cc42
-rw-r--r--src/libutil/config.hh8
5 files changed, 49 insertions, 26 deletions
diff --git a/src/libstore/globals.cc b/src/libstore/globals.cc
index c6b508cbe82f..c5a4536ef2f7 100644
--- a/src/libstore/globals.cc
+++ b/src/libstore/globals.cc
@@ -161,6 +161,22 @@ void initPlugins()
                 throw Error("could not dynamically open plugin file '%s%': %s%", file, dlerror());
         }
     }
+    /* We handle settings registrations here, since plugins can add settings */
+    if (RegisterSetting::settingRegistrations) {
+        for (auto & registration : *RegisterSetting::settingRegistrations)
+            settings.addSetting(registration);
+        delete RegisterSetting::settingRegistrations;
+    }
+    settings.handleUnknownSettings();
+}
+
+RegisterSetting::SettingRegistrations * RegisterSetting::settingRegistrations;
+
+RegisterSetting::RegisterSetting(AbstractSetting * s)
+{
+    if (!settingRegistrations)
+        settingRegistrations = new SettingRegistrations;
+    settingRegistrations->emplace_back(s);
 }
 
 
diff --git a/src/libstore/globals.hh b/src/libstore/globals.hh
index 508084d08acb..1d019aab9d23 100644
--- a/src/libstore/globals.hh
+++ b/src/libstore/globals.hh
@@ -383,5 +383,12 @@ void initPlugins();
 
 extern const string nixVersion;
 
+struct RegisterSetting
+{
+    typedef std::vector<AbstractSetting *> SettingRegistrations;
+    static SettingRegistrations * settingRegistrations;
+    RegisterSetting(AbstractSetting * s);
+};
+
 
 }
diff --git a/src/libstore/store-api.cc b/src/libstore/store-api.cc
index 4d43ef082d53..8830edcc3449 100644
--- a/src/libstore/store-api.cc
+++ b/src/libstore/store-api.cc
@@ -839,7 +839,7 @@ ref<Store> openStore(const std::string & uri_,
     for (auto fun : *RegisterStoreImplementation::implementations) {
         auto store = fun(uri, params);
         if (store) {
-            store->warnUnknownSettings();
+            store->handleUnknownSettings();
             return ref<Store>(store);
         }
     }
diff --git a/src/libutil/config.cc b/src/libutil/config.cc
index 0e502769edf8..cdd1e0a15aa6 100644
--- a/src/libutil/config.cc
+++ b/src/libutil/config.cc
@@ -7,10 +7,12 @@ namespace nix {
 void Config::set(const std::string & name, const std::string & value)
 {
     auto i = _settings.find(name);
-    if (i == _settings.end())
-        throw UsageError("unknown setting '%s'", name);
-    i->second.setting->set(value);
-    i->second.setting->overriden = true;
+    if (i == _settings.end()) {
+        extras.emplace(name, value);
+    } else {
+        i->second.setting->set(value);
+        i->second.setting->overriden = true;
+    }
 }
 
 void Config::addSetting(AbstractSetting * setting)
@@ -21,34 +23,37 @@ void Config::addSetting(AbstractSetting * setting)
 
     bool set = false;
 
-    auto i = initials.find(setting->name);
-    if (i != initials.end()) {
+    auto i = extras.find(setting->name);
+    if (i != extras.end()) {
         setting->set(i->second);
         setting->overriden = true;
-        initials.erase(i);
+        extras.erase(i);
         set = true;
     }
 
     for (auto & alias : setting->aliases) {
-        auto i = initials.find(alias);
-        if (i != initials.end()) {
+        auto i = extras.find(alias);
+        if (i != extras.end()) {
             if (set)
                 warn("setting '%s' is set, but it's an alias of '%s' which is also set",
                     alias, setting->name);
             else {
                 setting->set(i->second);
                 setting->overriden = true;
-                initials.erase(i);
+                extras.erase(i);
                 set = true;
             }
         }
     }
 }
 
-void Config::warnUnknownSettings()
+void Config::handleUnknownSettings(bool fatal)
 {
-    for (auto & i : initials)
-        warn("unknown setting '%s'", i.first);
+    for (auto & s : extras)
+        if (fatal)
+            throw UsageError("unknown setting '%s%'", s.first);
+        else
+            warn("unknown setting '%s'", s.first);
 }
 
 StringMap Config::getSettings(bool overridenOnly)
@@ -60,7 +65,7 @@ StringMap Config::getSettings(bool overridenOnly)
     return res;
 }
 
-void Config::applyConfigFile(const Path & path, bool fatal)
+void Config::applyConfigFile(const Path & path)
 {
     try {
         string contents = readFile(path);
@@ -97,7 +102,7 @@ void Config::applyConfigFile(const Path & path, bool fatal)
                     throw UsageError("illegal configuration line '%1%' in '%2%'", line, path);
                 auto p = absPath(tokens[1], dirOf(path));
                 if (pathExists(p)) {
-                    applyConfigFile(p, fatal);
+                    applyConfigFile(p);
                 } else if (!ignoreMissing) {
                     throw Error("file '%1%' included from '%2%' not found", p, path);
                 }
@@ -112,12 +117,7 @@ void Config::applyConfigFile(const Path & path, bool fatal)
             vector<string>::iterator i = tokens.begin();
             advance(i, 2);
 
-            try {
-                set(name, concatStringsSep(" ", Strings(i, tokens.end()))); // FIXME: slow
-            } catch (UsageError & e) {
-                if (fatal) throw;
-                warn("in configuration file '%s': %s", path, e.what());
-            }
+            set(name, concatStringsSep(" ", Strings(i, tokens.end()))); // FIXME: slow
         };
     } catch (SysError &) { }
 }
diff --git a/src/libutil/config.hh b/src/libutil/config.hh
index 9a32af528ec7..c6783e13c2b0 100644
--- a/src/libutil/config.hh
+++ b/src/libutil/config.hh
@@ -48,25 +48,25 @@ private:
 
     Settings _settings;
 
-    StringMap initials;
+    StringMap extras;
 
 public:
 
     Config(const StringMap & initials)
-        : initials(initials)
+        : extras(initials)
     { }
 
     void set(const std::string & name, const std::string & value);
 
     void addSetting(AbstractSetting * setting);
 
-    void warnUnknownSettings();
+    void handleUnknownSettings(bool fatal = false);
 
     StringMap getSettings(bool overridenOnly = false);
 
     const Settings & _getSettings() { return _settings; }
 
-    void applyConfigFile(const Path & path, bool fatal = false);
+    void applyConfigFile(const Path & path);
 
     void resetOverriden();