Skip to content

Commit 9ec6d6d

Browse files
cleverca22cidkidnix
andcommitted
fix: log all ifd
Co-authored-by: Dylan Green <[email protected]>
1 parent 916da45 commit 9ec6d6d

File tree

5 files changed

+58
-39
lines changed

5 files changed

+58
-39
lines changed

src/libexpr/eval.hh

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -593,7 +593,7 @@ public:
593593
* Realise the given context, and return a mapping from the placeholders
594594
* used to construct the associated value to their final store path
595595
*/
596-
[[nodiscard]] StringMap realiseContext(const NixStringContext & context);
596+
[[nodiscard]] StringMap realiseContext(const NixStringContext & context, const PosIdx pos, const std::string_view reason);
597597

598598
private:
599599

@@ -746,6 +746,9 @@ struct EvalSettings : Config
746746

747747
Setting<bool> traceVerbose{this, false, "trace-verbose",
748748
"Whether `builtins.traceVerbose` should trace its first argument when evaluated."};
749+
750+
Setting<bool> logImportFromDerivation{this, false, "log-import-from-derivation",
751+
"Emit log messages for all imports from derivations at the 'info' log level"};
749752
};
750753

751754
extern EvalSettings evalSettings;

src/libexpr/primops.cc

Lines changed: 42 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
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 {
3839
InvalidPathError::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. */
170186
static 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 */
333349
void 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. */
16011617
static 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

17191735
static 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 ..) */
17371753
static 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;

src/libutil/logging.hh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ typedef enum {
2323
actQueryPathInfo = 109,
2424
actPostBuildHook = 110,
2525
actBuildWaiting = 111,
26+
actFromDerivation = 112,
2627
} ActivityType;
2728

2829
typedef enum {

tests/import-from-derivation.nix

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
with import ./config.nix;
2+
import (
3+
mkDerivation {
4+
name = "foo";
5+
bla = import ./dependencies.nix;
6+
buildCommand = "
7+
echo \\\"hi\\\" > $out
8+
";
9+
}
10+
)

tests/remote-store.sh

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,7 @@ else
1919
fi
2020

2121
# Test import-from-derivation through the daemon.
22-
[[ $(nix eval --impure --raw --expr '
23-
with import ./config.nix;
24-
import (
25-
mkDerivation {
26-
name = "foo";
27-
bla = import ./dependencies.nix;
28-
buildCommand = "
29-
echo \\\"hi\\\" > $out
30-
";
31-
}
32-
)
33-
') = hi ]]
22+
[[ $(nix eval --option "log-import-from-derivation" true --impure --raw ./import-from-derivation.nix) = hi ]]
3423

3524
storeCleared=1 NIX_REMOTE_=$NIX_REMOTE $SHELL ./user-envs.sh
3625

0 commit comments

Comments
 (0)