Fix derivation computation with __structuredAttrs and multiple outputs

Fixes

  error: derivation '/nix/store/klivma7r7h5lndb99f7xxmlh5whyayvg-zlib-1.2.11.drv' has incorrect output '/nix/store/fv98nnx5ykgbq8sqabilkgkbc4169q05-zlib-1.2.11-dev', should be '/nix/store/adm7pilzlj3z5k249s8b4wv3scprhzi1-zlib-1.2.11-dev'
This commit is contained in:
Eelco Dolstra 2020-01-21 21:14:13 +01:00
parent 8b09105db3
commit aef635da78
7 changed files with 27 additions and 27 deletions

View file

@ -731,6 +731,8 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * *
the hash. */ the hash. */
for (auto & i : outputs) { for (auto & i : outputs) {
if (!jsonObject) drv.env[i] = ""; if (!jsonObject) drv.env[i] = "";
drv.outputs.insert_or_assign(i,
DerivationOutput(StorePath::dummy.clone(), "", ""));
} }
Hash h = hashDerivationModulo(*state.store, Derivation(drv), true); Hash h = hashDerivationModulo(*state.store, Derivation(drv), true);

View file

@ -246,30 +246,18 @@ string Derivation::unparse(const Store & store, bool maskOutputs,
s.reserve(65536); s.reserve(65536);
s += "Derive(["; s += "Derive([";
StringSet maskedOutputs; bool first = true;
for (auto & i : outputs) {
if (maskOutputs) { if (first) first = false; else s += ',';
bool first = true; s += '('; printString(s, i.first);
maskedOutputs = tokenizeString<StringSet>(get(env, "outputs").value_or("out"), " "); s += ','; printString(s, maskOutputs ? "" : store.printStorePath(i.second.path));
for (auto & i : maskedOutputs) { s += ','; printString(s, i.second.hashAlgo);
if (first) first = false; else s += ','; s += ','; printString(s, i.second.hash);
s += '('; printString(s, i); s += ')';
s += ",\"\",\"\",\"\")";
}
} else {
bool first = true;
for (auto & i : outputs) {
if (first) first = false; else s += ',';
s += '('; printString(s, i.first);
s += ','; printString(s, store.printStorePath(i.second.path));
s += ','; printString(s, i.second.hashAlgo);
s += ','; printString(s, i.second.hash);
s += ')';
}
} }
s += "],["; s += "],[";
bool first = true; first = true;
if (actualInputs) { if (actualInputs) {
for (auto & i : *actualInputs) { for (auto & i : *actualInputs) {
if (first) first = false; else s += ','; if (first) first = false; else s += ',';
@ -299,7 +287,7 @@ string Derivation::unparse(const Store & store, bool maskOutputs,
for (auto & i : env) { for (auto & i : env) {
if (first) first = false; else s += ','; if (first) first = false; else s += ',';
s += '('; printString(s, i.first); s += '('; printString(s, i.first);
s += ','; printString(s, maskOutputs && maskedOutputs.count(i.first) ? "" : i.second); s += ','; printString(s, maskOutputs && outputs.count(i.first) ? "" : i.second);
s += ')'; s += ')';
} }

View file

@ -4,7 +4,7 @@
namespace nix { namespace nix {
NarInfo::NarInfo(const Store & store, const std::string & s, const std::string & whence) NarInfo::NarInfo(const Store & store, const std::string & s, const std::string & whence)
: ValidPathInfo(StorePath::make((unsigned char *) "xxxxxxxxxxxxxxxxxxxx", "x")) // FIXME: hack : ValidPathInfo(StorePath::dummy.clone()) // FIXME: hack
{ {
auto corrupt = [&]() { auto corrupt = [&]() {
throw Error(format("NAR info file '%1%' is corrupt") % whence); throw Error(format("NAR info file '%1%' is corrupt") % whence);

View file

@ -46,12 +46,15 @@ std::string_view StorePath::name() const
return ffi_StorePath_name(*this); return ffi_StorePath_name(*this);
} }
StorePath StorePath::dummy(
StorePath::make(
(unsigned char *) "xxxxxxxxxxxxxxxxxxxx", "x"));
StorePath Store::parseStorePath(std::string_view path) const StorePath Store::parseStorePath(std::string_view path) const
{ {
return StorePath::make(path, storeDir); return StorePath::make(path, storeDir);
} }
StorePathSet Store::parseStorePathSet(const PathSet & paths) const StorePathSet Store::parseStorePathSet(const PathSet & paths) const
{ {
StorePathSet res; StorePathSet res;

View file

@ -53,6 +53,8 @@ struct StorePath : rust::Value<3 * sizeof(void *) + 24, ffi_StorePath_drop>
{ {
return ffi_StorePath_hash_data(*this); return ffi_StorePath_hash_data(*this);
} }
static StorePath dummy;
}; };
typedef std::set<StorePath> StorePathSet; typedef std::set<StorePath> StorePathSet;

View file

@ -16,6 +16,8 @@ mkDerivation {
__structuredAttrs = true; __structuredAttrs = true;
outputs = [ "out" "dev" ];
buildCommand = '' buildCommand = ''
set -x set -x
@ -30,8 +32,9 @@ mkDerivation {
[[ -v nothing ]] [[ -v nothing ]]
[[ -z $nothing ]] [[ -z $nothing ]]
mkdir ''${outputs[out]} mkdir ''${outputs[out]} ''${outputs[dev]}
echo bar > $dest echo bar > $dest
echo foo > $dest2
json=$(cat .attrs.json) json=$(cat .attrs.json)
[[ $json =~ '"narHash":"sha256:1r7yc43zqnzl5b0als5vnyp649gk17i37s7mj00xr8kc47rjcybk"' ]] [[ $json =~ '"narHash":"sha256:1r7yc43zqnzl5b0als5vnyp649gk17i37s7mj00xr8kc47rjcybk"' ]]
@ -57,6 +60,7 @@ mkDerivation {
nothing = null; nothing = null;
dest = "${placeholder "out"}/foo"; dest = "${placeholder "out"}/foo";
dest2 = "${placeholder "dev"}/foo";
"foo bar" = "BAD"; "foo bar" = "BAD";
"1foobar" = "BAD"; "1foobar" = "BAD";

View file

@ -2,6 +2,7 @@ source common.sh
clearStore clearStore
outPath=$(nix-build structured-attrs.nix --no-out-link) nix-build structured-attrs.nix -A all -o $TEST_ROOT/result
[[ $(cat $outPath/foo) = bar ]] [[ $(cat $TEST_ROOT/result/foo) = bar ]]
[[ $(cat $TEST_ROOT/result-dev/foo) = foo ]]