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
22 changes: 10 additions & 12 deletions src/libcmd/built-path.cc
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "nix/cmd/built-path.hh"
#include "nix/store/derivations.hh"
#include "nix/store/store-api.hh"
#include "nix/store/outputs-query.hh"
#include "nix/util/comparator.hh"

#include <nlohmann/json.hpp>
Expand Down Expand Up @@ -109,18 +110,15 @@ RealisedPath::Set BuiltPath::toRealisedPaths(Store & store) const
[&](const BuiltPath::Opaque & p) { res.insert(p.path); },
[&](const BuiltPath::Built & p) {
for (auto & [outputName, outputPath] : p.outputs) {
if (experimentalFeatureSettings.isEnabled(Xp::CaDerivations)) {
DrvOutput key{
.drvPath = p.drvPath->outPath(),
.outputName = outputName,
};
auto thisRealisation = store.queryRealisation(key);
// We’ve built it, so we must have the realisation.
assert(thisRealisation);
res.insert(Realisation{*thisRealisation, key});
} else {
res.insert(outputPath);
}
/* Use a custom callback to collect realisations as they're queried. */
deepQueryPartialDerivationOutput(
store, p.drvPath->outPath(), outputName, nullptr, [&](const DrvOutput & drvOutput) {
auto realisation = store.queryRealisation(drvOutput);
if (realisation)
res.insert(Realisation{*realisation, drvOutput});
return realisation;
});
res.insert(outputPath);
}
},
},
Expand Down
3 changes: 2 additions & 1 deletion src/libcmd/repl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "nix/cmd/get-build-log.hh"
#include "nix/expr/get-drvs.hh"
#include "nix/store/derivations.hh"
#include "nix/store/outputs-query.hh"
#include "nix/store/globals.hh"
#include "nix/flake/flake.hh"
#include "nix/flake/lockfile.hh"
Expand Down Expand Up @@ -548,7 +549,7 @@ ProcessLineResult NixRepl::processLine(std::string line)
});
auto drv = state->store->readDerivation(drvPath);
logger->cout("\nThis derivation produced the following outputs:");
for (auto & [outputName, outputPath] : state->store->queryDerivationOutputMap(drvPath)) {
for (auto & [outputName, outputPath] : deepQueryDerivationOutputMap(*state->store, drvPath)) {
auto localStore = state->store.dynamic_pointer_cast<LocalFSStore>();
if (localStore && command == ":bl") {
std::string symlink = "repl-result-" + outputName;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
{
"buildTrace": {
"11yvkl84ashq63ilwc2mi4va41z2disw-root-drv.drv": {
"am42vl3rp8w29f5hyp9ljckxll50icpl-root-drv.drv": {
"out": {
"outPath": "px7apdw6ydm9ynjy5g0bpdcylw3xz2kj-root-drv-out",
"signatures": []
}
},
"vy7j6m6p5y0327fhk3zxn12hbpzkh6lp-dep-drv.drv": {
"out": {
"outPath": "w0yjpwh59kpbyc7hz9jgmi44r9br908i-dep-drv-out",
"signatures": []
}
}
},
"config": {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"buildTrace": {
"11yvkl84ashq63ilwc2mi4va41z2disw-root-drv.drv": {
"am42vl3rp8w29f5hyp9ljckxll50icpl-root-drv.drv": {
"out": {
"outPath": "px7apdw6ydm9ynjy5g0bpdcylw3xz2kj-root-drv-out",
"signatures": []
Expand Down Expand Up @@ -62,5 +62,26 @@
}
}
},
"derivations": {}
"derivations": {
"am42vl3rp8w29f5hyp9ljckxll50icpl-root-drv.drv": {
"args": [],
"builder": "",
"env": {},
"inputs": {
"drvs": {},
"srcs": [
"w0yjpwh59kpbyc7hz9jgmi44r9br908i-dep-drv-out"
]
},
"name": "root-drv",
"outputs": {
"out": {
"hashAlgo": "sha256",
"method": "nar"
}
},
"system": "",
"version": 4
}
}
}
4 changes: 4 additions & 0 deletions src/libstore-tests/dummy-store.cc
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ TEST(DummyStore, realisation_read)
{
initLibStore(/*loadConfig=*/false);

nix::experimentalFeatureSettings.set("extra-experimental-features", "ca-derivations");

auto store = [] {
auto cfg = make_ref<DummyStoreConfig>(StoreReference::Params{});
cfg->readOnly = false;
Expand All @@ -53,6 +55,8 @@ TEST(DummyStore, realisation_read)

ASSERT_TRUE(value2);
EXPECT_EQ(*value2, value);

nix::experimentalFeatureSettings.set("extra-experimental-features", "");
}

/* ----------------------------------------------------------------------------
Expand Down
41 changes: 26 additions & 15 deletions src/libstore-tests/worker-substitution.cc
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,19 @@ TEST_F(WorkerSubstitutionTest, floatingDerivationOutputWithDepDrv)
// Write the root derivation to the destination store
auto rootDrvPath = dummyStore->writeDerivation(rootDrv);

// Resolve the root derivation using a callback that returns the dep output path
auto resolvedRootDrv = rootDrv.tryResolve(
*substituter,
[&](ref<const SingleDerivedPath> drvPath, const std::string & outputName) -> std::optional<StorePath> {
EXPECT_EQ(*drvPath, SingleDerivedPath::Opaque{depDrvPath});
EXPECT_EQ(outputName, "out");
return depOutputPath;
});
ASSERT_TRUE(resolvedRootDrv);

// Write the resolved derivation to the substituter
auto resolvedRootDrvPath = substituter->writeDerivation(Derivation{*resolvedRootDrv});

// Snapshot the destination store before
checkpointJson("issue-11928/store-before", dummyStore);

Expand All @@ -363,11 +376,12 @@ TEST_F(WorkerSubstitutionTest, floatingDerivationOutputWithDepDrv)

// The DrvOutputs for both derivations
DrvOutput depDrvOutput{depDrvPath, "out"};
DrvOutput rootDrvOutput{rootDrvPath, "out"};
DrvOutput resolvedRootDrvOutput{resolvedRootDrvPath, "out"};

// Add the realisation for the root derivation to the substituter
// Add the realisation for the *resolved* root derivation to the substituter
// (not the original root derivation - that would be an illegal "deep" realisation)
substituter->buildTrace.insert_or_assign(
rootDrvPath,
resolvedRootDrvPath,
std::map<std::string, UnkeyedRealisation>{
{
"out",
Expand All @@ -378,12 +392,12 @@ TEST_F(WorkerSubstitutionTest, floatingDerivationOutputWithDepDrv)
});

// Snapshot the substituter
// Note: it has realisations for both drvs, but only the root's output store object
// Note: it has the dep realisation, resolved root drv, resolved root realisation, and root output
checkpointJson("issue-11928/substituter", substituter);

// The realisations should not exist in the destination store yet
ASSERT_FALSE(dummyStore->queryRealisation(depDrvOutput));
ASSERT_FALSE(dummyStore->queryRealisation(rootDrvOutput));
ASSERT_FALSE(dummyStore->queryRealisation(resolvedRootDrvOutput));

// Create a worker with our custom substituter
Worker worker{*dummyStore, *dummyStore};
Expand All @@ -407,21 +421,18 @@ TEST_F(WorkerSubstitutionTest, floatingDerivationOutputWithDepDrv)
// The root output path should now exist in the destination store
ASSERT_TRUE(dummyStore->isValidPath(rootOutputPath));

// The root realisation should now exist in the destination store
auto rootRealisation = dummyStore->queryRealisation(rootDrvOutput);
// The resolved root realisation should now exist in the destination store
auto rootRealisation = dummyStore->queryRealisation(resolvedRootDrvOutput);
ASSERT_TRUE(rootRealisation);
ASSERT_EQ(rootRealisation->outPath, rootOutputPath);

// #11928: The dependency's REALISATION should be fetched, because
// it is needed to resolve the underlying derivation. Currently the
// realisation is not fetched (bug). Once fixed: Change
// depRealisation ASSERT_FALSE to ASSERT_TRUE and uncomment the
// ASSERT_EQ
// The dependency's REALISATION should have been fetched
auto depRealisation = dummyStore->queryRealisation(depDrvOutput);
ASSERT_FALSE(depRealisation);
// ASSERT_EQ(depRealisation->outPath, depOutputPath);
ASSERT_TRUE(depRealisation);
ASSERT_EQ(depRealisation->outPath, depOutputPath);

// The dependency's OUTPUT is correctly not fetched (not referenced by root output)
// The dependency's OUTPUT should NOT be fetched (not referenced by
// root output).
ASSERT_FALSE(dummyStore->isValidPath(depOutputPath));

// Verify the goal succeeded
Expand Down
Loading