1
1
Fork 0
mirror of https://github.com/NixOS/nix.git synced 2025-11-15 15:02:42 +01:00

Move exportReferencesGraph to DerivationOptions

Tests are updated accordingly.
This commit is contained in:
John Ericson 2025-02-03 11:28:43 -05:00
parent 307dbe9914
commit d285b80033
18 changed files with 183 additions and 56 deletions

View file

@ -3,9 +3,11 @@
#include "nix/store/parsed-derivations.hh"
#include "nix/util/types.hh"
#include "nix/util/util.hh"
#include <optional>
#include <string>
#include <variant>
#include <regex>
namespace nix {
@ -126,6 +128,34 @@ DerivationOptions DerivationOptions::fromParsedDerivation(const ParsedDerivation
}
return res;
}(),
.exportReferencesGraph =
[&] {
std::map<std::string, StringSet> ret;
if (auto structuredAttrs = parsed.structuredAttrs.get()) {
auto e = optionalValueAt(*structuredAttrs, "exportReferencesGraph");
if (!e || !e->is_object())
return ret;
for (auto & [key, storePathsJson] : getObject(*e)) {
ret.insert_or_assign(key, storePathsJson);
}
} else {
auto s = getOr(parsed.drv.env, "exportReferencesGraph", "");
Strings ss = tokenizeString<Strings>(s);
if (ss.size() % 2 != 0)
throw BuildError("odd number of tokens in 'exportReferencesGraph': '%1%'", s);
for (Strings::iterator i = ss.begin(); i != ss.end();) {
auto fileName = std::move(*i++);
static std::regex regex("[A-Za-z_][A-Za-z0-9_.-]*");
if (!std::regex_match(fileName, regex))
throw Error("invalid file name '%s' in 'exportReferencesGraph'", fileName);
auto & storePathS = *i++;
ret.insert_or_assign(std::move(fileName), StringSet{storePathS});
}
}
return ret;
}(),
.additionalSandboxProfile =
parsed.getStringAttr("__sandboxProfile").value_or(defaults.additionalSandboxProfile),
.noChroot = parsed.getBoolAttr("__noChroot", defaults.noChroot),

View file

@ -95,6 +95,27 @@ struct DerivationOptions
*/
StringSet passAsFile;
/**
* The `exportReferencesGraph' feature allows the references graph
* to be passed to a builder
*
* ### Legacy case
*
* Given a `name` `pathSet` key-value pair, the references graph of
* `pathSet` will be stored in a text file `name' in the temporary
* build directory. The text files have the format used by
* `nix-store
* --register-validity'. However, the `deriver` fields are left
* empty.
*
* ### "Structured attributes" case
*
* The same information will be put put in the final structured
* attributes give to the builder. The set of paths in the original JSON
* is replaced with a list of `PathInfo` in JSON format.
*/
std::map<std::string, StringSet> exportReferencesGraph;
/**
* env: __sandboxProfile
*

View file

@ -42,7 +42,8 @@ public:
return static_cast<bool>(structuredAttrs);
}
std::optional<nlohmann::json> prepareStructuredAttrs(Store & store, const StorePathSet & inputPaths);
std::optional<nlohmann::json>
prepareStructuredAttrs(Store & store, const DerivationOptions & drvOptions, const StorePathSet & inputPaths);
};
std::string writeStructuredAttrsShell(const nlohmann::json & json);

View file

@ -1,7 +1,7 @@
#pragma once
///@file
#include "local-store.hh"
#include "nix/store/local-store.hh"
namespace nix {

View file

@ -1,4 +1,5 @@
#include "nix/store/parsed-derivations.hh"
#include "nix/store/derivation-options.hh"
#include <nlohmann/json.hpp>
#include <regex>
@ -151,7 +152,10 @@ static nlohmann::json pathInfoToJSON(
return jsonList;
}
std::optional<nlohmann::json> ParsedDerivation::prepareStructuredAttrs(Store & store, const StorePathSet & inputPaths)
std::optional<nlohmann::json> ParsedDerivation::prepareStructuredAttrs(
Store & store,
const DerivationOptions & drvOptions,
const StorePathSet & inputPaths)
{
if (!structuredAttrs) return std::nullopt;
@ -164,15 +168,12 @@ std::optional<nlohmann::json> ParsedDerivation::prepareStructuredAttrs(Store & s
json["outputs"] = outputs;
/* Handle exportReferencesGraph. */
auto e = json.find("exportReferencesGraph");
if (e != json.end() && e->is_object()) {
for (auto i = e->begin(); i != e->end(); ++i) {
StorePathSet storePaths;
for (auto & p : *i)
storePaths.insert(store.toStorePath(p.get<std::string>()).first);
json[i.key()] = pathInfoToJSON(store,
store.exportReferences(storePaths, inputPaths));
}
for (auto & [key, inputPaths] : drvOptions.exportReferencesGraph) {
StorePathSet storePaths;
for (auto & p : inputPaths)
storePaths.insert(store.toStorePath(p).first);
json[key] = pathInfoToJSON(store,
store.exportReferences(storePaths, storePaths));
}
return json;

View file

@ -24,7 +24,6 @@
#include "nix/store/restricted-store.hh"
#include "nix/store/config.hh"
#include <regex>
#include <queue>
#include <sys/un.h>
@ -973,32 +972,17 @@ void LocalDerivationGoal::startBuilder()
/* Handle exportReferencesGraph(), if set. */
if (!parsedDrv->hasStructuredAttrs()) {
/* The `exportReferencesGraph' feature allows the references graph
to be passed to a builder. This attribute should be a list of
pairs [name1 path1 name2 path2 ...]. The references graph of
each `pathN' will be stored in a text file `nameN' in the
temporary build directory. The text files have the format used
by `nix-store --register-validity'. However, the deriver
fields are left empty. */
auto s = getOr(drv->env, "exportReferencesGraph", "");
Strings ss = tokenizeString<Strings>(s);
if (ss.size() % 2 != 0)
throw BuildError("odd number of tokens in 'exportReferencesGraph': '%1%'", s);
for (Strings::iterator i = ss.begin(); i != ss.end(); ) {
auto fileName = *i++;
static std::regex regex("[A-Za-z_][A-Za-z0-9_.-]*");
if (!std::regex_match(fileName, regex))
throw Error("invalid file name '%s' in 'exportReferencesGraph'", fileName);
auto storePathS = *i++;
if (!worker.store.isInStore(storePathS))
throw BuildError("'exportReferencesGraph' contains a non-store path '%1%'", storePathS);
auto storePath = worker.store.toStorePath(storePathS).first;
for (auto & [fileName, ss] : drvOptions->exportReferencesGraph) {
StorePathSet storePathSet;
for (auto & storePathS : ss) {
if (!worker.store.isInStore(storePathS))
throw BuildError("'exportReferencesGraph' contains a non-store path '%1%'", storePathS);
storePathSet.insert(worker.store.toStorePath(storePathS).first);
}
/* Write closure info to <fileName>. */
writeFile(tmpDir + "/" + fileName,
worker.store.makeValidityRegistration(
worker.store.exportReferences({storePath}, inputPaths), false, false));
worker.store.exportReferences(storePathSet, inputPaths), false, false));
}
}
@ -1592,7 +1576,7 @@ void LocalDerivationGoal::initEnv()
void LocalDerivationGoal::writeStructuredAttrs()
{
if (auto structAttrsJson = parsedDrv->prepareStructuredAttrs(worker.store, inputPaths)) {
if (auto structAttrsJson = parsedDrv->prepareStructuredAttrs(worker.store, *drvOptions, inputPaths)) {
auto json = structAttrsJson.value();
nlohmann::json rewritten;
for (auto & [i, v] : json["outputs"].get<nlohmann::json::object_t>()) {