* toFile: added an additional argument to specify the store path

suffix, e.g., `builtins.toFile "builder.sh" "..."'.
* toFile: handle references to other files correctly.
This commit is contained in:
Eelco Dolstra 2006-10-03 14:55:54 +00:00
parent 84e6c43e85
commit d20c3011a0
4 changed files with 41 additions and 5 deletions

View File

@ -2,6 +2,7 @@
#include "parser.hh" #include "parser.hh"
#include "hash.hh" #include "hash.hh"
#include "util.hh" #include "util.hh"
#include "store.hh"
#include "nixexpr-ast.hh" #include "nixexpr-ast.hh"
@ -256,7 +257,11 @@ string coerceToStringWithContext(EvalState & state,
if (matchPath(e, s)) { if (matchPath(e, s)) {
isPath = true; isPath = true;
return aterm2String(s); Path path = aterm2String(s);
if (isInStore(path)) {
context = ATinsert(context, makePath(toATerm(toStorePath(path))));
}
return path;
} }
if (matchAttrs(e, es)) { if (matchAttrs(e, es)) {

View File

@ -297,6 +297,7 @@ string showType(Expr e)
{ {
ATerm t1, t2, t3; ATerm t1, t2, t3;
ATermList l1; ATermList l1;
ATermBlob b1;
int i1; int i1;
if (matchStr(e, t1)) return "a string"; if (matchStr(e, t1)) return "a string";
if (matchPath(e, t1)) return "a path"; if (matchPath(e, t1)) return "a path";
@ -308,6 +309,7 @@ string showType(Expr e)
if (matchFunction1(e, t1, t2, t3)) return "a function"; if (matchFunction1(e, t1, t2, t3)) return "a function";
if (matchAttrs(e, l1)) return "an attribute set"; if (matchAttrs(e, l1)) return "an attribute set";
if (matchList(e, l1)) return "a list"; if (matchList(e, l1)) return "a list";
if (matchPrimOp(e, i1, b1, l1)) return "a partially applied built-in function";
if (matchContext(e, l1, t1)) return "a context containing " + showType(t1); if (matchContext(e, l1, t1)) return "a context containing " + showType(t1);
return "an unknown type"; return "an unknown type";
} }

View File

@ -512,12 +512,41 @@ static Expr primToXML(EvalState & state, const ATermVector & args)
} }
static Expr unwrapContext(EvalState & state, Expr e, ATermList & context)
{
context = ATempty;
e = evalExpr(state, e);
if (matchContext(e, context, e))
e = evalExpr(state, e);
return e;
}
/* Store a string in the Nix store as a source file that can be used /* Store a string in the Nix store as a source file that can be used
as an input by derivations. */ as an input by derivations. */
static Expr primToFile(EvalState & state, const ATermVector & args) static Expr primToFile(EvalState & state, const ATermVector & args)
{ {
string s = evalString(state, args[0]); ATermList context;
Path storePath = addTextToStore("", s, PathSet()); string name = evalString(state, args[0]);
string contents = evalString(state,
unwrapContext(state, args[1], context));
PathSet refs;
for (ATermIterator i(context); i; ++i) {
ATerm s;
if (matchPath(*i, s)) {
assert(isStorePath(aterm2String(s)));
refs.insert(aterm2String(s));
}
else throw EvalError("in `toFile': the file cannot contain references to derivation outputs");
}
Path storePath = addTextToStore(name, contents, refs);
/* Note: we don't need to wrap the result in a context, since
`storePath' itself has references to the paths used in
args[1]. */
return makePath(toATerm(storePath)); return makePath(toATerm(storePath));
} }
@ -842,7 +871,6 @@ void EvalState::addPrimOps()
addPrimOp("toString", 1, primToString); addPrimOp("toString", 1, primToString);
addPrimOp("__toPath", 1, primToPath); addPrimOp("__toPath", 1, primToPath);
addPrimOp("__toXML", 1, primToXML); addPrimOp("__toXML", 1, primToXML);
addPrimOp("__toFile", 1, primToFile);
addPrimOp("isNull", 1, primIsNull); addPrimOp("isNull", 1, primIsNull);
addPrimOp("__isList", 1, primIsList); addPrimOp("__isList", 1, primIsList);
addPrimOp("dependencyClosure", 1, primDependencyClosure); addPrimOp("dependencyClosure", 1, primDependencyClosure);
@ -858,6 +886,7 @@ void EvalState::addPrimOps()
addPrimOp("relativise", 2, primRelativise); addPrimOp("relativise", 2, primRelativise);
addPrimOp("__add", 2, primAdd); addPrimOp("__add", 2, primAdd);
addPrimOp("__lessThan", 2, primLessThan); addPrimOp("__lessThan", 2, primLessThan);
addPrimOp("__toFile", 2, primToFile);
} }

View File

@ -1,7 +1,7 @@
let { let {
# Test inline source file definitions. # Test inline source file definitions.
builder = builtins.toFile " builder = builtins.toFile "builder.sh" "
mkdir $out mkdir $out
cat > $out/program <<EOF cat > $out/program <<EOF