* 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:
parent
84e6c43e85
commit
d20c3011a0
|
@ -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)) {
|
||||||
|
|
|
@ -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";
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue