Allow multiple hooks with the same name
You can now register multiple values per named hook, e.g. addHook preConfigure "echo foo" addHook preConfigure "echo bar" will cause ‘runHook preConfigure’ to run both ‘echo foo’ and ‘echo bar’ (in that order). It will also call the shell function preConfigure() or eval the shell variable $preConfigure, if defined. Thus, if you don't call addHook, it works like the old hook mechanism. Allowing multiple hooks makes stdenv more modular and extensible. For instance, multiple setup hooks can define a preFixup hook, and all of these will be executed.
This commit is contained in:
parent
18e422d047
commit
b0f2d3419c
@ -1,8 +1,38 @@
|
||||
# Run the named hook, either by calling the function with that name or
|
||||
# by evaluating the variable with that name. This allows convenient
|
||||
# setting of hooks both from Nix expressions (as attributes /
|
||||
# environment variables) and from shell scripts (as functions).
|
||||
######################################################################
|
||||
# Hook handling.
|
||||
|
||||
|
||||
# Add the specified shell code to the named hook, e.g. ‘addHook
|
||||
# preConfigure "rm ./foo; touch ./bar"’.
|
||||
addHook() {
|
||||
local hookName="$1"
|
||||
local hookCode="$2"
|
||||
eval "_${hookName}_hooks+=(\"\$hookCode\")"
|
||||
}
|
||||
|
||||
|
||||
# Run all hooks with the specified name in the order in which they
|
||||
# were added, stopping if any fails (returns a non-zero exit
|
||||
# code). Hooks are added using ‘addHooks <hookName> <code>’, or
|
||||
# implicitly by defining a shell function or variable <hookName>. Note
|
||||
# that the latter takes precedence over hooks added via ‘addHooks’.
|
||||
runHook() {
|
||||
local hookName="$1"
|
||||
local var="_${hookName}_hooks"
|
||||
eval "local -a dummy=(\"\${_${hookName}_hooks[@]}\")"
|
||||
for hook in "runSingleHook $hookName" "${dummy[@]}"; do
|
||||
if ! _eval "$hook"; then return 1; fi
|
||||
done
|
||||
return 0
|
||||
}
|
||||
|
||||
|
||||
# Run the named hook, either by calling the function with that name or
|
||||
# by evaluating the variable with that name. This allows convenient
|
||||
# setting of hooks both from Nix expressions (as attributes /
|
||||
# environment variables) and from shell scripts (as functions). If you
|
||||
# want to allow multiple hooks, use runHook instead.
|
||||
runSingleHook() {
|
||||
local hookName="$1"
|
||||
case "$(type -t $hookName)" in
|
||||
(function|alias|builtin) $hookName;;
|
||||
@ -13,6 +43,17 @@ runHook() {
|
||||
}
|
||||
|
||||
|
||||
# A function wrapper around ‘eval’ that ensures that ‘return’ inside
|
||||
# hooks exits the hook, not the caller.
|
||||
_eval() {
|
||||
local code="$1"
|
||||
eval "$code"
|
||||
}
|
||||
|
||||
|
||||
######################################################################
|
||||
# Error handling.
|
||||
|
||||
exitHandler() {
|
||||
exitCode=$?
|
||||
set +e
|
||||
@ -467,7 +508,7 @@ unpackFile() {
|
||||
echo "source archive $curSrc has unknown type"
|
||||
exit 1
|
||||
fi
|
||||
runHook unpackCmd
|
||||
runSingleHook unpackCmd
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
@ -505,7 +546,7 @@ unpackPhase() {
|
||||
|
||||
# Find the source directory.
|
||||
if [ -n "$setSourceRoot" ]; then
|
||||
runHook setSourceRoot
|
||||
runSingleHook setSourceRoot
|
||||
elif [ -z "$sourceRoot" ]; then
|
||||
sourceRoot=
|
||||
for i in *; do
|
||||
|
Loading…
Reference in New Issue
Block a user