about summary refs log tree commit diff
path: root/src/libexpr/primops.cc
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2008-11-19T23·26+0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2008-11-19T23·26+0000
commitaab530e9712baf802bcb48f03440a915dbc37ee9 (patch)
tree0a9d25b811dc91caabe2545c3e38c7ca0cc85bda /src/libexpr/primops.cc
parent60564410ef34db8fd3c9be759bdc687366f24e8e (diff)
* Primop builtins.storePath for declaring a store path as a
  dependency.  `storePath /nix/store/bla' gives exactly the same
  result as `toPath /nix/store/bla', except that the former includes
  /nix/store/bla in the dependency context of the string.

  Useful in some generated Nix expressions like nix-push, which now
  finally does the right thing wrt distributed builds.  (Previously
  the path to be packed wasn't an explicit dependency, so it wouldn't
  be copied to the remote machine.)

Diffstat (limited to 'src/libexpr/primops.cc')
-rw-r--r--src/libexpr/primops.cc22
1 files changed, 22 insertions, 0 deletions
diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc
index 50a6416700..4b7702effc 100644
--- a/src/libexpr/primops.cc
+++ b/src/libexpr/primops.cc
@@ -482,6 +482,27 @@ static Expr prim_toPath(EvalState & state, const ATermVector & args)
 }
 
 
+/* Allow a valid store path to be used in an expression.  This is
+   useful in some generated expressions such as in nix-push, which
+   generates a call to a function with an already existing store path
+   as argument.  You don't want to use `toPath' here because it copies
+   the path to the Nix store, which yields a copy like
+   /nix/store/newhash-oldhash-oldname.  In the past, `toPath' had
+   special case behaviour for store paths, but that created weird
+   corner cases. */
+static Expr prim_storePath(EvalState & state, const ATermVector & args)
+{
+    PathSet context;
+    Path path = canonPath(coerceToPath(state, args[0], context));
+    if (!isInStore(path))
+        throw EvalError(format("path `%1%' is not in the Nix store") % path);
+    if (!store->isValidPath(path))
+        throw EvalError(format("store path `%1%' is not valid") % path);
+    context.insert(toStorePath(path));
+    return makeStr(path, context);
+}
+
+
 static Expr prim_pathExists(EvalState & state, const ATermVector & args)
 {
     PathSet context;
@@ -950,6 +971,7 @@ void EvalState::addPrimOps()
 
     // Paths
     addPrimOp("__toPath", 1, prim_toPath);
+    addPrimOp("__storePath", 1, prim_storePath);
     addPrimOp("__pathExists", 1, prim_pathExists);
     addPrimOp("baseNameOf", 1, prim_baseNameOf);
     addPrimOp("dirOf", 1, prim_dirOf);