This is a small application to run hooks for each package and ebuild phase in Gentoo's package manager Portage.
The idea is similar to Arch Linux pacman libalpm, but you can write actual scripts which are run, instead of a primitive config file with some commands in it. Also the layout is much cleaner than in libalpm so you don't get lost finding your custom hooks again.
What this hook runner can't do for you is to run scripts based on files which were modified. You need a fixed package name.
- Get build dependencies
- D Compiler (tested with LDC2)
- CMake (latest from Gentoo repos)
- Compile with CMake as usual
mkdir build && cd build
cmake -DCMAKE_BUILD_TYPE=Release ..
cmake --build .
The binary can be found under build/bin
.
Put this snippet in your Portage bashrc
(/etc/portage/bashrc
):
# invoke emerge hook trigger for each package and ebuild phase (except depend)
# hooks are stored in /etc/portage/hooks
if [[ ! -z "$EBUILD_PHASE" && "$EBUILD_PHASE" != "depend" ]]; then
echo -e "\e[1m>>> \e[38;2;120;120;39m[${CATEGORY}/${PN}]\e[0m\e[1m Running ebuild phase \e[38;2;48;90;116m$EBUILD_PHASE\e[0m\e[1m...\e[0m"
portage-hook-ctrl --pkg "${CATEGORY}/${PN}" --phase "$EBUILD_PHASE" --run
if (( $? != 0 )); then
die "\e[1mhook for [${CATEGORY}/${PN}][$EBUILD_PHASE] terminated with an error\e[0m"
fi
fi
Create a directory hooks
inside your Portage config directory.
The directory structure of hooks is the same as in the repositories with a package category and name.
The hook script must be located inside the correct category directory and
must be the exact package name. Make sure that the executable bit is set
on all hooks, otherwise they will not run. This is also a nice way to toggle
hooks without renaming the file. Alongside the hook script you must also
place a hook definition file. The filename is the package name with the
.hook
file extension added. The file contains a list of supported ebuild
phases by your script. Only phases listed in this file will be executed
with your script.
You can write your hooks in whatever scripting or programming language you
want. The first argument which is passed to your hook is the current ebuild
phase. You can obtain the ebuild phase names from the $EBUILD_PHASE
env
var as seen above in the bashrc snippet.
A list of ebuild phases invoked in exactly that order:
pretend
(verifying ebuild manifests, not sure about that phase as it isn't run for every package)clean
setup
unpack
(executed before thesrc_unpack
function)prepare
(executed before thesrc_prepare
function)configure
(executed before thesrc_configure
function)compile
(executed before thesrc_compile
function)test
(executed before running unit tests)install
(executed before thesrc_install
function)instprep
(prepare the installation image before merged into the system, the env var$ED
points to theDESTDIR
of the package, useful to remove unneeded files and bloat)preinst
prerm
postrm
cleanrm
postinst
(executed after the package is merged into the system)clean
Note that the clean phase is run twice.
ALL HOOKS ARE ALWAYS RUN BEFORE THE NATIVE EBUILD FUNCTIONS! If you need to run a hook after ebuild does its own stuff you need to hack in the script at the next ebuild phase and hope for the best.
If you need examples you can take a look here.
A typical shell script hook would look like this:
#!/bin/sh
postinst() {
echo doing some stuff with the installed files from package
}
case "$1" in
postinst) postinst ;;
*) : ;;
esac