From aef635da78d33bf679f49fd10e7130d918a82549 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 21 Jan 2020 21:14:13 +0100 Subject: [PATCH] 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' --- src/libexpr/primops.cc | 2 ++ src/libstore/derivations.cc | 32 ++++++++++---------------------- src/libstore/nar-info.cc | 2 +- src/libstore/path.cc | 5 ++++- src/libstore/path.hh | 2 ++ tests/structured-attrs.nix | 6 +++++- tests/structured-attrs.sh | 5 +++-- 7 files changed, 27 insertions(+), 27 deletions(-) diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index 3ef827ebc..29302c9b6 100644 --- a/src/libexpr/primops.cc +++ b/src/libexpr/primops.cc @@ -731,6 +731,8 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * * the hash. */ for (auto & i : outputs) { if (!jsonObject) drv.env[i] = ""; + drv.outputs.insert_or_assign(i, + DerivationOutput(StorePath::dummy.clone(), "", "")); } Hash h = hashDerivationModulo(*state.store, Derivation(drv), true); diff --git a/src/libstore/derivations.cc b/src/libstore/derivations.cc index 1a061149a..d9da8769c 100644 --- a/src/libstore/derivations.cc +++ b/src/libstore/derivations.cc @@ -246,30 +246,18 @@ string Derivation::unparse(const Store & store, bool maskOutputs, s.reserve(65536); s += "Derive(["; - StringSet maskedOutputs; - - if (maskOutputs) { - bool first = true; - maskedOutputs = tokenizeString(get(env, "outputs").value_or("out"), " "); - for (auto & i : maskedOutputs) { - if (first) first = false; else s += ','; - s += '('; printString(s, i); - 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 += ')'; - } + bool first = true; + for (auto & i : outputs) { + if (first) first = false; else s += ','; + s += '('; printString(s, i.first); + s += ','; printString(s, maskOutputs ? "" : store.printStorePath(i.second.path)); + s += ','; printString(s, i.second.hashAlgo); + s += ','; printString(s, i.second.hash); + s += ')'; } s += "],["; - bool first = true; + first = true; if (actualInputs) { for (auto & i : *actualInputs) { if (first) first = false; else s += ','; @@ -299,7 +287,7 @@ string Derivation::unparse(const Store & store, bool maskOutputs, for (auto & i : env) { if (first) first = false; else s += ','; 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 += ')'; } diff --git a/src/libstore/nar-info.cc b/src/libstore/nar-info.cc index fb02cf3fd..1375094b5 100644 --- a/src/libstore/nar-info.cc +++ b/src/libstore/nar-info.cc @@ -4,7 +4,7 @@ namespace nix { 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 = [&]() { throw Error(format("NAR info file '%1%' is corrupt") % whence); diff --git a/src/libstore/path.cc b/src/libstore/path.cc index cda5f9968..a33bec3ed 100644 --- a/src/libstore/path.cc +++ b/src/libstore/path.cc @@ -46,12 +46,15 @@ std::string_view StorePath::name() const return ffi_StorePath_name(*this); } +StorePath StorePath::dummy( + StorePath::make( + (unsigned char *) "xxxxxxxxxxxxxxxxxxxx", "x")); + StorePath Store::parseStorePath(std::string_view path) const { return StorePath::make(path, storeDir); } - StorePathSet Store::parseStorePathSet(const PathSet & paths) const { StorePathSet res; diff --git a/src/libstore/path.hh b/src/libstore/path.hh index 5ebb57480..6b29c3566 100644 --- a/src/libstore/path.hh +++ b/src/libstore/path.hh @@ -53,6 +53,8 @@ struct StorePath : rust::Value<3 * sizeof(void *) + 24, ffi_StorePath_drop> { return ffi_StorePath_hash_data(*this); } + + static StorePath dummy; }; typedef std::set StorePathSet; diff --git a/tests/structured-attrs.nix b/tests/structured-attrs.nix index 6c77a4391..c39c3a346 100644 --- a/tests/structured-attrs.nix +++ b/tests/structured-attrs.nix @@ -16,6 +16,8 @@ mkDerivation { __structuredAttrs = true; + outputs = [ "out" "dev" ]; + buildCommand = '' set -x @@ -30,8 +32,9 @@ mkDerivation { [[ -v nothing ]] [[ -z $nothing ]] - mkdir ''${outputs[out]} + mkdir ''${outputs[out]} ''${outputs[dev]} echo bar > $dest + echo foo > $dest2 json=$(cat .attrs.json) [[ $json =~ '"narHash":"sha256:1r7yc43zqnzl5b0als5vnyp649gk17i37s7mj00xr8kc47rjcybk"' ]] @@ -57,6 +60,7 @@ mkDerivation { nothing = null; dest = "${placeholder "out"}/foo"; + dest2 = "${placeholder "dev"}/foo"; "foo bar" = "BAD"; "1foobar" = "BAD"; diff --git a/tests/structured-attrs.sh b/tests/structured-attrs.sh index 9ba2672b6..646bdb876 100644 --- a/tests/structured-attrs.sh +++ b/tests/structured-attrs.sh @@ -2,6 +2,7 @@ source common.sh 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 ]]