diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index a645f546d..6af179e4e 100644 --- a/src/libexpr/primops.cc +++ b/src/libexpr/primops.cc @@ -1363,7 +1363,7 @@ static void derivationStrictInternal(EvalState & state, std::string_view drvName /* Check whether attributes should be passed as a JSON file. */ using nlohmann::json; - std::optional jsonObject; + std::optional jsonObject; auto pos = v.determinePos(noPos); auto attr = attrs->find(state.sStructuredAttrs); if (attr != attrs->end() @@ -1372,7 +1372,7 @@ static void derivationStrictInternal(EvalState & state, std::string_view drvName pos, "while evaluating the `__structuredAttrs` " "attribute passed to builtins.derivationStrict")) - jsonObject = json::object(); + jsonObject = StructuredAttrs{.structuredAttrs = json::object()}; /* Check whether null attributes should be ignored. */ bool ignoreNulls = false; @@ -1484,7 +1484,7 @@ static void derivationStrictInternal(EvalState & state, std::string_view drvName if (i->name == state.sStructuredAttrs) continue; - jsonObject->emplace(key, printValueAsJSON(state, true, *i->value, pos, context)); + jsonObject->structuredAttrs.emplace(key, printValueAsJSON(state, true, *i->value, pos, context)); if (i->name == state.sBuilder) drv.builder = state.forceString(*i->value, context, pos, context_below); @@ -1532,23 +1532,26 @@ static void derivationStrictInternal(EvalState & state, std::string_view drvName } else { auto s = state.coerceToString(pos, *i->value, context, context_below, true).toOwned(); - drv.env.emplace(key, s); - if (i->name == state.sBuilder) - drv.builder = std::move(s); - else if (i->name == state.sSystem) - drv.platform = std::move(s); - else if (i->name == state.sOutputHash) - outputHash = std::move(s); - else if (i->name == state.sOutputHashAlgo) - outputHashAlgo = parseHashAlgoOpt(s); - else if (i->name == state.sOutputHashMode) - handleHashMode(s); - else if (i->name == state.sOutputs) - handleOutputs(tokenizeString(s)); - else if (i->name == state.sJson) + if (i->name == state.sJson) { warn( "In derivation '%s': setting structured attributes via '__json' is deprecated, and may be disallowed in future versions of Nix. Set '__structuredAttrs = true' instead.", drvName); + drv.structuredAttrs = StructuredAttrs::parse(s); + } else { + drv.env.emplace(key, s); + if (i->name == state.sBuilder) + drv.builder = std::move(s); + else if (i->name == state.sSystem) + drv.platform = std::move(s); + else if (i->name == state.sOutputHash) + outputHash = std::move(s); + else if (i->name == state.sOutputHashAlgo) + outputHashAlgo = parseHashAlgoOpt(s); + else if (i->name == state.sOutputHashMode) + handleHashMode(s); + else if (i->name == state.sOutputs) + handleOutputs(tokenizeString(s)); + } } } @@ -1560,8 +1563,10 @@ static void derivationStrictInternal(EvalState & state, std::string_view drvName } if (jsonObject) { - drv.env.emplace("__json", jsonObject->dump()); - jsonObject.reset(); + /* The only other way `drv.structuredAttrs` can be set is when + `jsonObject` is not set. */ + assert(!drv.structuredAttrs); + drv.structuredAttrs = std::move(*jsonObject); } /* Everything in the context of the strings in the derivation diff --git a/src/libstore-tests/derivation-advanced-attrs.cc b/src/libstore-tests/derivation-advanced-attrs.cc index fbdf8ed29..37b422421 100644 --- a/src/libstore-tests/derivation-advanced-attrs.cc +++ b/src/libstore-tests/derivation-advanced-attrs.cc @@ -108,10 +108,9 @@ TYPED_TEST(DerivationAdvancedAttrsBothTest, advancedAttributes_defaults) auto drvPath = writeDerivation(*this->store, got, NoRepair, true); - auto parsedDrv = StructuredAttrs::tryParse(got.env); - DerivationOptions options = DerivationOptions::fromStructuredAttrs(got.env, parsedDrv ? &*parsedDrv : nullptr); + DerivationOptions options = DerivationOptions::fromStructuredAttrs(got.env, got.structuredAttrs); - EXPECT_TRUE(!parsedDrv); + EXPECT_TRUE(!got.structuredAttrs); EXPECT_EQ(options.additionalSandboxProfile, ""); EXPECT_EQ(options.noChroot, false); @@ -143,8 +142,7 @@ TEST_F(DerivationAdvancedAttrsTest, advancedAttributes_defaults) auto drvPath = writeDerivation(*this->store, got, NoRepair, true); - auto parsedDrv = StructuredAttrs::tryParse(got.env); - DerivationOptions options = DerivationOptions::fromStructuredAttrs(got.env, parsedDrv ? &*parsedDrv : nullptr); + DerivationOptions options = DerivationOptions::fromStructuredAttrs(got.env, got.structuredAttrs); EXPECT_EQ(options.getRequiredSystemFeatures(got), StringSet{}); }); @@ -157,8 +155,7 @@ TEST_F(CaDerivationAdvancedAttrsTest, advancedAttributes_defaults) auto drvPath = writeDerivation(*this->store, got, NoRepair, true); - auto parsedDrv = StructuredAttrs::tryParse(got.env); - DerivationOptions options = DerivationOptions::fromStructuredAttrs(got.env, parsedDrv ? &*parsedDrv : nullptr); + DerivationOptions options = DerivationOptions::fromStructuredAttrs(got.env, got.structuredAttrs); EXPECT_EQ(options.getRequiredSystemFeatures(got), StringSet{"ca-derivations"}); }); @@ -171,10 +168,9 @@ TYPED_TEST(DerivationAdvancedAttrsBothTest, advancedAttributes) auto drvPath = writeDerivation(*this->store, got, NoRepair, true); - auto parsedDrv = StructuredAttrs::tryParse(got.env); - DerivationOptions options = DerivationOptions::fromStructuredAttrs(got.env, parsedDrv ? &*parsedDrv : nullptr); + DerivationOptions options = DerivationOptions::fromStructuredAttrs(got.env, got.structuredAttrs); - EXPECT_TRUE(!parsedDrv); + EXPECT_TRUE(!got.structuredAttrs); EXPECT_EQ(options.additionalSandboxProfile, "sandcastle"); EXPECT_EQ(options.noChroot, true); @@ -195,8 +191,7 @@ TEST_F(DerivationAdvancedAttrsTest, advancedAttributes) auto drvPath = writeDerivation(*this->store, got, NoRepair, true); - auto parsedDrv = StructuredAttrs::tryParse(got.env); - DerivationOptions options = DerivationOptions::fromStructuredAttrs(got.env, parsedDrv ? &*parsedDrv : nullptr); + DerivationOptions options = DerivationOptions::fromStructuredAttrs(got.env, got.structuredAttrs); EXPECT_EQ( options.exportReferencesGraph, @@ -245,8 +240,7 @@ TEST_F(CaDerivationAdvancedAttrsTest, advancedAttributes) auto drvPath = writeDerivation(*this->store, got, NoRepair, true); - auto parsedDrv = StructuredAttrs::tryParse(got.env); - DerivationOptions options = DerivationOptions::fromStructuredAttrs(got.env, parsedDrv ? &*parsedDrv : nullptr); + DerivationOptions options = DerivationOptions::fromStructuredAttrs(got.env, got.structuredAttrs); EXPECT_EQ( options.exportReferencesGraph, @@ -298,10 +292,9 @@ TYPED_TEST(DerivationAdvancedAttrsBothTest, advancedAttributes_structuredAttrs_d auto drvPath = writeDerivation(*this->store, got, NoRepair, true); - auto parsedDrv = StructuredAttrs::tryParse(got.env); - DerivationOptions options = DerivationOptions::fromStructuredAttrs(got.env, parsedDrv ? &*parsedDrv : nullptr); + DerivationOptions options = DerivationOptions::fromStructuredAttrs(got.env, got.structuredAttrs); - EXPECT_TRUE(parsedDrv); + EXPECT_TRUE(got.structuredAttrs); EXPECT_EQ(options.additionalSandboxProfile, ""); EXPECT_EQ(options.noChroot, false); @@ -332,8 +325,7 @@ TEST_F(DerivationAdvancedAttrsTest, advancedAttributes_structuredAttrs_defaults) auto drvPath = writeDerivation(*this->store, got, NoRepair, true); - auto parsedDrv = StructuredAttrs::tryParse(got.env); - DerivationOptions options = DerivationOptions::fromStructuredAttrs(got.env, parsedDrv ? &*parsedDrv : nullptr); + DerivationOptions options = DerivationOptions::fromStructuredAttrs(got.env, got.structuredAttrs); EXPECT_EQ(options.getRequiredSystemFeatures(got), StringSet{}); }); @@ -346,8 +338,7 @@ TEST_F(CaDerivationAdvancedAttrsTest, advancedAttributes_structuredAttrs_default auto drvPath = writeDerivation(*this->store, got, NoRepair, true); - auto parsedDrv = StructuredAttrs::tryParse(got.env); - DerivationOptions options = DerivationOptions::fromStructuredAttrs(got.env, parsedDrv ? &*parsedDrv : nullptr); + DerivationOptions options = DerivationOptions::fromStructuredAttrs(got.env, got.structuredAttrs); EXPECT_EQ(options.getRequiredSystemFeatures(got), StringSet{"ca-derivations"}); }); @@ -360,10 +351,9 @@ TYPED_TEST(DerivationAdvancedAttrsBothTest, advancedAttributes_structuredAttrs) auto drvPath = writeDerivation(*this->store, got, NoRepair, true); - auto parsedDrv = StructuredAttrs::tryParse(got.env); - DerivationOptions options = DerivationOptions::fromStructuredAttrs(got.env, parsedDrv ? &*parsedDrv : nullptr); + DerivationOptions options = DerivationOptions::fromStructuredAttrs(got.env, got.structuredAttrs); - EXPECT_TRUE(parsedDrv); + EXPECT_TRUE(got.structuredAttrs); EXPECT_EQ(options.additionalSandboxProfile, "sandcastle"); EXPECT_EQ(options.noChroot, true); @@ -394,8 +384,7 @@ TEST_F(DerivationAdvancedAttrsTest, advancedAttributes_structuredAttrs) auto drvPath = writeDerivation(*this->store, got, NoRepair, true); - auto parsedDrv = StructuredAttrs::tryParse(got.env); - DerivationOptions options = DerivationOptions::fromStructuredAttrs(got.env, parsedDrv ? &*parsedDrv : nullptr); + DerivationOptions options = DerivationOptions::fromStructuredAttrs(got.env, got.structuredAttrs); EXPECT_EQ( options.exportReferencesGraph, @@ -448,8 +437,7 @@ TEST_F(CaDerivationAdvancedAttrsTest, advancedAttributes_structuredAttrs) auto drvPath = writeDerivation(*this->store, got, NoRepair, true); - auto parsedDrv = StructuredAttrs::tryParse(got.env); - DerivationOptions options = DerivationOptions::fromStructuredAttrs(got.env, parsedDrv ? &*parsedDrv : nullptr); + DerivationOptions options = DerivationOptions::fromStructuredAttrs(got.env, got.structuredAttrs); EXPECT_EQ( options.exportReferencesGraph, diff --git a/src/libstore-tests/derivation.cc b/src/libstore-tests/derivation.cc index 7d0507a7a..812e1d01b 100644 --- a/src/libstore-tests/derivation.cc +++ b/src/libstore-tests/derivation.cc @@ -222,7 +222,7 @@ Derivation makeSimpleDrv(const Store & store) "bar", "baz", }; - drv.env = { + drv.env = StringPairs{ { "BIG_BAD", "WOLF", @@ -284,7 +284,7 @@ Derivation makeDynDepDerivation(const Store & store) "bar", "baz", }; - drv.env = { + drv.env = StringPairs{ { "BIG_BAD", "WOLF", diff --git a/src/libstore/build/derivation-building-goal.cc b/src/libstore/build/derivation-building-goal.cc index e68e60250..bc8b35462 100644 --- a/src/libstore/build/derivation-building-goal.cc +++ b/src/libstore/build/derivation-building-goal.cc @@ -32,12 +32,9 @@ DerivationBuildingGoal::DerivationBuildingGoal( { drv = std::make_unique(drv_); - if (auto parsedOpt = StructuredAttrs::tryParse(drv->env)) { - parsedDrv = std::make_unique(*parsedOpt); - } try { drvOptions = - std::make_unique(DerivationOptions::fromStructuredAttrs(drv->env, parsedDrv.get())); + std::make_unique(DerivationOptions::fromStructuredAttrs(drv->env, drv->structuredAttrs)); } catch (Error & e) { e.addTrace({}, "while parsing derivation '%s'", worker.store.printStorePath(drvPath)); throw; @@ -661,7 +658,6 @@ Goal::Co DerivationBuildingGoal::tryToBuild() buildMode, buildResult, *drv, - parsedDrv.get(), *drvOptions, inputPaths, initialOutputs, diff --git a/src/libstore/build/derivation-goal.cc b/src/libstore/build/derivation-goal.cc index 55111e378..b2faa7a6e 100644 --- a/src/libstore/build/derivation-goal.cc +++ b/src/libstore/build/derivation-goal.cc @@ -63,9 +63,8 @@ Goal::Co DerivationGoal::haveDerivation() trace("have derivation"); auto drvOptions = [&]() -> DerivationOptions { - auto parsedOpt = StructuredAttrs::tryParse(drv->env); try { - return DerivationOptions::fromStructuredAttrs(drv->env, parsedOpt ? &*parsedOpt : nullptr); + return DerivationOptions::fromStructuredAttrs(drv->env, drv->structuredAttrs); } catch (Error & e) { e.addTrace({}, "while parsing derivation '%s'", worker.store.printStorePath(drvPath)); throw; diff --git a/src/libstore/derivation-options.cc b/src/libstore/derivation-options.cc index 07212289e..f1515c308 100644 --- a/src/libstore/derivation-options.cc +++ b/src/libstore/derivation-options.cc @@ -92,6 +92,12 @@ using OutputChecks = DerivationOptions::OutputChecks; using OutputChecksVariant = std::variant>; +DerivationOptions DerivationOptions::fromStructuredAttrs( + const StringMap & env, const std::optional & parsed, bool shouldWarn) +{ + return fromStructuredAttrs(env, parsed ? &*parsed : nullptr); +} + DerivationOptions DerivationOptions::fromStructuredAttrs(const StringMap & env, const StructuredAttrs * parsed, bool shouldWarn) { diff --git a/src/libstore/derivations.cc b/src/libstore/derivations.cc index 279713c71..30048c522 100644 --- a/src/libstore/derivations.cc +++ b/src/libstore/derivations.cc @@ -452,6 +452,7 @@ Derivation parseDerivation( expect(str, ")"); drv.env.insert_or_assign(std::move(name), std::move(value)); } + drv.structuredAttrs = StructuredAttrs::tryExtract(drv.env); expect(str, ")"); return drv; @@ -685,16 +686,28 @@ std::string Derivation::unparse( s += ",["; first = true; - for (auto & i : env) { - if (first) - first = false; - else + + auto unparseEnv = [&](const StringPairs atermEnv) { + for (auto & i : atermEnv) { + if (first) + first = false; + else + s += ','; + s += '('; + printString(s, i.first); s += ','; - s += '('; - printString(s, i.first); - s += ','; - printString(s, maskOutputs && outputs.count(i.first) ? "" : i.second); - s += ')'; + printString(s, maskOutputs && outputs.count(i.first) ? "" : i.second); + s += ')'; + } + }; + + StructuredAttrs::checkKeyNotInUse(env); + if (structuredAttrs) { + StringPairs scratch = env; + scratch.insert(structuredAttrs->unparse()); + unparseEnv(scratch); + } else { + unparseEnv(env); } s += "])"; @@ -948,6 +961,7 @@ Source & readDerivation(Source & in, const StoreDirConfig & store, BasicDerivati auto value = readString(in); drv.env[key] = value; } + drv.structuredAttrs = StructuredAttrs::tryExtract(drv.env); return in; } @@ -983,9 +997,21 @@ void writeDerivation(Sink & out, const StoreDirConfig & store, const BasicDeriva } CommonProto::write(store, CommonProto::WriteConn{.to = out}, drv.inputSrcs); out << drv.platform << drv.builder << drv.args; - out << drv.env.size(); - for (auto & i : drv.env) - out << i.first << i.second; + + auto writeEnv = [&](const StringPairs atermEnv) { + out << atermEnv.size(); + for (auto & [k, v] : atermEnv) + out << k << v; + }; + + StructuredAttrs::checkKeyNotInUse(drv.env); + if (drv.structuredAttrs) { + StringPairs scratch = drv.env; + scratch.insert(drv.structuredAttrs->unparse()); + writeEnv(scratch); + } else { + writeEnv(drv.env); + } } std::string hashPlaceholder(const OutputNameView outputName) @@ -1017,6 +1043,17 @@ void BasicDerivation::applyRewrites(const StringMap & rewrites) newEnv.emplace(envName, envValue); } env = std::move(newEnv); + + if (structuredAttrs) { + // TODO rewrite the JSON AST properly, rather than dump parse round trip. + auto [k, jsonS] = structuredAttrs->unparse(); + jsonS = rewriteStrings(jsonS, rewrites); + StringPairs newEnv; + newEnv.insert(std::pair{k, std::move(jsonS)}); + auto newStructuredAttrs = StructuredAttrs::tryExtract(newEnv); + assert(newStructuredAttrs); + structuredAttrs = std::move(*newStructuredAttrs); + } } static void rewriteDerivation(Store & store, BasicDerivation & drv, const StringMap & rewrites) @@ -1338,10 +1375,8 @@ nlohmann::json Derivation::toJSON(const StoreDirConfig & store) const res["args"] = args; res["env"] = env; - if (auto it = env.find("__json"); it != env.end()) { - res["env"].erase("__json"); - res["structuredAttrs"] = nlohmann::json::parse(it->second); - } + if (structuredAttrs) + res["structuredAttrs"] = structuredAttrs->structuredAttrs; return res; } @@ -1411,7 +1446,7 @@ Derivation Derivation::fromJSON( } if (auto structuredAttrs = get(json, "structuredAttrs")) - res.env.insert_or_assign("__json", structuredAttrs->dump()); + res.structuredAttrs = StructuredAttrs{*structuredAttrs}; return res; } diff --git a/src/libstore/include/nix/store/build/derivation-building-goal.hh b/src/libstore/include/nix/store/build/derivation-building-goal.hh index 66a934d49..029288998 100644 --- a/src/libstore/include/nix/store/build/derivation-building-goal.hh +++ b/src/libstore/include/nix/store/build/derivation-building-goal.hh @@ -1,8 +1,8 @@ #pragma once ///@file -#include "nix/store/parsed-derivations.hh" #include "nix/store/derivations.hh" +#include "nix/store/parsed-derivations.hh" #include "nix/store/derivation-options.hh" #include "nix/store/build/derivation-building-misc.hh" #include "nix/store/outputs-spec.hh" @@ -39,7 +39,6 @@ struct DerivationBuildingGoal : public Goal */ std::unique_ptr drv; - std::unique_ptr parsedDrv; std::unique_ptr drvOptions; /** diff --git a/src/libstore/include/nix/store/derivation-options.hh b/src/libstore/include/nix/store/derivation-options.hh index ff3693366..98517e904 100644 --- a/src/libstore/include/nix/store/derivation-options.hh +++ b/src/libstore/include/nix/store/derivation-options.hh @@ -176,6 +176,9 @@ struct DerivationOptions static DerivationOptions fromStructuredAttrs(const StringMap & env, const StructuredAttrs * parsed, bool shouldWarn = true); + static DerivationOptions + fromStructuredAttrs(const StringMap & env, const std::optional & parsed, bool shouldWarn = true); + /** * @param drv Must be the same derivation we parsed this from. In * the future we'll flip things around so a `BasicDerivation` has diff --git a/src/libstore/include/nix/store/derivations.hh b/src/libstore/include/nix/store/derivations.hh index 41cd179f4..18479b425 100644 --- a/src/libstore/include/nix/store/derivations.hh +++ b/src/libstore/include/nix/store/derivations.hh @@ -7,6 +7,7 @@ #include "nix/store/content-address.hh" #include "nix/util/repair-flag.hh" #include "nix/store/derived-path-map.hh" +#include "nix/store/parsed-derivations.hh" #include "nix/util/sync.hh" #include "nix/util/variant-wrapper.hh" @@ -286,7 +287,12 @@ struct BasicDerivation std::string platform; Path builder; Strings args; + /** + * Must not contain the key `__json`, at least in order to serialize to A-Term. + */ StringPairs env; + std::optional structuredAttrs; + std::string name; BasicDerivation() = default; diff --git a/src/libstore/include/nix/store/parsed-derivations.hh b/src/libstore/include/nix/store/parsed-derivations.hh index ecc2f7e61..2638a3500 100644 --- a/src/libstore/include/nix/store/parsed-derivations.hh +++ b/src/libstore/include/nix/store/parsed-derivations.hh @@ -18,7 +18,30 @@ struct StructuredAttrs { nlohmann::json structuredAttrs; - static std::optional tryParse(const StringPairs & env); + bool operator==(const StructuredAttrs &) const = default; + + /** + * Unconditionally parse from a JSON string. Used by `tryExtract`. + */ + static StructuredAttrs parse(const std::string & encoded); + + /** + * Like `tryParse`, but removes the env var which encoded the structured + * attrs from the map if one is found. + */ + static std::optional tryExtract(StringPairs & env); + + /** + * Opposite of `tryParse`, at least if one makes a map from this + * single key-value PR. + */ + std::pair unparse() const; + + /** + * Ensures that the structured attrs "env var" is not in used, so we + * are free to use it instead. + */ + static void checkKeyNotInUse(const StringPairs & env); nlohmann::json prepareStructuredAttrs( Store & store, diff --git a/src/libstore/misc.cc b/src/libstore/misc.cc index 7492204ce..c794f8d06 100644 --- a/src/libstore/misc.cc +++ b/src/libstore/misc.cc @@ -224,13 +224,11 @@ MissingPaths Store::queryMissing(const std::vector & targets) return; auto drv = make_ref(derivationFromPath(drvPath)); - auto parsedDrv = StructuredAttrs::tryParse(drv->env); DerivationOptions drvOptions; try { // FIXME: this is a lot of work just to get the value // of `allowSubstitutes`. - drvOptions = - DerivationOptions::fromStructuredAttrs(drv->env, parsedDrv ? &*parsedDrv : nullptr); + drvOptions = DerivationOptions::fromStructuredAttrs(drv->env, drv->structuredAttrs); } catch (Error & e) { e.addTrace({}, "while parsing derivation '%s'", printStorePath(drvPath)); throw; diff --git a/src/libstore/parsed-derivations.cc b/src/libstore/parsed-derivations.cc index 5c6deb87a..797230e97 100644 --- a/src/libstore/parsed-derivations.cc +++ b/src/libstore/parsed-derivations.cc @@ -8,20 +8,41 @@ namespace nix { -std::optional StructuredAttrs::tryParse(const StringPairs & env) +static constexpr std::string_view envVarName = "__json"; + +StructuredAttrs StructuredAttrs::parse(const std::string & encoded) +{ + try { + return StructuredAttrs{ + .structuredAttrs = nlohmann::json::parse(encoded), + }; + } catch (std::exception & e) { + throw Error("cannot process __json attribute: %s", e.what()); + } +} + +std::optional StructuredAttrs::tryExtract(StringPairs & env) { /* Parse the __json attribute, if any. */ - auto jsonAttr = env.find("__json"); + auto jsonAttr = env.find(envVarName); if (jsonAttr != env.end()) { - try { - return StructuredAttrs{ - .structuredAttrs = nlohmann::json::parse(jsonAttr->second), - }; - } catch (std::exception & e) { - throw Error("cannot process __json attribute: %s", e.what()); - } - } - return {}; + auto encoded = std::move(jsonAttr->second); + env.erase(jsonAttr); + return parse(encoded); + } else + return {}; +} + +std::pair StructuredAttrs::unparse() const +{ + return {envVarName, structuredAttrs.dump()}; +} + +void StructuredAttrs::checkKeyNotInUse(const StringPairs & env) +{ + if (env.count(envVarName)) + throw Error( + "Cannot have an environment variable named '__json'. This key is reserved for encoding structured attrs"); } static std::regex shVarName("[A-Za-z_][A-Za-z0-9_]*"); @@ -175,4 +196,5 @@ std::string StructuredAttrs::writeShell(const nlohmann::json & json) return jsonSh; } + } // namespace nix diff --git a/src/libstore/unix/build/derivation-builder.cc b/src/libstore/unix/build/derivation-builder.cc index d598e51d9..7bb4f3177 100644 --- a/src/libstore/unix/build/derivation-builder.cc +++ b/src/libstore/unix/build/derivation-builder.cc @@ -809,7 +809,7 @@ void DerivationBuilderImpl::startBuilder() writeStructuredAttrs(); /* Handle exportReferencesGraph(), if set. */ - if (!parsedDrv) { + if (!drv.structuredAttrs) { for (auto & [fileName, ss] : drvOptions.exportReferencesGraph) { StorePathSet storePathSet; for (auto & storePathS : ss) { @@ -1081,7 +1081,7 @@ void DerivationBuilderImpl::initEnv() /* In non-structured mode, set all bindings either directory in the environment or via a file, as specified by `DerivationOptions::passAsFile`. */ - if (!parsedDrv) { + if (!drv.structuredAttrs) { for (auto & i : drv.env) { if (drvOptions.passAsFile.find(i.first) == drvOptions.passAsFile.end()) { env[i.first] = i.second; @@ -1149,8 +1149,8 @@ void DerivationBuilderImpl::initEnv() void DerivationBuilderImpl::writeStructuredAttrs() { - if (parsedDrv) { - auto json = parsedDrv->prepareStructuredAttrs(store, drvOptions, inputPaths, drv.outputs); + if (drv.structuredAttrs) { + auto json = drv.structuredAttrs->prepareStructuredAttrs(store, drvOptions, inputPaths, drv.outputs); nlohmann::json rewritten; for (auto & [i, v] : json["outputs"].get()) { /* The placeholder must have a rewrite, so we use it to cover both the diff --git a/src/libstore/unix/include/nix/store/build/derivation-builder.hh b/src/libstore/unix/include/nix/store/build/derivation-builder.hh index eecad3daa..465b45197 100644 --- a/src/libstore/unix/include/nix/store/build/derivation-builder.hh +++ b/src/libstore/unix/include/nix/store/build/derivation-builder.hh @@ -27,15 +27,6 @@ struct DerivationBuilderParams */ const Derivation & drv; - /** - * The "structured attrs" of `drv`, if it has them. - * - * @todo this should be part of `Derivation`. - * - * @todo this should be renamed from `parsedDrv`. - */ - const StructuredAttrs * parsedDrv; - /** * The derivation options of `drv`. * @@ -63,14 +54,12 @@ struct DerivationBuilderParams const BuildMode & buildMode, BuildResult & buildResult, const Derivation & drv, - const StructuredAttrs * parsedDrv, const DerivationOptions & drvOptions, const StorePathSet & inputPaths, std::map & initialOutputs) : drvPath{drvPath} , buildResult{buildResult} , drv{drv} - , parsedDrv{parsedDrv} , drvOptions{drvOptions} , inputPaths{inputPaths} , initialOutputs{initialOutputs} diff --git a/src/nix-build/nix-build.cc b/src/nix-build/nix-build.cc index d61a2f282..d3902f2a6 100644 --- a/src/nix-build/nix-build.cc +++ b/src/nix-build/nix-build.cc @@ -555,10 +555,9 @@ static void main_nix_build(int argc, char ** argv) env["NIX_STORE"] = store->storeDir; env["NIX_BUILD_CORES"] = fmt("%d", settings.buildCores ? settings.buildCores : settings.getDefaultCores()); - auto parsedDrv = StructuredAttrs::tryParse(drv.env); DerivationOptions drvOptions; try { - drvOptions = DerivationOptions::fromStructuredAttrs(drv.env, parsedDrv ? &*parsedDrv : nullptr); + drvOptions = DerivationOptions::fromStructuredAttrs(drv.env, drv.structuredAttrs); } catch (Error & e) { e.addTrace({}, "while parsing derivation '%s'", store->printStorePath(packageInfo.requireDrvPath())); throw; @@ -577,7 +576,7 @@ static void main_nix_build(int argc, char ** argv) std::string structuredAttrsRC; - if (parsedDrv) { + if (drv.structuredAttrs) { StorePathSet inputs; std::function::ChildNode &)> accumInputClosure; @@ -596,7 +595,7 @@ static void main_nix_build(int argc, char ** argv) for (const auto & [inputDrv, inputNode] : drv.inputDrvs.map) accumInputClosure(inputDrv, inputNode); - auto json = parsedDrv->prepareStructuredAttrs(*store, drvOptions, inputs, drv.outputs); + auto json = drv.structuredAttrs->prepareStructuredAttrs(*store, drvOptions, inputs, drv.outputs); structuredAttrsRC = StructuredAttrs::writeShell(json);