Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion src/libexpr/eval.hh
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ public:
/* Realise the given context, and return a mapping from the placeholders
* used to construct the associated value to their final store path
*/
[[nodiscard]] StringMap realiseContext(const PathSet & context);
[[nodiscard]] StringMap realiseContext(const PathSet & context, const Pos &pos, const string & reason);

private:

Expand Down Expand Up @@ -496,6 +496,9 @@ struct EvalSettings : Config

Setting<bool> useEvalCache{this, true, "eval-cache",
"Whether to use the flake evaluation cache."};

Setting<bool> logImportFromDerivation{this, false, "log-import-from-derivation",
"Emit log messages for all imports from derivations at the `info` log level"};
};

extern EvalSettings evalSettings;
Expand Down
27 changes: 15 additions & 12 deletions src/libexpr/primops.cc
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ namespace nix {
InvalidPathError::InvalidPathError(const Path & path) :
EvalError("path '%s' is not valid", path), path(path) {}

StringMap EvalState::realiseContext(const PathSet & context)
StringMap EvalState::realiseContext(const PathSet & context, const Pos & pos, std::string_view reason)
{
std::vector<DerivedPath::Built> drvs;
StringMap res;
Expand All @@ -49,6 +49,9 @@ StringMap EvalState::realiseContext(const PathSet & context)
throw InvalidPathError(store->printStorePath(ctx));
if (!outputName.empty() && ctx.isDerivation()) {
drvs.push_back({ctx, {outputName}});
if (evalSettings.logAllIFD) {
printInfo("'import from derivation of '%s' by '%s' at %s", ctxS, reason, pos);
}
} else {
res.insert_or_assign(ctxS, ctxS);
}
Expand Down Expand Up @@ -96,7 +99,7 @@ struct RealisePathFlags {
bool checkForPureEval = true;
};

static Path realisePath(EvalState & state, const Pos & pos, Value & v, const RealisePathFlags flags = {})
static Path realisePath(EvalState & state, const Pos & pos, Value & v, std::string_view reason, const RealisePathFlags flags = {})
{
PathSet context;

Expand All @@ -111,7 +114,7 @@ static Path realisePath(EvalState & state, const Pos & pos, Value & v, const Rea
}();

try {
StringMap rewrites = state.realiseContext(context);
StringMap rewrites = state.realiseContext(context, pos, reason);

auto realPath = state.toRealPath(rewriteStrings(path, rewrites), context);

Expand Down Expand Up @@ -159,7 +162,7 @@ static void mkOutputString(
argument. */
static void import(EvalState & state, const Pos & pos, Value & vPath, Value * vScope, Value & v)
{
auto path = realisePath(state, pos, vPath);
auto path = realisePath(state, pos, vPath, "scopedImport");

// FIXME
auto isValidDerivationInStore = [&]() -> std::optional<StorePath> {
Expand Down Expand Up @@ -312,7 +315,7 @@ extern "C" typedef void (*ValueInitializer)(EvalState & state, Value & v);
/* Load a ValueInitializer from a DSO and return whatever it initializes */
void prim_importNative(EvalState & state, const Pos & pos, Value * * args, Value & v)
{
auto path = realisePath(state, pos, *args[0]);
auto path = realisePath(state, pos, *args[0], "importNative");

string sym(state.forceStringNoCtx(*args[1], pos));

Expand Down Expand Up @@ -356,7 +359,7 @@ void prim_exec(EvalState & state, const Pos & pos, Value * * args, Value & v)
commandArgs.push_back(state.coerceToString(pos, *elems[i], context, false, false).toOwned());
}
try {
auto _ = state.realiseContext(context); // FIXME: Handle CA derivations
auto _ = state.realiseContext(context, pos, "exec"); // FIXME: Handle CA derivations
} catch (InvalidPathError & e) {
throw EvalError({
.msg = hintfmt("cannot execute '%1%', since path '%2%' is not valid",
Expand Down Expand Up @@ -1372,7 +1375,7 @@ static void prim_pathExists(EvalState & state, const Pos & pos, Value * * args,
can’t just catch the exception here because we still want to
throw if something in the evaluation of `*args[0]` tries to
access an unauthorized path). */
auto path = realisePath(state, pos, *args[0], { .checkForPureEval = false });
auto path = realisePath(state, pos, *args[0], "pathExists", { .checkForPureEval = false });

try {
v.mkBool(pathExists(state.checkSourcePath(path)));
Expand Down Expand Up @@ -1439,7 +1442,7 @@ static RegisterPrimOp primop_dirOf({
/* Return the contents of a file as a string. */
static void prim_readFile(EvalState & state, const Pos & pos, Value * * args, Value & v)
{
auto path = realisePath(state, pos, *args[0]);
auto path = realisePath(state, pos, *args[0], "readFile");
string s = readFile(path);
if (s.find((char) 0) != string::npos)
throw Error("the contents of the file '%1%' cannot be represented as a Nix string", path);
Expand Down Expand Up @@ -1491,7 +1494,7 @@ static void prim_findFile(EvalState & state, const Pos & pos, Value * * args, Va
string path = state.coerceToString(pos, *i->value, context, false, false).toOwned();

try {
auto rewrites = state.realiseContext(context);
auto rewrites = state.realiseContext(context, pos, "findFile");
path = rewriteStrings(path, rewrites);
} catch (InvalidPathError & e) {
throw EvalError({
Expand Down Expand Up @@ -1526,7 +1529,7 @@ static void prim_hashFile(EvalState & state, const Pos & pos, Value * * args, Va
.errPos = pos
});

auto path = realisePath(state, pos, *args[1]);
auto path = realisePath(state, pos, *args[1], "hashFile");

v.mkString(hashFile(*ht, path).to_string(Base16, false));
}
Expand All @@ -1545,7 +1548,7 @@ static RegisterPrimOp primop_hashFile({
/* Read a directory (without . or ..) */
static void prim_readDir(EvalState & state, const Pos & pos, Value * * args, Value & v)
{
auto path = realisePath(state, pos, *args[0]);
auto path = realisePath(state, pos, *args[0], "readDir");

DirEntries entries = readDirectory(path);

Expand Down Expand Up @@ -1874,7 +1877,7 @@ static void addPath(
try {
// FIXME: handle CA derivation outputs (where path needs to
// be rewritten to the actual output).
auto rewrites = state.realiseContext(context);
auto rewrites = state.realiseContext(context, noPos, "addPath");
path = state.toRealPath(rewriteStrings(path, rewrites), context);

StorePathSet refs;
Expand Down