From e255be6cbef4b02185fb09218aab3daf59bcfa4c Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 14 May 2024 17:31:06 +0200 Subject: [PATCH] builtins.toPath: Rewrite virtual paths --- src/libexpr/eval.hh | 5 ++++- src/libexpr/paths.cc | 4 ++-- src/libexpr/primops.cc | 10 +++++++++- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh index d853cbc4592..62fad7d8d83 100644 --- a/src/libexpr/eval.hh +++ b/src/libexpr/eval.hh @@ -372,7 +372,10 @@ public: materializing those store paths. This is a backward compatibility hack to make buggy derivation attributes like `tostring ./bla` produce the same evaluation result. */ - std::string rewriteVirtualPaths(std::string_view s, PosIdx pos); + std::string rewriteVirtualPaths( + std::string_view s, + std::string_view warning, + PosIdx pos); /* Replace all virtual paths (i.e. `/nix/store/lazylazy...`) in a string by a pretty-printed rendition of the corresponding input diff --git a/src/libexpr/paths.cc b/src/libexpr/paths.cc index b3b9aa1d03b..7a9003a5365 100644 --- a/src/libexpr/paths.cc +++ b/src/libexpr/paths.cc @@ -91,7 +91,7 @@ std::string EvalState::prettyPrintPaths(std::string_view s) } } -std::string EvalState::rewriteVirtualPaths(std::string_view s, PosIdx pos) +std::string EvalState::rewriteVirtualPaths(std::string_view s, std::string_view warning, PosIdx pos) { std::string res; @@ -120,7 +120,7 @@ std::string EvalState::rewriteVirtualPaths(std::string_view s, PosIdx pos) assert(accessor != sourceAccessors.end()); // FIXME warn( - "derivation at %s has an attribute that refers to source tree '%s' without context; this does not work correctly", + std::string(warning), // FIXME: should accept a string_view positions[pos], accessor->second->showPath(CanonPath::root)); // FIXME: cache this. diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index 9c734c013d7..767da61497e 100644 --- a/src/libexpr/primops.cc +++ b/src/libexpr/primops.cc @@ -1352,7 +1352,10 @@ static void derivationStrictInternal( don't have a context, so aren't accessible from a sandbox) but we don't want to change evaluation results. */ for (auto & [name, value] : drv.env) - value = state.rewriteVirtualPaths(value, pos); + value = state.rewriteVirtualPaths( + value, + "derivation at %s has an attribute that refers to source tree '%s' without context; this does not work correctly", + pos); /* Do we have all required attributes? */ if (drv.builder == "") @@ -2170,6 +2173,11 @@ static void prim_toFile(EvalState & state, const PosIdx pos, Value * * args, Val std::string name(state.forceStringNoCtx(*args[0], pos, "while evaluating the first argument passed to builtins.toFile")); std::string contents(state.forceString(*args[1], context, pos, "while evaluating the second argument passed to builtins.toFile")); + contents = state.rewriteVirtualPaths( + contents, + "call to `builtins.toFile` at %s refers to source tree '%s' without context; this does not work correctly", + pos); + StorePathSet refs; for (auto c : context) {