Skip to content

Commit 106195a

Browse files
committed
Move exportReferencesGraph to DerivationOptions
1 parent c868df9 commit 106195a

9 files changed

Lines changed: 83 additions & 47 deletions

File tree

src/libstore-tests/derivation-advanced-attrs.cc

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ TEST_F(DerivationAdvancedAttrsTest, Derivation_advancedAttributes_defaults)
8282
auto drvPath = writeDerivation(*store, got, NoRepair, true);
8383

8484
ParsedDerivation parsedDrv(got);
85-
DerivationOptions options = DerivationOptions::fromParsedDerivation(parsedDrv);
85+
DerivationOptions options = DerivationOptions::fromParsedDerivation(*store, parsedDrv);
8686

8787
EXPECT_TRUE(!parsedDrv.hasStructuredAttrs());
8888

@@ -117,7 +117,7 @@ TEST_F(DerivationAdvancedAttrsTest, Derivation_advancedAttributes)
117117
auto drvPath = writeDerivation(*store, got, NoRepair, true);
118118

119119
ParsedDerivation parsedDrv(got);
120-
DerivationOptions options = DerivationOptions::fromParsedDerivation(parsedDrv);
120+
DerivationOptions options = DerivationOptions::fromParsedDerivation(*store, parsedDrv);
121121

122122
StringSet systemFeatures{"rainbow", "uid-range"};
123123

@@ -158,7 +158,7 @@ TEST_F(DerivationAdvancedAttrsTest, Derivation_advancedAttributes_structuredAttr
158158
auto drvPath = writeDerivation(*store, got, NoRepair, true);
159159

160160
ParsedDerivation parsedDrv(got);
161-
DerivationOptions options = DerivationOptions::fromParsedDerivation(parsedDrv);
161+
DerivationOptions options = DerivationOptions::fromParsedDerivation(*store, parsedDrv);
162162

163163
EXPECT_TRUE(parsedDrv.hasStructuredAttrs());
164164

@@ -192,7 +192,7 @@ TEST_F(DerivationAdvancedAttrsTest, Derivation_advancedAttributes_structuredAttr
192192
auto drvPath = writeDerivation(*store, got, NoRepair, true);
193193

194194
ParsedDerivation parsedDrv(got);
195-
DerivationOptions options = DerivationOptions::fromParsedDerivation(parsedDrv);
195+
DerivationOptions options = DerivationOptions::fromParsedDerivation(*store, parsedDrv);
196196

197197
StringSet systemFeatures{"rainbow", "uid-range"};
198198

src/libstore/build/derivation-goal.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,8 @@ Goal::Co DerivationGoal::haveDerivation()
182182

183183
parsedDrv = std::make_unique<ParsedDerivation>(*drv);
184184
try {
185-
drvOptions = std::make_unique<DerivationOptions>(DerivationOptions::fromParsedDerivation(*parsedDrv));
185+
drvOptions = std::make_unique<DerivationOptions>(
186+
DerivationOptions::fromParsedDerivation(worker.store, *parsedDrv));
186187
} catch (Error & e) {
187188
e.addTrace({}, "while parsing derivation '%s'", worker.store.printStorePath(drvPath));
188189
throw;

src/libstore/derivation-options.cc

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,20 @@
33
#include "parsed-derivations.hh"
44
#include "types.hh"
55
#include "util.hh"
6+
67
#include <optional>
78
#include <string>
89
#include <variant>
10+
#include <regex>
911

1012
namespace nix {
1113

1214
using OutputChecks = DerivationOptions::OutputChecks;
1315

1416
using OutputChecksVariant = std::variant<OutputChecks, std::map<std::string, OutputChecks>>;
1517

16-
DerivationOptions DerivationOptions::fromParsedDerivation(const ParsedDerivation & parsed, bool shouldWarn)
18+
DerivationOptions
19+
DerivationOptions::fromParsedDerivation(const StoreDirConfig & store, const ParsedDerivation & parsed, bool shouldWarn)
1720
{
1821
DerivationOptions defaults = {};
1922

@@ -126,6 +129,39 @@ DerivationOptions DerivationOptions::fromParsedDerivation(const ParsedDerivation
126129
}
127130
return res;
128131
}(),
132+
.exportReferencesGraph =
133+
[&] {
134+
std::map<std::string, StorePathSet> ret;
135+
136+
if (auto structuredAttrs = parsed.structuredAttrs.get()) {
137+
auto e = optionalValueAt(*structuredAttrs, "exportReferencesGraph");
138+
if (!e || !e->is_object())
139+
return ret;
140+
for (auto & [key, storePathsJson] : getObject(*e)) {
141+
StorePathSet storePaths;
142+
for (auto & p : storePathsJson)
143+
storePaths.insert(store.toStorePath(p.get<std::string>()).first);
144+
ret.insert_or_assign(key, std::move(storePaths));
145+
}
146+
} else {
147+
auto s = getOr(parsed.drv.env, "exportReferencesGraph", "");
148+
Strings ss = tokenizeString<Strings>(s);
149+
if (ss.size() % 2 != 0)
150+
throw BuildError("odd number of tokens in 'exportReferencesGraph': '%1%'", s);
151+
for (Strings::iterator i = ss.begin(); i != ss.end();) {
152+
auto fileName = std::move(*i++);
153+
static std::regex regex("[A-Za-z_][A-Za-z0-9_.-]*");
154+
if (!std::regex_match(fileName, regex))
155+
throw Error("invalid file name '%s' in 'exportReferencesGraph'", fileName);
156+
157+
auto & storePathS = *i++;
158+
if (!store.isInStore(storePathS))
159+
throw Error("'exportReferencesGraph' contains a non-store path '%1%'", storePathS);
160+
ret.insert_or_assign(std::move(fileName), StorePathSet{store.toStorePath(storePathS).first});
161+
}
162+
}
163+
return ret;
164+
}(),
129165
.additionalSandboxProfile =
130166
parsed.getStringAttr("__sandboxProfile").value_or(defaults.additionalSandboxProfile),
131167
.noChroot = parsed.getBoolAttr("__noChroot", defaults.noChroot),
@@ -180,7 +216,6 @@ bool DerivationOptions::useUidRange(const BasicDerivation & drv) const
180216
{
181217
return getRequiredSystemFeatures(drv).count("uid-range");
182218
}
183-
184219
}
185220

186221
namespace nlohmann {

src/libstore/derivation-options.hh

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#include "types.hh"
1010
#include "json-impls.hh"
11+
#include "store-dir-config.hh"
1112

1213
namespace nix {
1314

@@ -95,6 +96,27 @@ struct DerivationOptions
9596
*/
9697
StringSet passAsFile;
9798

99+
/**
100+
* The `exportReferencesGraph' feature allows the references graph
101+
* to be passed to a builder
102+
*
103+
* ### Legacy case
104+
*
105+
* Given a `name` `pathSet` key-value pair, the references graph of
106+
* `pathSet` will be stored in a text file `name' in the temporary
107+
* build directory. The text files have the format used by
108+
* `nix-store
109+
* --register-validity'. However, the `deriver` fields are left
110+
* empty.
111+
*
112+
* ### "Structured attributes" case
113+
*
114+
* The same information will be put put in the final structured
115+
* attributes give to the builder. The set of paths in the original JSON
116+
* is replaced with a list of `PathInfo` in JSON format.
117+
*/
118+
std::map<std::string, StorePathSet> exportReferencesGraph;
119+
98120
/**
99121
* env: __sandboxProfile
100122
*
@@ -152,7 +174,8 @@ struct DerivationOptions
152174
* (e.g. JSON) but is necessary for supporing old formats (e.g.
153175
* ATerm).
154176
*/
155-
static DerivationOptions fromParsedDerivation(const ParsedDerivation & parsed, bool shouldWarn = true);
177+
static DerivationOptions
178+
fromParsedDerivation(const StoreDirConfig & store, const ParsedDerivation & parsed, bool shouldWarn = true);
156179

157180
/**
158181
* @param drv Must be the same derivation we parsed this from. In

src/libstore/misc.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ void Store::queryMissing(const std::vector<DerivedPath> & targets,
225225
ParsedDerivation parsedDrv(*drv);
226226
DerivationOptions drvOptions;
227227
try {
228-
drvOptions = DerivationOptions::fromParsedDerivation(parsedDrv);
228+
drvOptions = DerivationOptions::fromParsedDerivation(*this, parsedDrv);
229229
} catch (Error & e) {
230230
e.addTrace({}, "while parsing derivation '%s'", printStorePath(drvPath));
231231
throw;

src/libstore/parsed-derivations.cc

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "parsed-derivations.hh"
2+
#include "derivation-options.hh"
23

34
#include <nlohmann/json.hpp>
45
#include <regex>
@@ -151,7 +152,10 @@ static nlohmann::json pathInfoToJSON(
151152
return jsonList;
152153
}
153154

154-
std::optional<nlohmann::json> ParsedDerivation::prepareStructuredAttrs(Store & store, const StorePathSet & inputPaths)
155+
std::optional<nlohmann::json> ParsedDerivation::prepareStructuredAttrs(
156+
Store & store,
157+
const DerivationOptions & drvOptions,
158+
const StorePathSet & inputPaths)
155159
{
156160
if (!structuredAttrs) return std::nullopt;
157161

@@ -164,15 +168,9 @@ std::optional<nlohmann::json> ParsedDerivation::prepareStructuredAttrs(Store & s
164168
json["outputs"] = outputs;
165169

166170
/* Handle exportReferencesGraph. */
167-
auto e = json.find("exportReferencesGraph");
168-
if (e != json.end() && e->is_object()) {
169-
for (auto i = e->begin(); i != e->end(); ++i) {
170-
StorePathSet storePaths;
171-
for (auto & p : *i)
172-
storePaths.insert(store.toStorePath(p.get<std::string>()).first);
173-
json[i.key()] = pathInfoToJSON(store,
174-
store.exportReferences(storePaths, inputPaths));
175-
}
171+
for (auto & [key, storePaths] : drvOptions.exportReferencesGraph) {
172+
json[key] = pathInfoToJSON(store,
173+
store.exportReferences(storePaths, inputPaths));
176174
}
177175

178176
return json;

src/libstore/parsed-derivations.hh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ public:
4242
return static_cast<bool>(structuredAttrs);
4343
}
4444

45-
std::optional<nlohmann::json> prepareStructuredAttrs(Store & store, const StorePathSet & inputPaths);
45+
std::optional<nlohmann::json>
46+
prepareStructuredAttrs(Store & store, const DerivationOptions & drvOptions, const StorePathSet & inputPaths);
4647
};
4748

4849
std::string writeStructuredAttrsShell(const nlohmann::json & json);

src/libstore/unix/build/local-derivation-goal.cc

Lines changed: 3 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
#include "posix-fs-canonicalise.hh"
2323
#include "posix-source-accessor.hh"
2424

25-
#include <regex>
2625
#include <queue>
2726

2827
#include <sys/un.h>
@@ -976,32 +975,11 @@ void LocalDerivationGoal::startBuilder()
976975

977976
/* Handle exportReferencesGraph(), if set. */
978977
if (!parsedDrv->hasStructuredAttrs()) {
979-
/* The `exportReferencesGraph' feature allows the references graph
980-
to be passed to a builder. This attribute should be a list of
981-
pairs [name1 path1 name2 path2 ...]. The references graph of
982-
each `pathN' will be stored in a text file `nameN' in the
983-
temporary build directory. The text files have the format used
984-
by `nix-store --register-validity'. However, the deriver
985-
fields are left empty. */
986-
auto s = getOr(drv->env, "exportReferencesGraph", "");
987-
Strings ss = tokenizeString<Strings>(s);
988-
if (ss.size() % 2 != 0)
989-
throw BuildError("odd number of tokens in 'exportReferencesGraph': '%1%'", s);
990-
for (Strings::iterator i = ss.begin(); i != ss.end(); ) {
991-
auto fileName = *i++;
992-
static std::regex regex("[A-Za-z_][A-Za-z0-9_.-]*");
993-
if (!std::regex_match(fileName, regex))
994-
throw Error("invalid file name '%s' in 'exportReferencesGraph'", fileName);
995-
996-
auto storePathS = *i++;
997-
if (!worker.store.isInStore(storePathS))
998-
throw BuildError("'exportReferencesGraph' contains a non-store path '%1%'", storePathS);
999-
auto storePath = worker.store.toStorePath(storePathS).first;
1000-
978+
for (auto & [fileName, storePathSet] : drvOptions->exportReferencesGraph) {
1001979
/* Write closure info to <fileName>. */
1002980
writeFile(tmpDir + "/" + fileName,
1003981
worker.store.makeValidityRegistration(
1004-
worker.store.exportReferences({storePath}, inputPaths), false, false));
982+
worker.store.exportReferences(storePathSet, inputPaths), false, false));
1005983
}
1006984
}
1007985

@@ -1595,7 +1573,7 @@ void LocalDerivationGoal::initEnv()
15951573

15961574
void LocalDerivationGoal::writeStructuredAttrs()
15971575
{
1598-
if (auto structAttrsJson = parsedDrv->prepareStructuredAttrs(worker.store, inputPaths)) {
1576+
if (auto structAttrsJson = parsedDrv->prepareStructuredAttrs(worker.store, *drvOptions, inputPaths)) {
15991577
auto json = structAttrsJson.value();
16001578
nlohmann::json rewritten;
16011579
for (auto & [i, v] : json["outputs"].get<nlohmann::json::object_t>()) {

src/nix-build/nix-build.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -547,7 +547,7 @@ static void main_nix_build(int argc, char * * argv)
547547
ParsedDerivation parsedDrv(drv);
548548
DerivationOptions drvOptions;
549549
try {
550-
drvOptions = DerivationOptions::fromParsedDerivation(parsedDrv);
550+
drvOptions = DerivationOptions::fromParsedDerivation(*store, parsedDrv);
551551
} catch (Error & e) {
552552
e.addTrace({}, "while parsing derivation '%s'", store->printStorePath(packageInfo.requireDrvPath()));
553553
throw;
@@ -584,7 +584,7 @@ static void main_nix_build(int argc, char * * argv)
584584
for (const auto & [inputDrv, inputNode] : drv.inputDrvs.map)
585585
accumInputClosure(inputDrv, inputNode);
586586

587-
if (auto structAttrs = parsedDrv.prepareStructuredAttrs(*store, inputs)) {
587+
if (auto structAttrs = parsedDrv.prepareStructuredAttrs(*store, drvOptions, inputs)) {
588588
auto json = structAttrs.value();
589589
structuredAttrsRC = writeStructuredAttrsShell(json);
590590

0 commit comments

Comments
 (0)