libstore: remove DerivedPathMap

single-level maps suffice now that dynamic derivations are gone.

Change-Id: If29998b104b31255292ab0c789622d7d27040f69
This commit is contained in:
eldritch horrors
2025-05-12 13:37:54 +02:00
parent 68dfcfc6a4
commit 84c1df46ea
14 changed files with 67 additions and 298 deletions
+1 -1
View File
@@ -324,7 +324,7 @@ connected:
//
// 2. Changing the `inputSrcs` set changes the associated
// output ids, which break CA derivations
if (!drv.inputDrvs.map.empty())
if (!drv.inputDrvs.empty())
drv.inputSrcs = store->parseStorePathSet(inputs);
optResult = aio.blockOn(sshStore->buildDerivation(*drvPath, (const BasicDerivation &) drv));
auto & result = *optResult;
+7 -13
View File
@@ -368,18 +368,16 @@ static void main_nix_build(AsyncIoRoot & aio, std::string programName, Strings a
}
}
auto accumDerivedPath = [&](ref<SingleDerivedPath::Opaque> inputDrv, const DerivedPathMap<StringSet>::ChildNode & inputNode) {
if (!inputNode.value.empty())
auto accumDerivedPath = [&](ref<SingleDerivedPath::Opaque> inputDrv, const StringSet & inputNode) {
if (!inputNode.empty())
pathsToBuild.push_back(DerivedPath::Built {
.drvPath = inputDrv,
.outputs = OutputsSpec::Names { inputNode.value },
.outputs = OutputsSpec::Names { inputNode },
});
// only dynamic derivations have a non-empty childMap
assert(inputNode.childMap.empty());
};
// Build or fetch all dependencies of the derivation.
for (const auto & [inputDrv0, inputNode] : drv.inputDrvs.map) {
for (const auto & [inputDrv0, inputNode] : drv.inputDrvs) {
// To get around lambda capturing restrictions in the
// standard.
const auto & inputDrv = inputDrv0;
@@ -451,20 +449,16 @@ static void main_nix_build(AsyncIoRoot & aio, std::string programName, Strings a
if (env.count("__json")) {
StorePathSet inputs;
std::function<void(const StorePath &, const DerivedPathMap<StringSet>::ChildNode &)> accumInputClosure;
accumInputClosure = [&](const StorePath & inputDrv, const DerivedPathMap<StringSet>::ChildNode & inputNode) {
auto accumInputClosure = [&](const StorePath & inputDrv, const StringSet & inputNode) {
auto outputs =
aio.blockOn(store->queryPartialDerivationOutputMap(inputDrv, &*evalStore));
for (auto & i : inputNode.value) {
for (auto & i : inputNode) {
auto o = outputs.at(i);
aio.blockOn(store->computeFSClosure(*o, inputs));
}
for (const auto & [outputName, childNode] : inputNode.childMap)
accumInputClosure(*outputs.at(outputName), childNode);
};
for (const auto & [inputDrv, inputNode] : drv.inputDrvs.map)
for (const auto & [inputDrv, inputNode] : drv.inputDrvs)
accumInputClosure(inputDrv, inputNode);
ParsedDerivation parsedDrv(drvInfo.requireDrvPath(*state), drv);
+2 -2
View File
@@ -971,13 +971,13 @@ drvName, Bindings * attrs, Value & v)
for (auto & j : refs) {
drv.inputSrcs.insert(j);
if (j.isDerivation()) {
drv.inputDrvs.map[j].value =
drv.inputDrvs[j] =
state.aio.blockOn(state.ctx.store->readDerivation(j)).outputNames();
}
}
},
[&](const NixStringContextElem::Built & b) {
drv.inputDrvs.ensureSlot(*b.drvPath).value.insert(b.output);
drv.inputDrvs[b.drvPath->path].insert(b.output);
},
[&](const NixStringContextElem::Opaque & o) {
drv.inputSrcs.insert(o.path);
+11 -17
View File
@@ -373,19 +373,17 @@ try {
/* The inputs must be built before we can build this goal. */
inputDrvOutputs.clear();
if (useDerivation) {
auto addWaiteeDerivedPath = [&](ref<DerivedPathOpaque> inputDrv, const DerivedPathMap<StringSet>::ChildNode & inputNode) {
if (!inputNode.value.empty())
auto addWaiteeDerivedPath = [&](ref<DerivedPathOpaque> inputDrv, const StringSet & inputNode) {
if (!inputNode.empty())
dependencies.add(worker.goalFactory().makeGoal(
DerivedPath::Built {
.drvPath = inputDrv,
.outputs = inputNode.value,
.outputs = inputNode,
},
buildMode == bmRepair ? bmRepair : bmNormal));
// only dynamic derivations have a non-empty childMap
assert(inputNode.childMap.empty());
};
for (const auto & [inputDrvPath, inputNode] : dynamic_cast<Derivation *>(drv.get())->inputDrvs.map) {
for (const auto & [inputDrvPath, inputNode] : dynamic_cast<Derivation *>(drv.get())->inputDrvs) {
addWaiteeDerivedPath(makeConstantStorePathRef(inputDrvPath), inputNode);
}
}
@@ -539,7 +537,7 @@ try {
return ia.deferred;
},
[&](const DerivationType::ContentAddressed & ca) {
return !fullDrv.inputDrvs.map.empty() && (
return !fullDrv.inputDrvs.empty() && (
ca.fixed
/* Can optionally resolve if fixed, which is good
for avoiding unnecessary rebuilds. */
@@ -550,7 +548,7 @@ try {
},
}, drvType.raw);
if (resolveDrv && !fullDrv.inputDrvs.map.empty()) {
if (resolveDrv && !fullDrv.inputDrvs.empty()) {
experimentalFeatureSettings.require(Xp::CaDerivations);
/* We are be able to resolve this derivation based on the
@@ -587,10 +585,8 @@ try {
co_return co_await resolvedFinished();
}
std::function<kj::Promise<Result<void>>(const StorePath &, const DerivedPathMap<StringSet>::ChildNode &)> accumInputPaths;
// NOLINTNEXTLINE(cppcoreguidelines-avoid-capturing-lambda-coroutines)
accumInputPaths = [&](const StorePath & depDrvPath, const DerivedPathMap<StringSet>::ChildNode & inputNode) -> kj::Promise<Result<void>> {
auto accumInputPaths = [&](const StorePath & depDrvPath, const StringSet & inputNode) -> kj::Promise<Result<void>> {
try {
/* Add the relevant output closures of the input derivation
`i' as input paths. Only add the closures of output paths
@@ -633,21 +629,19 @@ try {
}
};
for (auto & outputName : inputNode.value) {
for (auto & outputName : inputNode) {
TRY_AWAIT(
worker.store.computeFSClosure(TRY_AWAIT(getOutput(outputName)), inputPaths)
);
}
for (auto & [outputName, childNode] : inputNode.childMap)
TRY_AWAIT(accumInputPaths(TRY_AWAIT(getOutput(outputName)), childNode));
co_return result::success();
} catch (...) {
co_return result::current_exception();
}
};
for (auto & [depDrvPath, depNode] : fullDrv.inputDrvs.map)
for (auto & [depDrvPath, depNode] : fullDrv.inputDrvs)
TRY_AWAIT(accumInputPaths(depDrvPath, depNode));
}
@@ -1762,9 +1756,9 @@ void DerivationGoal::waiteeDone(GoalPtr waitee)
auto & fullDrv = *dynamic_cast<Derivation *>(drv.get());
auto * nodeP = fullDrv.inputDrvs.findSlot(DerivedPath::Opaque { .path = dg->drvPath });
auto * nodeP = get(fullDrv.inputDrvs, dg->drvPath);
if (!nodeP) return;
auto & outputs = nodeP->value;
auto & outputs = *nodeP;
for (auto & outputName : outputs) {
auto buildResult = dg->buildResult.restrictTo(DerivedPath::Built {
+25 -55
View File
@@ -107,7 +107,7 @@ kj::Promise<Result<StorePath>> writeDerivation(Store & store,
const Derivation & drv, RepairFlag repair, bool readOnly)
try {
auto references = drv.inputSrcs;
for (auto & i : drv.inputDrvs.map)
for (auto & i : drv.inputDrvs)
references.insert(i.first);
/* Note that the outputs of a derivation are *not* references
(that can be missing (of course) and should not necessarily be
@@ -287,13 +287,11 @@ static DerivationOutput parseDerivationOutput(
return parseDerivationOutput(store, *pathS, *hashAlgo, *hash, xpSettings);
}
static DerivedPathMap<StringSet>::ChildNode parseDerivedPathMapNode(
static StringSet parseDerivedPathMapNode(
const Store & store,
StringViewStream & str)
{
DerivedPathMap<StringSet>::ChildNode node;
node.value = parseStrings(str, false);
return node;
return parseStrings(str, false);
}
@@ -333,7 +331,7 @@ Derivation parseDerivation(
expect(str, "(");
auto drvPath = parsePath(str);
expect(str, ",");
drv.inputDrvs.map.insert_or_assign(store.parseStorePath(*drvPath), parseDerivedPathMapNode(store, str));
drv.inputDrvs.insert_or_assign(store.parseStorePath(*drvPath), parseDerivedPathMapNode(store, str));
expect(str, ")");
}
@@ -421,29 +419,15 @@ static void printUnquotedStrings(std::string & res, ForwardIterator i, ForwardIt
}
static void unparseDerivedPathMapNode(const Store & store, std::string & s, const DerivedPathMap<StringSet>::ChildNode & node)
static void unparseDerivedPathMapNode(const Store & store, std::string & s, const StringSet & node)
{
s += ',';
if (node.childMap.empty()) {
printUnquotedStrings(s, node.value.begin(), node.value.end());
} else {
s += "(";
printUnquotedStrings(s, node.value.begin(), node.value.end());
s += ",[";
bool first = true;
for (auto & [outputName, childNode] : node.childMap) {
if (first) first = false; else s += ',';
s += '('; printUnquotedString(s, outputName);
unparseDerivedPathMapNode(store, s, childNode);
s += ')';
}
s += "])";
}
printUnquotedStrings(s, node.begin(), node.end());
}
std::string Derivation::unparse(const Store & store, bool maskOutputs,
DerivedPathMap<StringSet>::ChildNode::Map * actualInputs) const
std::map<std::string, StringSet> * actualInputs) const
{
std::string s;
s.reserve(65536);
@@ -490,7 +474,7 @@ std::string Derivation::unparse(const Store & store, bool maskOutputs,
s += ')';
}
} else {
for (auto & [drvPath, childMap] : inputDrvs.map) {
for (auto & [drvPath, childMap] : inputDrvs) {
if (first) first = false; else s += ',';
s += '('; printUnquotedString(s, store.printStorePath(drvPath));
unparseDerivedPathMapNode(store, s, childMap);
@@ -701,16 +685,16 @@ try {
},
}, drv.type().raw);
DerivedPathMap<StringSet>::ChildNode::Map inputs2;
for (auto & [drvPath, node] : drv.inputDrvs.map) {
std::map<std::string, StringSet> inputs2;
for (auto & [drvPath, node] : drv.inputDrvs) {
const auto & res = TRY_AWAIT(pathDerivationModulo(store, drvPath));
if (res.kind == DrvHash::Kind::Deferred)
kind = DrvHash::Kind::Deferred;
for (auto & outputName : node.value) {
for (auto & outputName : node) {
const auto h = get(res.hashes, outputName);
if (!h)
throw Error("no hash for output '%s' of derivation '%s'", outputName, drv.name);
inputs2[h->to_string(Base::Base16, false)].value.insert(outputName);
inputs2[h->to_string(Base::Base16, false)].insert(outputName);
}
}
@@ -900,19 +884,14 @@ Derivation::tryResolve(Store & store, Store * evalStore) const
try {
std::map<std::pair<StorePath, std::string>, StorePath> inputDrvOutputs;
std::function<
kj::Promise<Result<void>>(const StorePath &, const DerivedPathMap<StringSet>::ChildNode &)>
accum;
// NOLINTNEXTLINE(cppcoreguidelines-avoid-capturing-lambda-coroutines)
accum = [&](auto & inputDrv, auto & node) -> kj::Promise<Result<void>> {
auto accum = [&](auto & inputDrv, auto & node) -> kj::Promise<Result<void>> {
try {
for (auto & [outputName, outputPath] :
TRY_AWAIT(store.queryPartialDerivationOutputMap(inputDrv, evalStore)))
{
if (outputPath) {
inputDrvOutputs.insert_or_assign({inputDrv, outputName}, *outputPath);
if (auto p = get(node.childMap, outputName))
TRY_AWAIT(accum(*outputPath, *p));
}
}
co_return result::success();
@@ -921,7 +900,7 @@ try {
}
};
for (auto & [inputDrv, node] : inputDrvs.map)
for (auto & [inputDrv, node] : inputDrvs)
TRY_AWAIT(accum(inputDrv, node));
co_return TRY_AWAIT(tryResolve(store, inputDrvOutputs));
@@ -931,7 +910,7 @@ try {
static bool tryResolveInput(
Store & store, StorePathSet & inputSrcs, StringMap & inputRewrites,
const StorePath & inputDrv, const DerivedPathMap<StringSet>::ChildNode & inputNode,
const StorePath & inputDrv, const StringSet & inputNode,
const std::map<std::pair<StorePath, std::string>, StorePath> & inputDrvOutputs)
{
auto getOutput = [&](const std::string & outputName) {
@@ -948,7 +927,7 @@ static bool tryResolveInput(
return DownstreamPlaceholder::unknownCaOutput(inputDrv, outputName);
};
for (auto & outputName : inputNode.value) {
for (auto & outputName : inputNode) {
auto actualPathOpt = getOutput(outputName);
if (!actualPathOpt) return false;
auto actualPath = *actualPathOpt;
@@ -960,8 +939,6 @@ static bool tryResolveInput(
inputSrcs.insert(std::move(actualPath));
}
// only dynamic drvs can have non-empty childMaps
assert(inputNode.childMap.empty());
return true;
}
@@ -974,7 +951,7 @@ try {
// Input paths that we'll want to rewrite in the derivation
StringMap inputRewrites;
for (auto & [inputDrv, inputNode] : inputDrvs.map)
for (auto & [inputDrv, inputNode] : inputDrvs)
if (!tryResolveInput(store, resolved.inputSrcs, inputRewrites,
inputDrv, inputNode, inputDrvOutputs))
co_return std::nullopt;
@@ -1171,22 +1148,16 @@ JSON Derivation::toJSON(const Store & store) const
}
{
std::function<JSON(const DerivedPathMap<StringSet>::ChildNode &)> doInput;
doInput = [&](const auto & inputNode) {
auto doInput = [&](const auto & inputNode) {
auto value = JSON::object();
value["outputs"] = inputNode.value;
{
auto next = JSON::object();
for (auto & [outputId, childNode] : inputNode.childMap)
next[outputId] = doInput(childNode);
value["dynamicOutputs"] = std::move(next);
}
value["outputs"] = inputNode;
value["dynamicOutputs"] = JSON::object(); // for compatibility with cppnix
return value;
};
{
auto& inputDrvsObj = res["inputDrvs"];
inputDrvsObj = JSON::object();
for (auto & [inputDrv, inputNode] : inputDrvs.map) {
for (auto & [inputDrv, inputNode] : inputDrvs) {
inputDrvsObj[store.printStorePath(inputDrv)] = doInput(inputNode);
}
}
@@ -1236,10 +1207,9 @@ Derivation Derivation::fromJSON(
}
try {
std::function<DerivedPathMap<StringSet>::ChildNode(const JSON &)> doInput;
doInput = [&](const auto & json) {
DerivedPathMap<StringSet>::ChildNode node;
node.value = static_cast<const StringSet &>(
auto doInput = [&](const auto & json) {
StringSet node;
node = static_cast<const StringSet &>(
ensureType(valueAt(json, "outputs"), value_t::array));
if (!ensureType(valueAt(json, "dynamicOutputs"), value_t::object).empty()) {
throw UnimplementedError("dynamic derivations are not supported");
@@ -1248,7 +1218,7 @@ Derivation Derivation::fromJSON(
};
auto & inputDrvsObj = ensureType(valueAt(json, "inputDrvs"), value_t::object);
for (auto & [inputDrvPath, inputOutputs] : inputDrvsObj.items())
res.inputDrvs.map[store.parseStorePath(inputDrvPath)] =
res.inputDrvs[store.parseStorePath(inputDrvPath)] =
doInput(inputOutputs);
} catch (Error & e) {
e.addTrace({}, "while reading key 'inputDrvs'");
+4 -3
View File
@@ -2,15 +2,16 @@
///@file
#include "lix/libstore/path.hh"
#include "lix/libutil/config.hh"
#include "lix/libutil/result.hh"
#include "lix/libutil/types.hh"
#include "lix/libutil/hash.hh"
#include "lix/libstore/content-address.hh"
#include "lix/libutil/repair-flag.hh"
#include "lix/libstore/derived-path-map.hh"
#include "lix/libutil/sync.hh"
#include "lix/libutil/comparator.hh"
#include "lix/libutil/variant-wrapper.hh"
#include "outputs-spec.hh"
#include <kj/async.h>
#include <map>
@@ -286,13 +287,13 @@ struct Derivation : BasicDerivation
/**
* inputs that are sub-derivations
*/
DerivedPathMap<std::set<OutputName>> inputDrvs;
std::map<StorePath, std::set<OutputName>> inputDrvs;
/**
* Print a derivation.
*/
std::string unparse(const Store & store, bool maskOutputs,
DerivedPathMap<StringSet>::ChildNode::Map * actualInputs = nullptr) const;
std::map<std::string, StringSet> * actualInputs = nullptr) const;
/**
* Return the underlying basic derivation but with these changes:
-69
View File
@@ -1,69 +0,0 @@
#include "lix/libstore/derived-path-map.hh"
namespace nix {
template<typename V>
typename DerivedPathMap<V>::ChildNode & DerivedPathMap<V>::ensureSlot(const SingleDerivedPath & k)
{
std::function<ChildNode &(const SingleDerivedPath & )> initIter;
initIter = [&](const auto & k) -> auto & {
return std::visit(overloaded {
[&](const SingleDerivedPath::Opaque & bo) -> auto & {
// will not overwrite if already there
return map[bo.path];
},
[&](const SingleDerivedPath::Built & bfd) -> auto & {
auto & n = initIter(*bfd.drvPath);
return n.childMap[bfd.output];
},
}, k.raw());
};
return initIter(k);
}
template<typename V>
typename DerivedPathMap<V>::ChildNode * DerivedPathMap<V>::findSlot(const SingleDerivedPath & k)
{
std::function<ChildNode *(const SingleDerivedPath & )> initIter;
initIter = [&](const auto & k) {
return std::visit(overloaded {
[&](const SingleDerivedPath::Opaque & bo) {
auto it = map.find(bo.path);
return it != map.end()
? &it->second
: nullptr;
},
[&](const SingleDerivedPath::Built & bfd) {
auto * n = initIter(*bfd.drvPath);
if (!n) return (ChildNode *)nullptr;
auto it = n->childMap.find(bfd.output);
return it != n->childMap.end()
? &it->second
: nullptr;
},
}, k.raw());
};
return initIter(k);
}
}
// instantiations
namespace nix {
GENERATE_CMP_EXT(
template<>,
DerivedPathMap<std::set<std::string>>::ChildNode,
me->value,
me->childMap);
GENERATE_CMP_EXT(
template<>,
DerivedPathMap<std::set<std::string>>,
me->map);
template struct DerivedPathMap<std::set<std::string>>;
};
-96
View File
@@ -1,96 +0,0 @@
#pragma once
///@file
#include "lix/libutil/types.hh"
#include "lix/libstore/derived-path.hh"
namespace nix {
/**
* A simple Trie, of sorts. Conceptually a map of `SingleDerivedPath` to
* values.
*
* Concretely, an n-ary tree, as described below. A
* `SingleDerivedPath::Opaque` maps to the value of an immediate child
* of the root node. A `SingleDerivedPath::Built` maps to a deeper child
* node: the `SingleDerivedPath::Built::drvPath` is first mapped to a a
* child node (inductively), and then the
* `SingleDerivedPath::Built::output` is used to look up that child's
* child via its map. In this manner, every `SingleDerivedPath` is
* mapped to a child node.
*
* @param V A type to instantiate for each output. It should probably
* should be an "optional" type so not every interior node has to have a
* value. `* const Something` or `std::optional<Something>` would be
* good choices for "optional" types.
*/
template<typename V>
struct DerivedPathMap {
/**
* A child node (non-root node).
*/
struct ChildNode {
/**
* Value of this child node.
*
* @see DerivedPathMap for what `V` should be.
*/
V value;
/**
* The map type for the root node.
*/
using Map = std::map<OutputName, ChildNode>;
/**
* The map of the root node.
*/
Map childMap;
DECLARE_CMP(ChildNode);
};
/**
* The map type for the root node.
*/
using Map = std::map<StorePath, ChildNode>;
/**
* The map of root node.
*/
Map map;
DECLARE_CMP(DerivedPathMap);
/**
* Find the node for `k`, creating it if needed.
*
* The node is referred to as a "slot" on the assumption that `V` is
* some sort of optional type, so the given key can be set or unset
* by changing this node.
*/
ChildNode & ensureSlot(const SingleDerivedPath & k);
/**
* Like `ensureSlot` but does not create the slot if it doesn't exist.
*
* Read the entire description of `ensureSlot` to understand an
* important caveat here that "have slot" does *not* imply "key is
* set in map". To ensure a key is set one would need to get the
* child node (with `findSlot` or `ensureSlot`) *and* check the
* `ChildNode::value`.
*/
ChildNode * findSlot(const SingleDerivedPath & k);
};
DECLARE_CMP_EXT(
template<>,
DerivedPathMap<std::set<std::string>>::,
DerivedPathMap<std::set<std::string>>);
DECLARE_CMP_EXT(
template<>,
DerivedPathMap<std::set<std::string>>::ChildNode::,
DerivedPathMap<std::set<std::string>>::ChildNode);
}
-2
View File
@@ -156,7 +156,6 @@ libstore_sources = files(
'crypto.cc',
'daemon.cc',
'derivations.cc',
'derived-path-map.cc',
'derived-path.cc',
'downstream-placeholder.cc',
'dummy-store.cc',
@@ -225,7 +224,6 @@ libstore_headers = files(
'crypto.hh',
'daemon.hh',
'derivations.hh',
'derived-path-map.hh',
'derived-path.hh',
'downstream-placeholder.hh',
'dummy-store.hh',
+9 -26
View File
@@ -150,15 +150,13 @@ struct QueryMissingContext
kj::Promise<Result<void>> queryMissing(const std::vector<DerivedPath> & targets);
void enqueueDerivedPaths(ref<DerivedPathOpaque> inputDrv, const DerivedPathMap<StringSet>::ChildNode & inputNode)
void enqueueDerivedPaths(ref<DerivedPathOpaque> inputDrv, const StringSet & inputNode)
{
if (!inputNode.value.empty()) {
pool.enqueueWithAio([this, path{DerivedPath::Built{inputDrv, inputNode.value}}](
if (!inputNode.empty()) {
pool.enqueueWithAio([this, path{DerivedPath::Built{inputDrv, inputNode}}](
AsyncIoRoot & aio
) { doPath(aio, path); });
}
// only dynamic derivations have a non-empty childMap
assert(inputNode.childMap.empty());
}
void mustBuildDrv(const StorePath & drvPath, const Derivation & drv)
@@ -168,7 +166,7 @@ struct QueryMissingContext
state->willBuild.insert(drvPath);
}
for (const auto & [inputDrv, inputNode] : drv.inputDrvs.map) {
for (const auto & [inputDrv, inputNode] : drv.inputDrvs) {
enqueueDerivedPaths(makeConstantStorePathRef(inputDrv), inputNode);
}
}
@@ -415,20 +413,15 @@ try {
std::set<Realisation> inputRealisations;
std::function<
kj::Promise<Result<void>>(const StorePath &, const DerivedPathMap<StringSet>::ChildNode &)>
accumRealisations;
// NOLINTNEXTLINE(cppcoreguidelines-avoid-capturing-lambda-coroutines)
accumRealisations = [&](const StorePath & inputDrv,
const DerivedPathMap<StringSet>::ChildNode & inputNode
) -> kj::Promise<Result<void>> {
auto accumRealisations = [&](const StorePath & inputDrv,
const StringSet & inputNode) -> kj::Promise<Result<void>> {
try {
if (!inputNode.value.empty()) {
if (!inputNode.empty()) {
auto outputHashes = TRY_AWAIT(
staticOutputHashes(evalStore, TRY_AWAIT(evalStore.readDerivation(inputDrv)))
);
for (const auto & outputName : inputNode.value) {
for (const auto & outputName : inputNode) {
auto outputHash = get(outputHashes, outputName);
if (!outputHash)
throw Error(
@@ -443,23 +436,13 @@ try {
inputRealisations.insert(*thisRealisation);
}
}
if (!inputNode.value.empty()) {
auto d = makeConstantStorePathRef(inputDrv);
for (const auto & [outputName, childNode] : inputNode.childMap) {
SingleDerivedPath next = SingleDerivedPath::Built { d, outputName };
TRY_AWAIT(accumRealisations(
// TODO deep resolutions for dynamic derivations, issue #8947, would go here.
TRY_AWAIT(resolveDerivedPath(store, next, evalStore_)),
childNode));
}
}
co_return result::success();
} catch (...) {
co_return result::current_exception();
}
};
for (const auto & [inputDrv, inputNode] : drv.inputDrvs.map)
for (const auto & [inputDrv, inputNode] : drv.inputDrvs)
TRY_AWAIT(accumRealisations(inputDrv, inputNode));
auto info = TRY_AWAIT(store.queryPathInfo(outputPath));
+1 -1
View File
@@ -339,7 +339,7 @@ SV * derivationFromPath(char * drvPath)
hv_stores(hash, "outputs", newRV((SV *) outputs));
AV * inputDrvs = newAV();
for (auto & i : drv.inputDrvs.map)
for (auto & i : drv.inputDrvs)
av_push(inputDrvs, newSVpv(store()->printStorePath(i.first).c_str(), 0)); // !!! ignores i->second
hv_stores(hash, "inputDrvs", newRV((SV *) inputDrvs));
@@ -134,8 +134,7 @@ void rewriteAggregates(std::map<std::string, nix::JSON> &jobs,
auto childDrv = aio.blockOn(store->readDerivation(childDrvPath));
job["constituents"].push_back(
store->printStorePath(childDrvPath));
drv.inputDrvs.map[childDrvPath].value = {
childDrv.outputs.begin()->first};
drv.inputDrvs[childDrvPath] = {childDrv.outputs.begin()->first};
}
std::string drvName(drvPath.name());
+2 -3
View File
@@ -6,7 +6,6 @@
#include <lix/libexpr/value-to-json.hh>
#include <lix/libstore/derivations.hh>
#include <stdint.h>
#include <lix/libstore/derived-path-map.hh>
#include <lix/libexpr/eval.hh>
#include <lix/libexpr/get-drvs.hh>
#include <lix/libexpr/nixexpr.hh>
@@ -103,9 +102,9 @@ Drv::Drv(std::string &attrPath, nix::EvalState &state, nix::DrvInfo &drvInfo,
drvPath = localStore->printStorePath(drvInfo.requireDrvPath(state));
auto drv = state.aio.blockOn(localStore->readDerivation(drvInfo.requireDrvPath(state)));
for (const auto &[inputDrvPath, inputNode] : drv.inputDrvs.map) {
for (const auto &[inputDrvPath, inputNode] : drv.inputDrvs) {
std::set<std::string> inputDrvOutputs;
for (auto &outputName : inputNode.value) {
for (auto &outputName : inputNode) {
inputDrvOutputs.insert(outputName);
}
inputDrvs[localStore->printStorePath(inputDrvPath)] = inputDrvOutputs;
+4 -8
View File
@@ -204,15 +204,11 @@ Derivation makeSimpleDrv(const Store & store) {
store.parseStorePath("/nix/store/c015dhfh5l0lp6wxyvdn7bmwhbbr6hr9-dep1"),
};
drv.inputDrvs = {
.map = {
{
store.parseStorePath("/nix/store/c015dhfh5l0lp6wxyvdn7bmwhbbr6hr9-dep2.drv"),
{
store.parseStorePath("/nix/store/c015dhfh5l0lp6wxyvdn7bmwhbbr6hr9-dep2.drv"),
{
.value = {
"cat",
"dog",
},
},
"cat",
"dog",
},
},
};