diff options
Diffstat (limited to 'src/libexpr')
-rw-r--r-- | src/libexpr/nixexpr.hh | 1 | ||||
-rw-r--r-- | src/libexpr/primops.cc | 62 |
2 files changed, 45 insertions, 18 deletions
diff --git a/src/libexpr/nixexpr.hh b/src/libexpr/nixexpr.hh index 3df9dd47f0bb..b8d0929285fe 100644 --- a/src/libexpr/nixexpr.hh +++ b/src/libexpr/nixexpr.hh @@ -16,6 +16,7 @@ MakeError(ThrownError, AssertionError) MakeError(Abort, EvalError) MakeError(TypeError, EvalError) MakeError(ImportError, EvalError) // error building an imported derivation +MakeError(FindError, EvalError) // error building a nix-path component MakeError(UndefinedVarError, Error) diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index f270ca302f45..fecaf37b6ed3 100644 --- a/src/libexpr/primops.cc +++ b/src/libexpr/primops.cc @@ -37,36 +37,52 @@ std::pair<string, string> decodeContext(const string & s) } -/* Load and evaluate an expression from path specified by the - argument. */ -static void prim_scopedImport(EvalState & state, const Pos & pos, Value * * args, Value & v) +struct InvalidPathError : EvalError { - PathSet context; - Path path = state.coerceToPath(pos, *args[1], context); + Path path; + InvalidPathError(const Path & path) : + EvalError(format("path `%1%' is not valid") % path), path(path) {}; +}; + +static void realiseContext(const PathSet & context) +{ PathSet drvs; for (auto & i : context) { std::pair<string, string> decoded = decodeContext(i); Path ctx = decoded.first; assert(isStorePath(ctx)); if (!store->isValidPath(ctx)) - throw EvalError(format("cannot import `%1%', since path `%2%' is not valid, at %3%") - % path % ctx % pos); + throw InvalidPathError(ctx); if (isDerivation(ctx)) drvs.insert(decoded.first + "!" + decoded.second); } if (!drvs.empty()) { - try { - /* For performance, prefetch all substitute info. */ - PathSet willBuild, willSubstitute, unknown; - unsigned long long downloadSize, narSize; - queryMissing(*store, drvs, - willBuild, willSubstitute, unknown, downloadSize, narSize); + /* For performance, prefetch all substitute info. */ + PathSet willBuild, willSubstitute, unknown; + unsigned long long downloadSize, narSize; + queryMissing(*store, drvs, + willBuild, willSubstitute, unknown, downloadSize, narSize); - store->buildPaths(drvs); - } catch (Error & e) { - throw ImportError(e.msg()); - } + store->buildPaths(drvs); + } +} + + +/* Load and evaluate an expression from path specified by the + argument. */ +static void prim_scopedImport(EvalState & state, const Pos & pos, Value * * args, Value & v) +{ + PathSet context; + Path path = state.coerceToPath(pos, *args[1], context); + + try { + realiseContext(context); + } catch (InvalidPathError & e) { + throw EvalError(format("cannot import `%1%', since path `%2%' is not valid, at %3%") + % path % e.path % pos); + } catch (Error & e) { + throw ImportError(e.msg()); } if (isStorePath(path) && store->isValidPath(path) && isDerivation(path)) { @@ -660,6 +676,7 @@ static void prim_findFile(EvalState & state, const Pos & pos, Value * * args, Va SearchPath searchPath; + PathSet context; for (unsigned int n = 0; n < args[0]->list.length; ++n) { Value & v2(*args[0]->list.elems[n]); state.forceAttrs(v2, pos); @@ -672,13 +689,22 @@ 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); - PathSet context; string path = state.coerceToPath(pos, *i->value, context); searchPath.push_back(std::pair<string, Path>(prefix, path)); } string path = state.forceStringNoCtx(*args[1], pos); + + try { + realiseContext(context); + } catch (InvalidPathError & e) { + throw EvalError(format("cannot find `%1%', since path `%2%' is not valid, at %3%") + % path % e.path % pos); + } catch (Error & e) { + throw FindError(e.msg()); + } + mkPath(v, state.findFile(searchPath, path).c_str()); } |