diff --git a/lix/legacy/nix-build.cc b/lix/legacy/nix-build.cc index 8b7f312b6..78d738a2a 100644 --- a/lix/legacy/nix-build.cc +++ b/lix/legacy/nix-build.cc @@ -254,10 +254,10 @@ static void main_nix_build(AsyncIoRoot & aio, std::string programName, Strings a /* If we're in a #! script, interpret filenames relative to the script. */ exprs.push_back(evaluator->parseExprFromFile( - evaluator->paths.resolveExprPath(lookupFileArg( + evaluator->paths.resolveExprPath(aio.blockOn(lookupFileArg( *evaluator, inShebang && !packages ? absPath(i, absPath(dirOf(script))) : i - )) + ))) )); } } diff --git a/lix/legacy/nix-env.cc b/lix/legacy/nix-env.cc index 3cbd98c78..7ac40fdce 100644 --- a/lix/legacy/nix-env.cc +++ b/lix/legacy/nix-env.cc @@ -1547,7 +1547,7 @@ static int main_nix_env(AsyncIoRoot & aio, std::string programName, Strings argv globals.instSource.nixExprPath = std::make_shared( file != "" - ? lookupFileArg(*globals.state, file) + ? aio.blockOn(lookupFileArg(*globals.state, file)) : CanonPath(nixExprPath)); globals.instSource.autoArgs = myArgs.getAutoArgs(*globals.state); diff --git a/lix/legacy/nix-instantiate.cc b/lix/legacy/nix-instantiate.cc index 9b46a946f..4ee457f0e 100644 --- a/lix/legacy/nix-instantiate.cc +++ b/lix/legacy/nix-instantiate.cc @@ -183,7 +183,9 @@ static int main_nix_instantiate(AsyncIoRoot & aio, std::string programName, Stri for (auto & i : files) { Expr & e = fromArgs ? evaluator->parseExprFromString(i, CanonPath::fromCwd()) - : evaluator->parseExprFromFile(evaluator->paths.resolveExprPath(lookupFileArg(*evaluator, i))); + : evaluator->parseExprFromFile( + evaluator->paths.resolveExprPath(aio.blockOn(lookupFileArg(*evaluator, i))) + ); processExpr(*state, attrPaths, parseOnly, strict, autoArgs, evalOnly, outputKind, xmlOutputSourceLocation, e); } diff --git a/lix/libcmd/common-eval-args.cc b/lix/libcmd/common-eval-args.cc index 0c53d7fd7..6d9c7d791 100644 --- a/lix/libcmd/common-eval-args.cc +++ b/lix/libcmd/common-eval-args.cc @@ -8,6 +8,7 @@ #include "lix/libexpr/flake/flakeref.hh" #include "lix/libstore/store-api.hh" #include "lix/libcmd/command.hh" +#include "lix/libutil/async.hh" #include @@ -187,8 +188,8 @@ Bindings * MixEvalArgs::getAutoArgs(Evaluator & state) return res.finish(); } -SourcePath lookupFileArg(Evaluator & state, std::string_view fileArg) -{ +kj::Promise> lookupFileArg(Evaluator & state, std::string_view fileArg) +try { if (EvalSettings::isPseudoUrl(fileArg)) { auto const url = EvalSettings::resolvePseudoUrl(fileArg); auto const downloaded = fetchers::downloadTarball( @@ -198,21 +199,22 @@ SourcePath lookupFileArg(Evaluator & state, std::string_view fileArg) /* locked */ false ); StorePath const storePath = downloaded.tree.storePath; - return CanonPath(state.store->toRealPath(storePath)); + co_return CanonPath(state.store->toRealPath(storePath)); } else if (fileArg.starts_with("flake:")) { experimentalFeatureSettings.require(Xp::Flakes); static constexpr size_t FLAKE_LEN = std::string_view("flake:").size(); auto flakeRef = parseFlakeRef(std::string(fileArg.substr(FLAKE_LEN)), {}, true, false); auto storePath = - RUN_ASYNC_IN_NEW_THREAD(flakeRef.resolve(state.store).fetchTree(state.store)) - .first.storePath; - return CanonPath(state.store->toRealPath(storePath)); + TRY_AWAIT(flakeRef.resolve(state.store).fetchTree(state.store)).first.storePath; + co_return CanonPath(state.store->toRealPath(storePath)); } else if (fileArg.size() > 2 && fileArg.at(0) == '<' && fileArg.at(fileArg.size() - 1) == '>') { Path p(fileArg.substr(1, fileArg.size() - 2)); - return RUN_ASYNC_IN_NEW_THREAD(state.paths.findFile(p)); + co_return TRY_AWAIT(state.paths.findFile(p)); } else { - return CanonPath::fromCwd(fileArg); + co_return CanonPath::fromCwd(fileArg); } +} catch (...) { + co_return result::current_exception(); } } diff --git a/lix/libcmd/common-eval-args.hh b/lix/libcmd/common-eval-args.hh index 1d42ee5e4..cb7781769 100644 --- a/lix/libcmd/common-eval-args.hh +++ b/lix/libcmd/common-eval-args.hh @@ -49,6 +49,6 @@ private: * * @exception nix::ThrownError for failed search path lookup. Probably others. */ -SourcePath lookupFileArg(Evaluator & state, std::string_view fileArg); +kj::Promise> lookupFileArg(Evaluator & state, std::string_view fileArg); } diff --git a/lix/libcmd/installables.cc b/lix/libcmd/installables.cc index 33fd3529e..5781eee21 100644 --- a/lix/libcmd/installables.cc +++ b/lix/libcmd/installables.cc @@ -217,7 +217,7 @@ void SourceExprCommand::completeInstallable(EvalState & state, AddCompletions & auto evaluator = getEvaluator(); Expr & e = evaluator->parseExprFromFile( - state.ctx.paths.resolveExprPath(lookupFileArg(*evaluator, *file)) + state.ctx.paths.resolveExprPath(state.aio.blockOn(lookupFileArg(*evaluator, *file))) ); Value root; @@ -454,7 +454,7 @@ Installables SourceExprCommand::parseInstallables( state.eval(e, *vFile); } else if (file) - state.evalFile(lookupFileArg(*evaluator, *file), *vFile); + state.evalFile(state.aio.blockOn(lookupFileArg(*evaluator, *file)), *vFile); else { auto & e = evaluator->parseExprFromString(*expr, CanonPath::fromCwd()); state.eval(e, *vFile); diff --git a/lix/libcmd/repl.cc b/lix/libcmd/repl.cc index 9acb7ef99..7799ef20c 100644 --- a/lix/libcmd/repl.cc +++ b/lix/libcmd/repl.cc @@ -895,7 +895,7 @@ void NixRepl::loadFile(const Path & path) loadedFiles.remove(path); loadedFiles.push_back(path); Value v, v2; - state.evalFile(lookupFileArg(evaluator, path), v); + state.evalFile(state.aio.blockOn(lookupFileArg(evaluator, path)), v); state.autoCallFunction(*autoArgs, v, v2); addAttrsToScope(v2); } diff --git a/lix/nix/prefetch.cc b/lix/nix/prefetch.cc index 7cf3b8897..832fdb9ab 100644 --- a/lix/nix/prefetch.cc +++ b/lix/nix/prefetch.cc @@ -203,7 +203,7 @@ static int main_nix_prefetch_url(AsyncIoRoot & aio, std::string programName, Str Value vRoot; state->evalFile( evaluator->paths.resolveExprPath( - lookupFileArg(*evaluator, args.empty() ? "." : args[0])), + aio.blockOn(lookupFileArg(*evaluator, args.empty() ? "." : args[0]))), vRoot); Value & v(*findAlongAttrPath(*state, attrPath, autoArgs, vRoot).first); state->forceAttrs(v, noPos, "while evaluating the source attribute to prefetch"); diff --git a/subprojects/nix-eval-jobs/src/worker.cc b/subprojects/nix-eval-jobs/src/worker.cc index a11696809..934119d7e 100644 --- a/subprojects/nix-eval-jobs/src/worker.cc +++ b/subprojects/nix-eval-jobs/src/worker.cc @@ -53,7 +53,7 @@ static nix::Value *releaseExprTopLevelValue(nix::EvalState &state, nix::CanonPath::fromCwd()); state.eval(e, vTop); } else { - state.evalFile(nix::lookupFileArg(state.ctx, args.releaseExpr), vTop); + state.evalFile(state.aio.blockOn(nix::lookupFileArg(state.ctx, args.releaseExpr)), vTop); } auto vRoot = state.ctx.mem.allocValue(); diff --git a/tests/unit/libcmd/args.cc b/tests/unit/libcmd/args.cc index baee3deff..ae2406af5 100644 --- a/tests/unit/libcmd/args.cc +++ b/tests/unit/libcmd/args.cc @@ -35,22 +35,25 @@ TEST(Arguments, lookupFileArg) { auto store = openStore("dummy://"); auto state = std::make_shared(aio, searchPath, store, store); - SourcePath const foundUnitData = lookupFileArg(*state, ""); + SourcePath const foundUnitData = aio.blockOn(lookupFileArg(*state, "")); EXPECT_EQ(foundUnitData.canonical(), canonDataPath); // lookupFileArg should not resolve if anything else is before or after it. - SourcePath const yepEvenSpaces = lookupFileArg(*state, " "); + SourcePath const yepEvenSpaces = aio.blockOn(lookupFileArg(*state, " ")); EXPECT_EQ(yepEvenSpaces.canonical(), CanonPath::fromCwd(" ")); - EXPECT_EQ(lookupFileArg(*state, "/nixos").canonical(), CanonPath::fromCwd("/nixos")); + EXPECT_EQ( + aio.blockOn(lookupFileArg(*state, "/nixos")).canonical(), + CanonPath::fromCwd("/nixos") + ); try { - lookupFileArg(*state, INVALID_CHANNEL); + aio.blockOn(lookupFileArg(*state, INVALID_CHANNEL)); } catch (FileTransferError const & ex) { std::string_view const msg(ex.what()); EXPECT_NE(msg.find(CHANNEL_URL), msg.npos); } - SourcePath const normalFile = lookupFileArg(*state, unitDataPath); + SourcePath const normalFile = aio.blockOn(lookupFileArg(*state, unitDataPath)); EXPECT_EQ(normalFile.canonical(), canonDataPath); }