1
1
Fork 0
mirror of https://github.com/NixOS/nix.git synced 2025-11-09 03:56:01 +01:00

Store StructuredAttrs directly in Derivation

Instead of parsing a structured attrs at some later point, we parsed it
right away when parsing the A-Term format, and likewise serialize it to
`__json = <JSON dump>` when serializing a derivation to A-Term.

The JSON format can directly contain the JSON structured attrs without
so encoding it, so we just do that.
This commit is contained in:
John Ericson 2025-05-25 20:01:20 -04:00
parent b062730665
commit 8652b6b417
16 changed files with 177 additions and 109 deletions

View file

@ -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<json> jsonObject;
std::optional<StructuredAttrs> 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<Strings>(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<Strings>(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