diff options
author | Eelco Dolstra <e.dolstra@tudelft.nl> | 2005-01-19T16·39+0000 |
---|---|---|
committer | Eelco Dolstra <e.dolstra@tudelft.nl> | 2005-01-19T16·39+0000 |
commit | 96de272b48f8e9bdabffddb699ed4f2292d4f1d7 (patch) | |
tree | 6121797dd02605b2f01e2c28de0bef54e7446e8b /src/libstore/derivations.cc | |
parent | ef5f254a55a2d6db09d3d0549ed45701558027e0 (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.cc | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/src/libstore/derivations.cc b/src/libstore/derivations.cc new file mode 100644 index 000000000000..2f37c66fb60d --- /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; +} |