Skip to content

Commit

Permalink
Merge pull request #7283 from hercules-ci/issue-6572
Browse files Browse the repository at this point in the history
Fix #6572 `requires non-existent output`
  • Loading branch information
thufschmitt committed Nov 15, 2022
2 parents daf1423 + c279ddb commit 3ade5f5
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 6 deletions.
30 changes: 24 additions & 6 deletions src/libstore/build/derivation-goal.cc
Original file line number Diff line number Diff line change
Expand Up @@ -528,13 +528,31 @@ void DerivationGoal::inputsRealised()
/* Add the relevant output closures of the input derivation
`i' as input paths. Only add the closures of output paths
that are specified as inputs. */
for (auto & j : wantedDepOutputs)
if (auto outPath = get(inputDrvOutputs, { depDrvPath, j }))
for (auto & j : wantedDepOutputs) {
/* TODO (impure derivations-induced tech debt):
Tracking input derivation outputs statefully through the
goals is error prone and has led to bugs.
For a robust nix, we need to move towards the `else` branch,
which does not rely on goal state to match up with the
reality of the store, which is our real source of truth.
However, the impure derivations feature still relies on this
fragile way of doing things, because its builds do not have
a representation in the store, which is a usability problem
in itself */
if (auto outPath = get(inputDrvOutputs, { depDrvPath, j })) {
worker.store.computeFSClosure(*outPath, inputPaths);
else
throw Error(
"derivation '%s' requires non-existent output '%s' from input derivation '%s'",
worker.store.printStorePath(drvPath), j, worker.store.printStorePath(depDrvPath));
}
else {
auto outMap = worker.evalStore.queryDerivationOutputMap(depDrvPath);
auto outMapPath = outMap.find(j);
if (outMapPath == outMap.end()) {
throw Error(
"derivation '%s' requires non-existent output '%s' from input derivation '%s'",
worker.store.printStorePath(drvPath), j, worker.store.printStorePath(depDrvPath));
}
worker.store.computeFSClosure(outMapPath->second, inputPaths);
}
}
}
}

Expand Down
51 changes: 51 additions & 0 deletions tests/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,54 @@ testNormalization () {
}

testNormalization

# https://github.com/NixOS/nix/issues/6572
issue_6572_independent_outputs() {
nix build -f multiple-outputs.nix --json independent --no-link > $TEST_ROOT/independent.json

# Make sure that 'nix build' can build a derivation that depends on both outputs of another derivation.
p=$(nix build -f multiple-outputs.nix use-independent --no-link --print-out-paths)
nix-store --delete "$p" # Clean up for next test

# Make sure that 'nix build' tracks input-outputs correctly when a single output is already present.
nix-store --delete "$(jq -r <$TEST_ROOT/independent.json .[0].outputs.first)"
p=$(nix build -f multiple-outputs.nix use-independent --no-link --print-out-paths)
cmp $p <<EOF
first
second
EOF
nix-store --delete "$p" # Clean up for next test

# Make sure that 'nix build' tracks input-outputs correctly when a single output is already present.
nix-store --delete "$(jq -r <$TEST_ROOT/independent.json .[0].outputs.second)"
p=$(nix build -f multiple-outputs.nix use-independent --no-link --print-out-paths)
cmp $p <<EOF
first
second
EOF
nix-store --delete "$p" # Clean up for next test
}
issue_6572_independent_outputs


# https://github.com/NixOS/nix/issues/6572
issue_6572_dependent_outputs() {

nix build -f multiple-outputs.nix --json a --no-link > $TEST_ROOT/a.json

# # Make sure that 'nix build' can build a derivation that depends on both outputs of another derivation.
p=$(nix build -f multiple-outputs.nix use-a --no-link --print-out-paths)
nix-store --delete "$p" # Clean up for next test

# Make sure that 'nix build' tracks input-outputs correctly when a single output is already present.
nix-store --delete "$(jq -r <$TEST_ROOT/a.json .[0].outputs.second)"
p=$(nix build -f multiple-outputs.nix use-a --no-link --print-out-paths)
cmp $p <<EOF
first
second
EOF
nix-store --delete "$p" # Clean up for next test
}
if isDaemonNewer "2.12pre0"; then
issue_6572_dependent_outputs
fi
30 changes: 30 additions & 0 deletions tests/multiple-outputs.nix
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,15 @@ rec {
helloString = "Hello, world!";
};

use-a = mkDerivation {
name = "use-a";
inherit (a) first second;
builder = builtins.toFile "builder.sh"
''
cat $first/file $second/file >$out
'';
};

b = mkDerivation {
defaultOutput = assert a.second.helloString == "Hello, world!"; a;
firstOutput = assert a.outputName == "first"; a.first.first;
Expand Down Expand Up @@ -87,4 +96,25 @@ rec {
buildCommand = "mkdir $a $b $c";
};

independent = mkDerivation {
name = "multiple-outputs-independent";
outputs = [ "first" "second" ];
builder = builtins.toFile "builder.sh"
''
mkdir $first $second
test -z $all
echo "first" > $first/file
echo "second" > $second/file
'';
};

use-independent = mkDerivation {
name = "use-independent";
inherit (a) first second;
builder = builtins.toFile "builder.sh"
''
cat $first/file $second/file >$out
'';
};

}

0 comments on commit 3ade5f5

Please sign in to comment.