about summary refs log tree commit diff
path: root/src/libstore/derivations.cc
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2005-01-19T16·39+0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2005-01-19T16·39+0000
commit96de272b48f8e9bdabffddb699ed4f2292d4f1d7 (patch)
tree6121797dd02605b2f01e2c28de0bef54e7446e8b /src/libstore/derivations.cc
parentef5f254a55a2d6db09d3d0549ed45701558027e0 (diff)
* Renamed `normalise.cc' -> `build.cc', `storeexprs.cc' ->
  `derivations.cc', etc.
* Store the SHA-256 content hash of store paths in the database after
  they have been built/added.  This is so that we can check whether
  the store has been messed with (a la `rpm --verify').
* When registering path validity, verify that the closure property
  holds.

Diffstat (limited to 'src/libstore/derivations.cc')
-rw-r--r--src/libstore/derivations.cc142
1 files changed, 142 insertions, 0 deletions
diff --git a/src/libstore/derivations.cc b/src/libstore/derivations.cc
new file mode 100644
index 0000000000..2f37c66fb6
--- /dev/null
+++ b/src/libstore/derivations.cc
@@ -0,0 +1,142 @@
+#include "derivations.hh"
+#include "globals.hh"
+#include "store.hh"
+
+#include "derivations-ast.hh"
+#include "derivations-ast.cc"
+
+
+Hash hashTerm(ATerm t)
+{
+    return hashString(htSHA256, atPrint(t));
+}
+
+
+Path writeDerivation(const Derivation & drv, const string & name)
+{
+    return addTextToStore(name + drvExtension,
+        atPrint(unparseDerivation(drv)));
+}
+
+
+static void checkPath(const string & s)
+{
+    if (s.size() == 0 || s[0] != '/')
+        throw Error(format("bad path `%1%' in store expression") % s);
+}
+    
+
+static void parsePaths(ATermList paths, PathSet & out)
+{
+    for (ATermIterator i(paths); i; ++i) {
+        if (ATgetType(*i) != AT_APPL)
+            throw badTerm("not a path", *i);
+        string s = aterm2String(*i);
+        checkPath(s);
+        out.insert(s);
+    }
+}
+
+
+void throwBadDrv(ATerm t)
+{
+    throw badTerm("not a valid derivation", t);
+}
+
+
+Derivation parseDerivation(ATerm t)
+{
+    Derivation drv;
+    ATermList outs, inDrvs, inSrcs, args, bnds;
+    ATerm builder, platform;
+
+    if (!matchDerive(t, outs, inDrvs, inSrcs, platform, builder, args, bnds))
+        throwBadDrv(t);
+
+    for (ATermIterator i(outs); i; ++i) {
+        ATerm id, path, hashAlgo, hash;
+        if (!matchDerivationOutput(*i, id, path, hashAlgo, hash))
+            throwBadDrv(t);
+        DerivationOutput out;
+        out.path = aterm2String(path);
+        checkPath(out.path);
+        out.hashAlgo = aterm2String(hashAlgo);
+        out.hash = aterm2String(hash);
+        drv.outputs[aterm2String(id)] = out;
+    }
+
+    parsePaths(inDrvs, drv.inputDrvs);
+    parsePaths(inSrcs, drv.inputSrcs);
+
+    drv.builder = aterm2String(builder);
+    drv.platform = aterm2String(platform);
+    
+    for (ATermIterator i(args); i; ++i) {
+        if (ATgetType(*i) != AT_APPL)
+            throw badTerm("string expected", *i);
+        drv.args.push_back(aterm2String(*i));
+    }
+
+    for (ATermIterator i(bnds); i; ++i) {
+        ATerm s1, s2;
+        if (!matchEnvBinding(*i, s1, s2))
+            throw badTerm("tuple of strings expected", *i);
+        drv.env[aterm2String(s1)] = aterm2String(s2);
+    }
+
+    return drv;
+}
+
+
+static ATermList unparsePaths(const PathSet & paths)
+{
+    ATermList l = ATempty;
+    for (PathSet::const_iterator i = paths.begin();
+         i != paths.end(); i++)
+        l = ATinsert(l, toATerm(*i));
+    return ATreverse(l);
+}
+
+
+ATerm unparseDerivation(const Derivation & drv)
+{
+    ATermList outputs = ATempty;
+    for (DerivationOutputs::const_iterator i = drv.outputs.begin();
+         i != drv.outputs.end(); i++)
+        outputs = ATinsert(outputs,
+            makeDerivationOutput(
+                toATerm(i->first),
+                toATerm(i->second.path),
+                toATerm(i->second.hashAlgo),
+                toATerm(i->second.hash)));
+
+    ATermList args = ATempty;
+    for (Strings::const_iterator i = drv.args.begin();
+         i != drv.args.end(); i++)
+        args = ATinsert(args, toATerm(*i));
+
+    ATermList env = ATempty;
+    for (StringPairs::const_iterator i = drv.env.begin();
+         i != drv.env.end(); i++)
+        env = ATinsert(env,
+            makeEnvBinding(
+                toATerm(i->first),
+                toATerm(i->second)));
+
+    return makeDerive(
+        ATreverse(outputs),
+        unparsePaths(drv.inputDrvs),
+        unparsePaths(drv.inputSrcs),
+        toATerm(drv.platform),
+        toATerm(drv.builder),
+        ATreverse(args),
+        ATreverse(env));
+}
+
+
+bool isDerivation(const string & fileName)
+{
+    return
+        fileName.size() >= drvExtension.size() &&
+        string(fileName, fileName.size() - drvExtension.size()) == drvExtension;
+}