1111#include " value-to-json.hh"
1212#include " value-to-xml.hh"
1313#include " primops.hh"
14+ #include " build-result.hh"
1415
1516#include < boost/container/small_vector.hpp>
1617#include < nlohmann/json.hpp>
@@ -38,9 +39,9 @@ namespace nix {
3839InvalidPathError::InvalidPathError (const Path & path) :
3940 EvalError (" path '%s' is not valid" , path), path(path) {}
4041
41- StringMap EvalState::realiseContext (const NixStringContext & context)
42+ StringMap EvalState::realiseContext (const NixStringContext & context, const PosIdx pos, const std::string_view reason )
4243{
43- std::vector<DerivedPath ::Built> drvs;
44+ std::vector<NixStringContextElem ::Built> drvs;
4445 StringMap res;
4546
4647 for (auto & c : context) {
@@ -50,10 +51,8 @@ StringMap EvalState::realiseContext(const NixStringContext & context)
5051 };
5152 std::visit (overloaded {
5253 [&](const NixStringContextElem::Built & b) {
53- drvs.push_back (DerivedPath::Built {
54- .drvPath = b.drvPath ,
55- .outputs = OutputsSpec::Names { b.output },
56- });
54+ auto ctxS = store->printStorePath (b.drvPath );
55+ drvs.push_back (b);
5756 ensureValid (b.drvPath );
5857 },
5958 [&](const NixStringContextElem::Opaque & o) {
@@ -77,18 +76,35 @@ StringMap EvalState::realiseContext(const NixStringContext & context)
7776 " cannot build '%1%' during evaluation because the option 'allow-import-from-derivation' is disabled" ,
7877 store->printStorePath (drvs.begin ()->drvPath )));
7978
79+ if (evalSettings.logImportFromDerivation ) {
80+ for (auto & drv : drvs) {
81+ Activity act{
82+ *logger, lvlInfo, actFromDerivation,
83+ fmt (" Derivation %s Output %s: importing from derivation %s via %s" ,
84+ store->printStorePath (drv.drvPath ), drv.output , positions[pos], reason),
85+ };
86+ }
87+ }
88+
8089 /* Build/substitute the context. */
8190 std::vector<DerivedPath> buildReqs;
82- for (auto & d : drvs) buildReqs.emplace_back (DerivedPath { d });
83- store->buildPaths (buildReqs);
91+ for (auto & d : drvs) buildReqs.emplace_back (DerivedPath {
92+ DerivedPath::Built {
93+ .drvPath = d.drvPath ,
94+ .outputs = OutputsSpec::Names { d.output },
95+ }
96+ });
97+ auto results = store->buildPathsWithResults (buildReqs);
8498
8599 /* Get all the output paths corresponding to the placeholders we had */
86- for (auto & drv : drvs) {
87- auto outputs = resolveDerivedPath (*store, drv);
88- for (auto & [outputName, outputPath] : outputs) {
100+ for (auto & result : results) {
101+ for (auto & [outputName, realisation] : result.builtOutputs ) {
89102 res.insert_or_assign (
90- downstreamPlaceholder (*store, drv.drvPath , outputName),
91- store->printStorePath (outputPath)
103+ downstreamPlaceholder (
104+ *store,
105+ std::get<DerivedPath::Built>(result.path ).drvPath ,
106+ outputName),
107+ store->printStorePath (realisation.outPath )
92108 );
93109 }
94110 }
@@ -109,14 +125,14 @@ struct RealisePathFlags {
109125 bool checkForPureEval = true ;
110126};
111127
112- static SourcePath realisePath (EvalState & state, const PosIdx pos, Value & v, const RealisePathFlags flags = {})
128+ static SourcePath realisePath (EvalState & state, const PosIdx pos, Value & v, const std::string_view reason, const RealisePathFlags flags = {})
113129{
114130 NixStringContext context;
115131
116- auto path = state.coerceToPath (noPos , v, context, " while realising the context of a path" );
132+ auto path = state.coerceToPath (pos , v, context, " while realising the context of a path" );
117133
118134 try {
119- StringMap rewrites = state.realiseContext (context);
135+ StringMap rewrites = state.realiseContext (context, pos, reason );
120136
121137 auto realPath = state.rootPath (CanonPath (state.toRealPath (rewriteStrings (path.path .abs (), rewrites), context)));
122138
@@ -169,7 +185,7 @@ static void mkOutputString(
169185 argument. */
170186static void import (EvalState & state, const PosIdx pos, Value & vPath, Value * vScope, Value & v)
171187{
172- auto path = realisePath (state, pos, vPath);
188+ auto path = realisePath (state, pos, vPath, " scopedImport " );
173189 auto path2 = path.path .abs ();
174190
175191 // FIXME
@@ -332,7 +348,7 @@ extern "C" typedef void (*ValueInitializer)(EvalState & state, Value & v);
332348/* Load a ValueInitializer from a DSO and return whatever it initializes */
333349void prim_importNative (EvalState & state, const PosIdx pos, Value * * args, Value & v)
334350{
335- auto path = realisePath (state, pos, *args[0 ]);
351+ auto path = realisePath (state, pos, *args[0 ], " importNative " );
336352
337353 std::string sym (state.forceStringNoCtx (*args[1 ], pos, " while evaluating the second argument passed to builtins.importNative" ));
338354
@@ -376,7 +392,7 @@ void prim_exec(EvalState & state, const PosIdx pos, Value * * args, Value & v)
376392 false , false ).toOwned ());
377393 }
378394 try {
379- auto _ = state.realiseContext (context); // FIXME: Handle CA derivations
395+ auto _ = state.realiseContext (context, pos, " exec " ); // FIXME: Handle CA derivations
380396 } catch (InvalidPathError & e) {
381397 state.error (" cannot execute '%1%', since path '%2%' is not valid" , program, e.path ).atPos (pos).debugThrow <EvalError>();
382398 }
@@ -1523,7 +1539,7 @@ static void prim_pathExists(EvalState & state, const PosIdx pos, Value * * args,
15231539 can’t just catch the exception here because we still want to
15241540 throw if something in the evaluation of `*args[0]` tries to
15251541 access an unauthorized path). */
1526- auto path = realisePath (state, pos, *args[0 ], { .checkForPureEval = false });
1542+ auto path = realisePath (state, pos, *args[0 ], " pathExists " , { .checkForPureEval = false });
15271543
15281544 try {
15291545 v.mkBool (state.checkSourcePath (path).pathExists ());
@@ -1600,7 +1616,7 @@ static RegisterPrimOp primop_dirOf({
16001616/* Return the contents of a file as a string. */
16011617static void prim_readFile (EvalState & state, const PosIdx pos, Value * * args, Value & v)
16021618{
1603- auto path = realisePath (state, pos, *args[0 ]);
1619+ auto path = realisePath (state, pos, *args[0 ], " readFile " );
16041620 auto s = path.readFile ();
16051621 if (s.find ((char ) 0 ) != std::string::npos)
16061622 state.debugThrowLastTrace (Error (" the contents of the file '%1%' cannot be represented as a Nix string" , path));
@@ -1657,7 +1673,7 @@ static void prim_findFile(EvalState & state, const PosIdx pos, Value * * args, V
16571673 false , false ).toOwned ();
16581674
16591675 try {
1660- auto rewrites = state.realiseContext (context);
1676+ auto rewrites = state.realiseContext (context, pos, " findFile " );
16611677 path = rewriteStrings (path, rewrites);
16621678 } catch (InvalidPathError & e) {
16631679 state.debugThrowLastTrace (EvalError ({
@@ -1691,7 +1707,7 @@ static void prim_hashFile(EvalState & state, const PosIdx pos, Value * * args, V
16911707 .errPos = state.positions [pos]
16921708 }));
16931709
1694- auto path = realisePath (state, pos, *args[1 ]);
1710+ auto path = realisePath (state, pos, *args[1 ], " hashFile " );
16951711
16961712 v.mkString (hashString (*ht, path.readFile ()).to_string (Base16, false ));
16971713}
@@ -1718,7 +1734,7 @@ static std::string_view fileTypeToString(InputAccessor::Type type)
17181734
17191735static void prim_readFileType (EvalState & state, const PosIdx pos, Value * * args, Value & v)
17201736{
1721- auto path = realisePath (state, pos, *args[0 ]);
1737+ auto path = realisePath (state, pos, *args[0 ], " readFileType " );
17221738 /* Retrieve the directory entry type and stringize it. */
17231739 v.mkString (fileTypeToString (path.lstat ().type ));
17241740}
@@ -1736,7 +1752,7 @@ static RegisterPrimOp primop_readFileType({
17361752/* Read a directory (without . or ..) */
17371753static void prim_readDir (EvalState & state, const PosIdx pos, Value * * args, Value & v)
17381754{
1739- auto path = realisePath (state, pos, *args[0 ]);
1755+ auto path = realisePath (state, pos, *args[0 ], " readDir " );
17401756
17411757 // Retrieve directory entries for all nodes in a directory.
17421758 // This is similar to `getFileType` but is optimized to reduce system calls
@@ -2082,7 +2098,7 @@ static void addPath(
20822098 try {
20832099 // FIXME: handle CA derivation outputs (where path needs to
20842100 // be rewritten to the actual output).
2085- auto rewrites = state.realiseContext (context);
2101+ auto rewrites = state.realiseContext (context, noPos, " addPath " );
20862102 path = state.toRealPath (rewriteStrings (path, rewrites), context);
20872103
20882104 StorePathSet refs;
0 commit comments