1
0
Fork 0
mirror of https://github.com/NixOS/nix synced 2025-06-27 12:41:15 +02:00

Derivations can output "text-hashed" data

In particular, this means that derivations can output derivations. But
that ramification isn't (yet!) useful as we would want, since there is
no way to have a dependent derivation that is itself a dependent
derivation.
This commit is contained in:
John Ericson 2020-10-12 23:51:23 +00:00
parent a0f369aa3f
commit a4e5de1b9d
15 changed files with 322 additions and 137 deletions

View file

@ -851,7 +851,7 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * *
bool contentAddressed = false;
std::optional<std::string> outputHash;
std::string outputHashAlgo;
auto ingestionMethod = FileIngestionMethod::Flat;
ContentAddressMethod ingestionMethod = FileIngestionMethod::Flat;
StringSet outputs;
outputs.insert("out");
@ -864,6 +864,7 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * *
auto handleHashMode = [&](const std::string & s) {
if (s == "recursive") ingestionMethod = FileIngestionMethod::Recursive;
else if (s == "flat") ingestionMethod = FileIngestionMethod::Flat;
else if (s == "text") ingestionMethod = TextHashMethod {};
else
throw EvalError({
.hint = hintfmt("invalid value '%s' for 'outputHashMode' attribute", s),
@ -995,8 +996,11 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * *
state.store->computeFSClosure(state.store->parseStorePath(std::string_view(path).substr(1)), refs);
for (auto & j : refs) {
drv.inputSrcs.insert(j);
if (j.isDerivation())
drv.inputDrvs[j] = state.store->readDerivation(j).outputNames();
if (j.isDerivation()) {
Derivation jDrv = state.store->readDerivation(j);
if(jDrv.type() != DerivationType::CAFloating)
drv.inputDrvs[j] = jDrv.outputNames();
}
}
}
@ -1025,9 +1029,9 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * *
});
/* Check whether the derivation name is valid. */
if (isDerivation(drvName))
if (isDerivation(drvName) && ingestionMethod != ContentAddressMethod { TextHashMethod { } })
throw EvalError({
.hint = hintfmt("derivation names are not allowed to end in '%s'", drvExtension),
.hint = hintfmt("derivation names are allowed to end in '%s' only if they produce a single derivation file", drvExtension),
.errPos = posDrvName
});
@ -1045,22 +1049,16 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * *
std::optional<HashType> ht = parseHashTypeOpt(outputHashAlgo);
Hash h = newHashAllowEmpty(*outputHash, ht);
auto outPath = state.store->makeFixedOutputPath(drvName, FixedOutputInfo {
{
.method = ingestionMethod,
.hash = h,
},
{},
});
drv.env["out"] = state.store->printStorePath(outPath);
drv.outputs.insert_or_assign("out", DerivationOutput {
.output = DerivationOutputCAFixed {
.hash = FixedOutputHash {
.method = ingestionMethod,
.hash = std::move(h),
},
},
});
// FIXME non-trivial fixed refs set
auto ca = contentAddressFromMethodHashAndRefs(
ingestionMethod,
std::move(h),
{});
DerivationOutputCAFixed dof { .ca = ca };
drv.env["out"] = state.store->printStorePath(dof.path(*state.store, drvName, "out"));
drv.outputs.insert_or_assign("out", DerivationOutput { .output = dof });
}
else if (contentAddressed) {