mirror of
https://github.com/NixOS/nix
synced 2025-06-24 18:01:16 +02:00
Merge d850983f1d
into f9afc1e68c
This commit is contained in:
commit
0d24c96ddb
16 changed files with 183 additions and 101 deletions
|
@ -1267,14 +1267,16 @@ static void derivationStrictInternal(
|
|||
|
||||
/* 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() &&
|
||||
state.forceBool(*attr->value, 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;
|
||||
|
@ -1383,7 +1385,7 @@ static void derivationStrictInternal(
|
|||
|
||||
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);
|
||||
|
@ -1420,6 +1422,10 @@ static void derivationStrictInternal(
|
|||
|
||||
} else {
|
||||
auto s = state.coerceToString(pos, *i->value, context, context_below, true).toOwned();
|
||||
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);
|
||||
|
@ -1428,8 +1434,7 @@ static void derivationStrictInternal(
|
|||
else if (i->name == state.sOutputHashMode) handleHashMode(s);
|
||||
else if (i->name == state.sOutputs)
|
||||
handleOutputs(tokenizeString<Strings>(s));
|
||||
else 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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1442,8 +1447,10 @@ static void derivationStrictInternal(
|
|||
}
|
||||
|
||||
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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -220,7 +220,7 @@ Derivation makeSimpleDrv(const Store & store) {
|
|||
"bar",
|
||||
"baz",
|
||||
};
|
||||
drv.env = {
|
||||
drv.env = StringPairs{
|
||||
{
|
||||
"BIG_BAD",
|
||||
"WOLF",
|
||||
|
@ -278,7 +278,7 @@ Derivation makeDynDepDerivation(const Store & store) {
|
|||
"bar",
|
||||
"baz",
|
||||
};
|
||||
drv.env = {
|
||||
drv.env = StringPairs{
|
||||
{
|
||||
"BIG_BAD",
|
||||
"WOLF",
|
||||
|
|
|
@ -32,12 +32,9 @@ DerivationBuildingGoal::DerivationBuildingGoal(const StorePath & drvPath, const
|
|||
{
|
||||
drv = std::make_unique<Derivation>(drv_);
|
||||
|
||||
if (auto parsedOpt = StructuredAttrs::tryParse(drv->env)) {
|
||||
parsedDrv = std::make_unique<StructuredAttrs>(*parsedOpt);
|
||||
}
|
||||
try {
|
||||
drvOptions = std::make_unique<DerivationOptions>(
|
||||
DerivationOptions::fromStructuredAttrs(drv->env, parsedDrv.get()));
|
||||
DerivationOptions::fromStructuredAttrs(drv->env, drv->structuredAttrs));
|
||||
} catch (Error & e) {
|
||||
e.addTrace({}, "while parsing derivation '%s'", worker.store.printStorePath(drvPath));
|
||||
throw;
|
||||
|
@ -628,7 +625,6 @@ Goal::Co DerivationBuildingGoal::tryToBuild()
|
|||
buildMode,
|
||||
buildResult,
|
||||
*drv,
|
||||
parsedDrv.get(),
|
||||
*drvOptions,
|
||||
inputPaths,
|
||||
initialOutputs,
|
||||
|
|
|
@ -173,9 +173,8 @@ Goal::Co DerivationGoal::haveDerivation(StorePath drvPath)
|
|||
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;
|
||||
|
|
|
@ -92,6 +92,12 @@ using OutputChecks = DerivationOptions::OutputChecks;
|
|||
|
||||
using OutputChecksVariant = std::variant<OutputChecks, std::map<std::string, OutputChecks>>;
|
||||
|
||||
DerivationOptions DerivationOptions::fromStructuredAttrs(
|
||||
const StringMap & env, const std::optional<StructuredAttrs> & parsed, bool shouldWarn)
|
||||
{
|
||||
return fromStructuredAttrs(env, parsed ? &*parsed : nullptr);
|
||||
}
|
||||
|
||||
DerivationOptions
|
||||
DerivationOptions::fromStructuredAttrs(const StringMap & env, const StructuredAttrs * parsed, bool shouldWarn)
|
||||
{
|
||||
|
|
|
@ -460,6 +460,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;
|
||||
|
@ -650,12 +651,24 @@ std::string Derivation::unparse(const StoreDirConfig & store, bool maskOutputs,
|
|||
|
||||
s += ",[";
|
||||
first = true;
|
||||
for (auto & i : env) {
|
||||
|
||||
auto unparseEnv = [&](const StringPairs atermEnv) {
|
||||
for (auto & i : atermEnv) {
|
||||
if (first) first = false; else s += ',';
|
||||
s += '('; printString(s, i.first);
|
||||
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 += "])";
|
||||
|
||||
|
@ -953,6 +966,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;
|
||||
}
|
||||
|
@ -995,9 +1009,21 @@ void writeDerivation(Sink & out, const StoreDirConfig & store, const BasicDeriva
|
|||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1027,6 +1053,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::tryParse(newEnv);
|
||||
assert(newStructuredAttrs);
|
||||
structuredAttrs = std::move(*newStructuredAttrs);
|
||||
}
|
||||
}
|
||||
|
||||
static void rewriteDerivation(Store & store, BasicDerivation & drv, const StringMap & rewrites)
|
||||
|
@ -1333,10 +1370,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;
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
@ -41,7 +41,6 @@ struct DerivationBuildingGoal : public Goal
|
|||
*/
|
||||
std::unique_ptr<Derivation> drv;
|
||||
|
||||
std::unique_ptr<StructuredAttrs> parsedDrv;
|
||||
std::unique_ptr<DerivationOptions> drvOptions;
|
||||
|
||||
/**
|
||||
|
|
|
@ -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<StructuredAttrs> & 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
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
@ -294,7 +295,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> structuredAttrs;
|
||||
|
||||
std::string name;
|
||||
|
||||
BasicDerivation() = default;
|
||||
|
|
|
@ -18,8 +18,37 @@ struct StructuredAttrs
|
|||
{
|
||||
nlohmann::json structuredAttrs;
|
||||
|
||||
bool operator==(const StructuredAttrs &) const = default;
|
||||
|
||||
/**
|
||||
* Unconditionally parse from a JSON string. Used by `tryParse`.
|
||||
*/
|
||||
static StructuredAttrs parse(const std::string & encoded);
|
||||
|
||||
/**
|
||||
* Parse structured attrs from one of the env vars, as is used by the ATerm
|
||||
* format.
|
||||
*/
|
||||
static std::optional<StructuredAttrs> tryParse(const StringPairs & env);
|
||||
|
||||
/**
|
||||
* Like `tryParse`, but removes the env var which encoded the structured
|
||||
* attrs from the map if one is found.
|
||||
*/
|
||||
static std::optional<StructuredAttrs> tryExtract(StringPairs & env);
|
||||
|
||||
/**
|
||||
* Opposite of `tryParse`, at least if one makes a map from this
|
||||
* single key-value PR.
|
||||
*/
|
||||
std::pair<std::string_view, std::string> 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,
|
||||
const DerivationOptions & drvOptions,
|
||||
|
|
|
@ -222,14 +222,11 @@ void Store::queryMissing(const std::vector<DerivedPath> & targets,
|
|||
if (knownOutputPaths && invalid.empty()) return;
|
||||
|
||||
auto drv = make_ref<Derivation>(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;
|
||||
|
|
|
@ -8,22 +8,52 @@
|
|||
|
||||
namespace nix {
|
||||
|
||||
std::optional<StructuredAttrs> StructuredAttrs::tryParse(const StringPairs & env)
|
||||
static constexpr std::string_view envVarName = "__json";
|
||||
|
||||
StructuredAttrs StructuredAttrs::parse(const std::string & encoded)
|
||||
{
|
||||
/* Parse the __json attribute, if any. */
|
||||
auto jsonAttr = env.find("__json");
|
||||
if (jsonAttr != env.end()) {
|
||||
try {
|
||||
return StructuredAttrs {
|
||||
.structuredAttrs = nlohmann::json::parse(jsonAttr->second),
|
||||
.structuredAttrs = nlohmann::json::parse(encoded),
|
||||
};
|
||||
} catch (std::exception & e) {
|
||||
throw Error("cannot process __json attribute: %s", e.what());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<StructuredAttrs> StructuredAttrs::tryParse(const StringPairs & env)
|
||||
{
|
||||
/* Parse the __json attribute, if any. */
|
||||
auto jsonAttr = env.find(envVarName);
|
||||
if (jsonAttr != env.end())
|
||||
return parse(jsonAttr->second);
|
||||
else
|
||||
return {};
|
||||
}
|
||||
|
||||
std::optional<StructuredAttrs> StructuredAttrs::tryExtract(StringPairs & env)
|
||||
{
|
||||
/* Parse the __json attribute, if any. */
|
||||
auto jsonAttr = env.find(envVarName);
|
||||
if (jsonAttr != env.end()) {
|
||||
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_]*");
|
||||
|
||||
/**
|
||||
|
@ -170,4 +200,5 @@ std::string StructuredAttrs::writeShell(const nlohmann::json & json)
|
|||
|
||||
return jsonSh;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -773,7 +773,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) {
|
||||
|
@ -1042,7 +1042,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;
|
||||
|
@ -1113,8 +1113,8 @@ void DerivationBuilderImpl::initEnv()
|
|||
|
||||
void DerivationBuilderImpl::writeStructuredAttrs()
|
||||
{
|
||||
if (parsedDrv) {
|
||||
auto json = parsedDrv->prepareStructuredAttrs(
|
||||
if (drv.structuredAttrs) {
|
||||
auto json = drv.structuredAttrs->prepareStructuredAttrs(
|
||||
store,
|
||||
drvOptions,
|
||||
inputPaths,
|
||||
|
|
|
@ -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<std::string, InitialOutput> & initialOutputs)
|
||||
: drvPath{drvPath}
|
||||
, buildResult{buildResult}
|
||||
, drv{drv}
|
||||
, parsedDrv{parsedDrv}
|
||||
, drvOptions{drvOptions}
|
||||
, inputPaths{inputPaths}
|
||||
, initialOutputs{initialOutputs}
|
||||
|
|
|
@ -544,12 +544,9 @@ static void main_nix_build(int argc, char * * argv)
|
|||
env["NIX_STORE"] = store->storeDir;
|
||||
env["NIX_BUILD_CORES"] = std::to_string(settings.buildCores);
|
||||
|
||||
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;
|
||||
|
@ -568,7 +565,7 @@ static void main_nix_build(int argc, char * * argv)
|
|||
|
||||
std::string structuredAttrsRC;
|
||||
|
||||
if (parsedDrv) {
|
||||
if (drv.structuredAttrs) {
|
||||
StorePathSet inputs;
|
||||
|
||||
std::function<void(const StorePath &, const DerivedPathMap<StringSet>::ChildNode &)> accumInputClosure;
|
||||
|
@ -586,7 +583,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(
|
||||
auto json = drv.structuredAttrs->prepareStructuredAttrs(
|
||||
*store,
|
||||
drvOptions,
|
||||
inputs,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue