From 2767ae35d9824e861df3211f4153bff7d3690023 Mon Sep 17 00:00:00 2001 From: John Ericson Date: Fri, 15 Aug 2025 16:50:46 -0400 Subject: [PATCH] Deduplicate "export reference graph" logic a bit The first part on `drvOptions.exportReferencesGraph` is the same in both cases. It is just how the information is finally rendered that is different. --- src/libstore/derivation-options.cc | 18 ++++++++++++++++++ .../include/nix/store/derivation-options.hh | 18 ++++++++++++++++++ src/libstore/parsed-derivations.cc | 5 +---- src/libstore/unix/build/derivation-builder.cc | 10 ++-------- 4 files changed, 39 insertions(+), 12 deletions(-) diff --git a/src/libstore/derivation-options.cc b/src/libstore/derivation-options.cc index b41b97f4c..1acb9dc03 100644 --- a/src/libstore/derivation-options.cc +++ b/src/libstore/derivation-options.cc @@ -256,6 +256,24 @@ DerivationOptions::fromStructuredAttrs(const StringMap & env, const StructuredAt }; } +std::map +DerivationOptions::getParsedExportReferencesGraph(const StoreDirConfig & store) const +{ + std::map res; + + for (auto & [fileName, ss] : exportReferencesGraph) { + StorePathSet storePaths; + for (auto & storePathS : ss) { + if (!store.isInStore(storePathS)) + throw BuildError("'exportReferencesGraph' contains a non-store path '%1%'", storePathS); + storePaths.insert(store.toStorePath(storePathS).first); + } + res.insert_or_assign(fileName, storePaths); + } + + return res; +} + StringSet DerivationOptions::getRequiredSystemFeatures(const BasicDerivation & drv) const { // FIXME: cache this? diff --git a/src/libstore/include/nix/store/derivation-options.hh b/src/libstore/include/nix/store/derivation-options.hh index 98517e904..88694f730 100644 --- a/src/libstore/include/nix/store/derivation-options.hh +++ b/src/libstore/include/nix/store/derivation-options.hh @@ -8,10 +8,12 @@ #include "nix/util/types.hh" #include "nix/util/json-impls.hh" +#include "nix/store/path.hh" namespace nix { class Store; +struct StoreDirConfig; struct BasicDerivation; struct StructuredAttrs; @@ -116,6 +118,22 @@ struct DerivationOptions */ std::map exportReferencesGraph; + /** + * Once a derivations is resolved, the strings in in + * `exportReferencesGraph` should all be store paths (with possible + * suffix paths, but those are discarded). + * + * @return The parsed path set for for each key in the map. + * + * @todo Ideally, `exportReferencesGraph` would just store + * `StorePath`s for this, but we can't just do that, because for CA + * derivations they is actually in general `DerivedPath`s (via + * placeholder strings) until the derivation is resolved and exact + * inputs store paths are known. We can use better types for that + * too, but that is a longer project. + */ + std::map getParsedExportReferencesGraph(const StoreDirConfig & store) const; + /** * env: __sandboxProfile * diff --git a/src/libstore/parsed-derivations.cc b/src/libstore/parsed-derivations.cc index 1006bbc0a..9e8d44d6e 100644 --- a/src/libstore/parsed-derivations.cc +++ b/src/libstore/parsed-derivations.cc @@ -113,10 +113,7 @@ nlohmann::json StructuredAttrs::prepareStructuredAttrs( json["outputs"] = std::move(outputsJson); /* Handle exportReferencesGraph. */ - for (auto & [key, inputPaths] : drvOptions.exportReferencesGraph) { - StorePathSet storePaths; - for (auto & p : inputPaths) - storePaths.insert(store.toStorePath(p).first); + for (auto & [key, storePaths] : drvOptions.getParsedExportReferencesGraph(store)) { json[key] = pathInfoToJSON(store, store.exportReferences(storePaths, storePaths)); } diff --git a/src/libstore/unix/build/derivation-builder.cc b/src/libstore/unix/build/derivation-builder.cc index f6546ec62..76468cca0 100644 --- a/src/libstore/unix/build/derivation-builder.cc +++ b/src/libstore/unix/build/derivation-builder.cc @@ -785,17 +785,11 @@ void DerivationBuilderImpl::startBuilder() /* Handle exportReferencesGraph(), if set. */ if (!drv.structuredAttrs) { - for (auto & [fileName, ss] : drvOptions.exportReferencesGraph) { - StorePathSet storePathSet; - for (auto & storePathS : ss) { - if (!store.isInStore(storePathS)) - throw BuildError("'exportReferencesGraph' contains a non-store path '%1%'", storePathS); - storePathSet.insert(store.toStorePath(storePathS).first); - } + for (auto & [fileName, storePaths] : drvOptions.getParsedExportReferencesGraph(store)) { /* Write closure info to . */ writeFile( tmpDir + "/" + fileName, - store.makeValidityRegistration(store.exportReferences(storePathSet, inputPaths), false, false)); + store.makeValidityRegistration(store.exportReferences(storePaths, inputPaths), false, false)); } }