1
1
Fork 0
mirror of https://github.com/NixOS/nix.git synced 2025-11-30 06:01:00 +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

@ -8,20 +8,41 @@
namespace nix {
std::optional<StructuredAttrs> 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> 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<std::string_view, std::string> 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