aboutsummaryrefslogtreecommitdiff
path: root/src/libstore/parsed-derivations.cc
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2018-09-28 14:31:16 +0200
committerEelco Dolstra <edolstra@gmail.com>2018-09-28 14:32:46 +0200
commit7ae7a38c9a7d0a5679e65c8213cd7b58dfdc1c52 (patch)
tree892fc56a42bc96e497a9bdc1ec4ad4278510e6f7 /src/libstore/parsed-derivations.cc
parent99d4bb2d4cd94e0234e8cfb12887db155d98ac50 (diff)
Move structured attrs handling into a separate class
This is primarily because Derivation::{can,will}BuildLocally() depends on attributes like preferLocalBuild and requiredSystemFeatures, but it can't handle them properly because it doesn't have access to the structured attributes.
Diffstat (limited to 'src/libstore/parsed-derivations.cc')
-rw-r--r--src/libstore/parsed-derivations.cc97
1 files changed, 97 insertions, 0 deletions
diff --git a/src/libstore/parsed-derivations.cc b/src/libstore/parsed-derivations.cc
new file mode 100644
index 000000000..0d7acf046
--- /dev/null
+++ b/src/libstore/parsed-derivations.cc
@@ -0,0 +1,97 @@
+#include "parsed-derivations.hh"
+
+namespace nix {
+
+ParsedDerivation::ParsedDerivation(const Path & drvPath, BasicDerivation & drv)
+ : drvPath(drvPath), drv(drv)
+{
+ /* Parse the __json attribute, if any. */
+ auto jsonAttr = drv.env.find("__json");
+ if (jsonAttr != drv.env.end()) {
+ try {
+ structuredAttrs = nlohmann::json::parse(jsonAttr->second);
+ } catch (std::exception & e) {
+ throw Error("cannot process __json attribute of '%s': %s", drvPath, e.what());
+ }
+ }
+}
+
+std::experimental::optional<std::string> ParsedDerivation::getStringAttr(const std::string & name) const
+{
+ if (structuredAttrs) {
+ auto i = structuredAttrs->find(name);
+ if (i == structuredAttrs->end())
+ return {};
+ else {
+ if (!i->is_string())
+ throw Error("attribute '%s' of derivation '%s' must be a string", name, drvPath);
+ return i->get<std::string>();
+ }
+ } else {
+ auto i = drv.env.find(name);
+ if (i == drv.env.end())
+ return {};
+ else
+ return i->second;
+ }
+}
+
+bool ParsedDerivation::getBoolAttr(const std::string & name, bool def) const
+{
+ if (structuredAttrs) {
+ auto i = structuredAttrs->find(name);
+ if (i == structuredAttrs->end())
+ return def;
+ else {
+ if (!i->is_boolean())
+ throw Error("attribute '%s' of derivation '%s' must be a Boolean", name, drvPath);
+ return i->get<bool>();
+ }
+ } else {
+ auto i = drv.env.find(name);
+ if (i == drv.env.end())
+ return def;
+ else
+ return i->second == "1";
+ }
+}
+
+std::experimental::optional<Strings> ParsedDerivation::getStringsAttr(const std::string & name) const
+{
+ if (structuredAttrs) {
+ auto i = structuredAttrs->find(name);
+ if (i == structuredAttrs->end())
+ return {};
+ else {
+ if (!i->is_array())
+ throw Error("attribute '%s' of derivation '%s' must be a list of strings", name, drvPath);
+ Strings res;
+ for (auto j = i->begin(); j != i->end(); ++j) {
+ if (!j->is_string())
+ throw Error("attribute '%s' of derivation '%s' must be a list of strings", name, drvPath);
+ res.push_back(j->get<std::string>());
+ }
+ return res;
+ }
+ } else {
+ auto i = drv.env.find(name);
+ if (i == drv.env.end())
+ return {};
+ else
+ return tokenizeString<Strings>(i->second);
+ }
+}
+
+bool ParsedDerivation::canBuildLocally() const
+{
+ return drv.platform == settings.thisSystem
+ || settings.extraPlatforms.get().count(drv.platform) > 0
+ || drv.isBuiltin();
+}
+
+bool ParsedDerivation::willBuildLocally() const
+{
+ return getBoolAttr("preferLocalBuild") && canBuildLocally();
+}
+
+}