about summary refs log tree commit diff
path: root/src/libexpr/primops.cc
diff options
context:
space:
mode:
authorEelco Dolstra <eelco.dolstra@logicblox.com>2016-04-14T13·32+0200
committerEelco Dolstra <eelco.dolstra@logicblox.com>2016-04-14T13·32+0200
commit363f37d0843d87e03bd4dcb600ce04e7be60d7e1 (patch)
tree006704025fa074f412c530938dd804080fc3ba3b /src/libexpr/primops.cc
parentfc6a03298989383aa6d4562b51820d45a0f728eb (diff)
Make the search path lazier with non-fatal errors
Thus, -I / $NIX_PATH entries are now downloaded only when they are
needed for evaluation. An error to download an entry is a non-fatal
warning (just like non-existant paths).

This does change the semantics of builtins.nixPath, which now returns
the original, rather than resulting path. E.g., before we had

  [ { path = "/nix/store/hgm3yxf1lrrwa3z14zpqaj5p9vs0qklk-nixexprs.tar.xz"; prefix = "nixpkgs"; } ... ]

but now

  [ { path = "https://nixos.org/channels/nixos-16.03/nixexprs.tar.xz"; prefix = "nixpkgs"; } ... ]

Fixes #792.
Diffstat (limited to 'src/libexpr/primops.cc')
-rw-r--r--src/libexpr/primops.cc23
1 files changed, 12 insertions, 11 deletions
diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc
index 816827d6ab..51680ad62e 100644
--- a/src/libexpr/primops.cc
+++ b/src/libexpr/primops.cc
@@ -778,7 +778,6 @@ static void prim_findFile(EvalState & state, const Pos & pos, Value * * args, Va
 
     SearchPath searchPath;
 
-    PathSet context;
     for (unsigned int n = 0; n < args[0]->listSize(); ++n) {
         Value & v2(*args[0]->listElems()[n]);
         state.forceAttrs(v2, pos);
@@ -791,21 +790,23 @@ static void prim_findFile(EvalState & state, const Pos & pos, Value * * args, Va
         i = v2.attrs->find(state.symbols.create("path"));
         if (i == v2.attrs->end())
             throw EvalError(format("attribute ‘path’ missing, at %1%") % pos);
-        string path = state.coerceToPath(pos, *i->value, context);
 
-        searchPath.push_back(std::pair<string, Path>(prefix, state.checkSourcePath(path)));
-    }
+        PathSet context;
+        string path = state.coerceToString(pos, *i->value, context, false, false);
 
-    string path = state.forceStringNoCtx(*args[1], pos);
+        try {
+            state.realiseContext(context);
+        } catch (InvalidPathError & e) {
+            throw EvalError(format("cannot find ‘%1%’, since path ‘%2%’ is not valid, at %3%")
+                % path % e.path % pos);
+        }
 
-    try {
-        state.realiseContext(context);
-    } catch (InvalidPathError & e) {
-        throw EvalError(format("cannot find ‘%1%’, since path ‘%2%’ is not valid, at %3%")
-            % path % e.path % pos);
+        searchPath.emplace_back(prefix, path);
     }
 
-    mkPath(v, state.findFile(searchPath, path, pos).c_str());
+    string path = state.forceStringNoCtx(*args[1], pos);
+
+    mkPath(v, state.checkSourcePath(state.findFile(searchPath, path, pos)).c_str());
 }
 
 /* Read a directory (without . or ..) */