mirror of
https://github.com/NixOS/nix.git
synced 2025-11-16 07:22:43 +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:
parent
b062730665
commit
8652b6b417
16 changed files with 177 additions and 109 deletions
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue