forked from lix-project/lix
Merge pull request #7721 from yorickvP/post-build-hook
Also pass unwanted outputs to post-build-hook
This commit is contained in:
commit
85ff212051
|
@ -1020,43 +1020,33 @@ void DerivationGoal::resolvedFinished()
|
||||||
|
|
||||||
StorePathSet outputPaths;
|
StorePathSet outputPaths;
|
||||||
|
|
||||||
// `wantedOutputs` might merely indicate “all the outputs”
|
for (auto & outputName : resolvedDrv.outputNames()) {
|
||||||
auto realWantedOutputs = std::visit(overloaded {
|
auto initialOutput = get(initialOutputs, outputName);
|
||||||
[&](const OutputsSpec::All &) {
|
auto resolvedHash = get(resolvedHashes, outputName);
|
||||||
return resolvedDrv.outputNames();
|
|
||||||
},
|
|
||||||
[&](const OutputsSpec::Names & names) {
|
|
||||||
return static_cast<std::set<std::string>>(names);
|
|
||||||
},
|
|
||||||
}, wantedOutputs.raw());
|
|
||||||
|
|
||||||
for (auto & wantedOutput : realWantedOutputs) {
|
|
||||||
auto initialOutput = get(initialOutputs, wantedOutput);
|
|
||||||
auto resolvedHash = get(resolvedHashes, wantedOutput);
|
|
||||||
if ((!initialOutput) || (!resolvedHash))
|
if ((!initialOutput) || (!resolvedHash))
|
||||||
throw Error(
|
throw Error(
|
||||||
"derivation '%s' doesn't have expected output '%s' (derivation-goal.cc/resolvedFinished,resolve)",
|
"derivation '%s' doesn't have expected output '%s' (derivation-goal.cc/resolvedFinished,resolve)",
|
||||||
worker.store.printStorePath(drvPath), wantedOutput);
|
worker.store.printStorePath(drvPath), outputName);
|
||||||
|
|
||||||
auto realisation = [&]{
|
auto realisation = [&]{
|
||||||
auto take1 = get(resolvedResult.builtOutputs, wantedOutput);
|
auto take1 = get(resolvedResult.builtOutputs, outputName);
|
||||||
if (take1) return *take1;
|
if (take1) return *take1;
|
||||||
|
|
||||||
/* The above `get` should work. But sateful tracking of
|
/* The above `get` should work. But sateful tracking of
|
||||||
outputs in resolvedResult, this can get out of sync with the
|
outputs in resolvedResult, this can get out of sync with the
|
||||||
store, which is our actual source of truth. For now we just
|
store, which is our actual source of truth. For now we just
|
||||||
check the store directly if it fails. */
|
check the store directly if it fails. */
|
||||||
auto take2 = worker.evalStore.queryRealisation(DrvOutput { *resolvedHash, wantedOutput });
|
auto take2 = worker.evalStore.queryRealisation(DrvOutput { *resolvedHash, outputName });
|
||||||
if (take2) return *take2;
|
if (take2) return *take2;
|
||||||
|
|
||||||
throw Error(
|
throw Error(
|
||||||
"derivation '%s' doesn't have expected output '%s' (derivation-goal.cc/resolvedFinished,realisation)",
|
"derivation '%s' doesn't have expected output '%s' (derivation-goal.cc/resolvedFinished,realisation)",
|
||||||
worker.store.printStorePath(resolvedDrvGoal->drvPath), wantedOutput);
|
worker.store.printStorePath(resolvedDrvGoal->drvPath), outputName);
|
||||||
}();
|
}();
|
||||||
|
|
||||||
if (drv->type().isPure()) {
|
if (drv->type().isPure()) {
|
||||||
auto newRealisation = realisation;
|
auto newRealisation = realisation;
|
||||||
newRealisation.id = DrvOutput { initialOutput->outputHash, wantedOutput };
|
newRealisation.id = DrvOutput { initialOutput->outputHash, outputName };
|
||||||
newRealisation.signatures.clear();
|
newRealisation.signatures.clear();
|
||||||
if (!drv->type().isFixed())
|
if (!drv->type().isFixed())
|
||||||
newRealisation.dependentRealisations = drvOutputReferences(worker.store, *drv, realisation.outPath);
|
newRealisation.dependentRealisations = drvOutputReferences(worker.store, *drv, realisation.outPath);
|
||||||
|
@ -1064,7 +1054,7 @@ void DerivationGoal::resolvedFinished()
|
||||||
worker.store.registerDrvOutput(newRealisation);
|
worker.store.registerDrvOutput(newRealisation);
|
||||||
}
|
}
|
||||||
outputPaths.insert(realisation.outPath);
|
outputPaths.insert(realisation.outPath);
|
||||||
builtOutputs.emplace(wantedOutput, realisation);
|
builtOutputs.emplace(outputName, realisation);
|
||||||
}
|
}
|
||||||
|
|
||||||
runPostBuildHook(
|
runPostBuildHook(
|
||||||
|
@ -1406,7 +1396,7 @@ std::pair<bool, SingleDrvOutputs> DerivationGoal::checkPathValidity()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (info.wanted && info.known && info.known->isValid())
|
if (info.known && info.known->isValid())
|
||||||
validOutputs.emplace(i.first, Realisation { drvOutput, info.known->path });
|
validOutputs.emplace(i.first, Realisation { drvOutput, info.known->path });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1457,8 +1447,9 @@ void DerivationGoal::done(
|
||||||
mcRunningBuilds.reset();
|
mcRunningBuilds.reset();
|
||||||
|
|
||||||
if (buildResult.success()) {
|
if (buildResult.success()) {
|
||||||
assert(!builtOutputs.empty());
|
auto wantedBuiltOutputs = filterDrvOutputs(wantedOutputs, std::move(builtOutputs));
|
||||||
buildResult.builtOutputs = std::move(builtOutputs);
|
assert(!wantedBuiltOutputs.empty());
|
||||||
|
buildResult.builtOutputs = std::move(wantedBuiltOutputs);
|
||||||
if (status == BuildResult::Built)
|
if (status == BuildResult::Built)
|
||||||
worker.doneBuilds++;
|
worker.doneBuilds++;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -306,15 +306,13 @@ struct DerivationGoal : public Goal
|
||||||
* Update 'initialOutputs' to determine the current status of the
|
* Update 'initialOutputs' to determine the current status of the
|
||||||
* outputs of the derivation. Also returns a Boolean denoting
|
* outputs of the derivation. Also returns a Boolean denoting
|
||||||
* whether all outputs are valid and non-corrupt, and a
|
* whether all outputs are valid and non-corrupt, and a
|
||||||
* 'SingleDrvOutputs' structure containing the valid and wanted
|
* 'SingleDrvOutputs' structure containing the valid outputs.
|
||||||
* outputs.
|
|
||||||
*/
|
*/
|
||||||
std::pair<bool, SingleDrvOutputs> checkPathValidity();
|
std::pair<bool, SingleDrvOutputs> checkPathValidity();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Aborts if any output is not valid or corrupt, and otherwise
|
* Aborts if any output is not valid or corrupt, and otherwise
|
||||||
* returns a 'SingleDrvOutputs' structure containing the wanted
|
* returns a 'SingleDrvOutputs' structure containing all outputs.
|
||||||
* outputs.
|
|
||||||
*/
|
*/
|
||||||
SingleDrvOutputs assertPathValidity();
|
SingleDrvOutputs assertPathValidity();
|
||||||
|
|
||||||
|
|
|
@ -2701,8 +2701,7 @@ SingleDrvOutputs LocalDerivationGoal::registerOutputs()
|
||||||
signRealisation(thisRealisation);
|
signRealisation(thisRealisation);
|
||||||
worker.store.registerDrvOutput(thisRealisation);
|
worker.store.registerDrvOutput(thisRealisation);
|
||||||
}
|
}
|
||||||
if (wantedOutputs.contains(outputName))
|
builtOutputs.emplace(outputName, thisRealisation);
|
||||||
builtOutputs.emplace(outputName, thisRealisation);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return builtOutputs;
|
return builtOutputs;
|
||||||
|
|
|
@ -136,6 +136,19 @@ size_t Realisation::checkSignatures(const PublicKeys & publicKeys) const
|
||||||
return good;
|
return good;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SingleDrvOutputs filterDrvOutputs(const OutputsSpec& wanted, SingleDrvOutputs&& outputs)
|
||||||
|
{
|
||||||
|
SingleDrvOutputs ret = std::move(outputs);
|
||||||
|
for (auto it = ret.begin(); it != ret.end(); ) {
|
||||||
|
if (!wanted.contains(it->first))
|
||||||
|
it = ret.erase(it);
|
||||||
|
else
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
StorePath RealisedPath::path() const {
|
StorePath RealisedPath::path() const {
|
||||||
return std::visit([](auto && arg) { return arg.getPath(); }, raw);
|
return std::visit([](auto && arg) { return arg.getPath(); }, raw);
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
class Store;
|
class Store;
|
||||||
|
struct OutputsSpec;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A general `Realisation` key.
|
* A general `Realisation` key.
|
||||||
|
@ -93,6 +94,14 @@ typedef std::map<std::string, Realisation> SingleDrvOutputs;
|
||||||
*/
|
*/
|
||||||
typedef std::map<DrvOutput, Realisation> DrvOutputs;
|
typedef std::map<DrvOutput, Realisation> DrvOutputs;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filter a SingleDrvOutputs to include only specific output names
|
||||||
|
*
|
||||||
|
* Moves the `outputs` input.
|
||||||
|
*/
|
||||||
|
SingleDrvOutputs filterDrvOutputs(const OutputsSpec&, SingleDrvOutputs&&);
|
||||||
|
|
||||||
|
|
||||||
struct OpaquePath {
|
struct OpaquePath {
|
||||||
StorePath path;
|
StorePath path;
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,10 @@ fi
|
||||||
|
|
||||||
# Build the dependencies and push them to the remote store.
|
# Build the dependencies and push them to the remote store.
|
||||||
nix-build -o $TEST_ROOT/result dependencies.nix --post-build-hook "$pushToStore"
|
nix-build -o $TEST_ROOT/result dependencies.nix --post-build-hook "$pushToStore"
|
||||||
|
# See if all outputs are passed to the post-build hook by only specifying one
|
||||||
|
# We're not able to test CA tests this way
|
||||||
|
export BUILD_HOOK_ONLY_OUT_PATHS=$([ ! $NIX_TESTS_CA_BY_DEFAULT ])
|
||||||
|
nix-build -o $TEST_ROOT/result-mult multiple-outputs.nix -A a.first --post-build-hook "$pushToStore"
|
||||||
|
|
||||||
clearStore
|
clearStore
|
||||||
|
|
||||||
|
@ -24,3 +28,4 @@ clearStore
|
||||||
# closure of what we've just built.
|
# closure of what we've just built.
|
||||||
nix copy --from "$REMOTE_STORE" --no-require-sigs -f dependencies.nix
|
nix copy --from "$REMOTE_STORE" --no-require-sigs -f dependencies.nix
|
||||||
nix copy --from "$REMOTE_STORE" --no-require-sigs -f dependencies.nix input1_drv
|
nix copy --from "$REMOTE_STORE" --no-require-sigs -f dependencies.nix input1_drv
|
||||||
|
nix copy --from "$REMOTE_STORE" --no-require-sigs -f multiple-outputs.nix a^second
|
||||||
|
|
|
@ -7,4 +7,8 @@ set -e
|
||||||
[ -n "$DRV_PATH" ]
|
[ -n "$DRV_PATH" ]
|
||||||
|
|
||||||
echo Pushing "$OUT_PATHS" to "$REMOTE_STORE"
|
echo Pushing "$OUT_PATHS" to "$REMOTE_STORE"
|
||||||
printf "%s" "$DRV_PATH" | xargs nix copy --to "$REMOTE_STORE" --no-require-sigs
|
if [ -n "$BUILD_HOOK_ONLY_OUT_PATHS" ]; then
|
||||||
|
printf "%s" "$OUT_PATHS" | xargs nix copy --to "$REMOTE_STORE" --no-require-sigs
|
||||||
|
else
|
||||||
|
printf "%s" "$DRV_PATH" | xargs nix copy --to "$REMOTE_STORE" --no-require-sigs
|
||||||
|
fi
|
||||||
|
|
|
@ -7,4 +7,8 @@ set -e
|
||||||
[ -n "$DRV_PATH" ]
|
[ -n "$DRV_PATH" ]
|
||||||
|
|
||||||
echo Pushing "$OUT_PATHS" to "$REMOTE_STORE"
|
echo Pushing "$OUT_PATHS" to "$REMOTE_STORE"
|
||||||
printf "%s" "$DRV_PATH"^'*' | xargs nix copy --to "$REMOTE_STORE" --no-require-sigs
|
if [ -n "$BUILD_HOOK_ONLY_OUT_PATHS" ]; then
|
||||||
|
printf "%s" "$OUT_PATHS" | xargs nix copy --to "$REMOTE_STORE" --no-require-sigs
|
||||||
|
else
|
||||||
|
printf "%s" "$DRV_PATH"^'*' | xargs nix copy --to "$REMOTE_STORE" --no-require-sigs
|
||||||
|
fi
|
||||||
|
|
Loading…
Reference in a new issue