Hooks
Overview
This document describes the Paludis hooks interface. A hook is a piece of code that is executed when a particular well defined action occurs.
There are currently four categories of hooks:
- General hooks. These have access to a limited environment. If a hook returns a non-zero exit code, the action will be aborted. See General Hooks.
- Ebuild phase hooks. These have ebuildin the hook name, and have full access to the ebuild environment (including the ability to calldie), but are only used for ebuild-based activities. See Ebuild Phase Hooks.
- Ebuild message hooks. These are special hooks that are called for
    einfo,ewarnetc. See Ebuild Message Hooks.
- Merger / Unmerger hooks. These are used when installing and uninstalling content to the live filesystem. If a check hook returns a non-zero exit code, the action will be aborted. See Merger / Unmerger Hooks.
There are currently five categories of hook execution code:
- .bashhooks. These are simple- .bashfiles that are executed with a particular environment. See Bash Hooks for details.
- .hookhooks. These are also- bashfiles, but rather than containing the relevant code in global scope, they make use of functions to perform hook actions. They also support specifying execution order dependencies upon other hooks. See Hook Hooks for details.
- .pyhooks. These are much like .hook hooks, but written in Python and with additional power given by Python bindings and access to the current Environment. See Python Hooks for details.
- .sohooks. These are written in C++ and compiled into shared libraries, and run inside the Paludis process. See .so Hooks for details.
- Repository hooks. These are implemented internally by Repositoryclasses.
Not all hook execution code methods are available for all hook categories. The following table indicates availability:
| .bash | .hook | .py | .so | Repository | |
|---|---|---|---|---|---|
| General | yes | yes | yes | yes | yes | 
| Ebuild Phase | yes | ||||
| Ebuild Message | yes | ||||
| Merger | yes | yes | yes | yes | yes | 
Where there is a choice, .hook hooks should be favoured over .bash
hooks.
Available Hooks
General Hooks
The following general normal hooks are available:
- install_pre
- install_fail
- install_post
- install_all_pre
- install_all_post
- install_pretend_pre
- install_pretend_post
- install_pretend_display_item_pre
- install_pretend_display_item_post
- install_task_execute_pre
- install_task_execute_post
- uninstall_pre
- uninstall_fail
- uninstall_post
- uninstall_all_pre
- uninstall_all_post
- clean_pre
- clean_post
- clean_fail
- clean_all_pre
- clean_all_post
- sync_pre
- sync_fail
- sync_post
- sync_all_pre
- sync_all_post
- fetch_pre
- fetch_post
- fetch_all_pre
- fetch_all_post
In general, certain special environment variables will be set:
- HOOKwill contain the name of the hook.
- For allhooks,TARGETSwill contain the targets for the operation.
- For non-allhooks,TARGETwill contain the current target.
- The PALUDIS_CMDLINEvariables described below are also available.
- For the install_pretend_display_itemhooks, theKINDvariable will also be of interest.
- For the install_task_execute_preandinstall_task_execute_posthooks,PRETEND,FETCH_ONLYandSUCCESSmay be useful.
Ebuild Phase Hooks
The following ebuild phase hooks are available:
- ebuild_metadata_pre
- ebuild_metadata_fail
- ebuild_metadata_post
- ebuild_variable_pre
- ebuild_variable_fail
- ebuild_variable_post
- ebuild_init_pre
- ebuild_init_fail
- ebuild_init_post
- ebuild_initmisc_pre
- ebuild_initmisc_fail
- ebuild_initmisc_post
- ebuild_fetch_extra_pre
- ebuild_fetch_extra_fail
- ebuild_fetch_extra_post
- ebuild_tidyup_pre
- ebuild_tidyup_fail
- ebuild_tidyup_post
- ebuild_unpack_pre
- ebuild_unpack_fail
- ebuild_unpack_post
- ebuild_prepare_pre
- ebuild_prepare_fail
- ebuild_prepare_post
- ebuild_configure_pre
- ebuild_configure_fail
- ebuild_configure_post
- ebuild_compile_pre
- ebuild_compile_fail
- ebuild_compile_post
- ebuild_install_pre
- ebuild_install_fail
- ebuild_install_post
- ebuild_test_pre
- ebuild_test_fail
- ebuild_test_post
- ebuild_test_expensive_pre
- ebuild_test_expensive_fail
- ebuild_test_expensive_post
- ebuild_pretend_pre
- ebuild_pretend_fail
- ebuild_pretend_post
- ebuild_bad_options_pre
- ebuild_bad_options_fail
- ebuild_bad_options_post
- ebuild_bad_required_use_pre
- ebuild_bad_required_use_fail
- ebuild_bad_required_use_post
- ebuild_setup_pre
- ebuild_setup_fail
- ebuild_setup_post
- ebuild_config_pre
- ebuild_config_fail
- ebuild_config_post
- ebuild_nofetch_pre
- ebuild_nofetch_fail
- ebuild_nofetch_post
- ebuild_preinst_pre
- ebuild_preinst_fail
- ebuild_preinst_post
- ebuild_postinst_pre
- ebuild_postinst_fail
- ebuild_postinst_post
- ebuild_prerm_pre
- ebuild_prerm_fail
- ebuild_prerm_post
- ebuild_postrm_pre
- ebuild_postrm_fail
- ebuild_postrm_post
- ebuild_info_pre
- ebuild_info_fail
- ebuild_info_post
- ebuild_infovars_pre
- ebuild_infovars_fail
- ebuild_infovars_post
- ebuild_pivotbin_pre
- ebuild_pivotbin_fail
- ebuild_pivotbin_post
- ebuild_installbin_pre
- ebuild_installbin_fail
- ebuild_installbin_post
- ebuild_saveenv_pre
- ebuild_saveenv_fail
- ebuild_saveenv_post
- ebuild_loadenv_pre
- ebuild_loadenv_fail
- ebuild_loadenv_post
- ebuild_killold_pre
- ebuild_killold_fail
- ebuild_killold_post
- ebuild_tidyup_pre
- ebuild_tidyup_fail
- ebuild_tidyup_post
These are called before and after the corresponding src_,
pkg_ or builtin_ phase functions (in particular,
note src_configure versus pkg_config).
As well as the full ebuild environment, the HOOK environment
variable will contain the name of the hook being called. The
PALUDIS_CMDLINE variables described below are also available.
Ebuild hooks will not necessarily be called if an ebuild does not define the function in question.
Ebuild Message Hooks
The following ebuild message hooks are available:
- einfo
- ewarn
- eerror
- elog
The HOOK environment variable will contain the name of the hook
being called, and the MESSAGE environment variable will contain
the message being passed to the function.  The PALUDIS_CMDLINE
variables described below are also available.
Merger / Unmerger Hooks
The merger runs in two stages, for safety. First it checks that it can probably install safely, then it does the actual install. Note that calculating the md5, timestamp etc for VDB CONTENTS is done after the install_post hooks are called.
In each of the following subcategories, the hooks that do not name a specific type of object are called before or after the entire process; those that do are called once for each relevant item.
The following merger check hooks are available:
- merger_check_pre
- merger_check_post
- merger_check_file_pre
- merger_check_file_post
- merger_check_sym_pre
- merger_check_sym_post
- merger_check_dir_pre
- merger_check_dir_post
The INSTALL_SOURCE and INSTALL_DESTINATION
environment variables contain the target source and destination. The
ROOT variable contains the filesystem root. The IMAGE
variable contains the image root.
The following merger hooks are available:
- merger_install_pre
- merger_install_post
- merger_install_file_pre
- merger_install_file_post
- merger_install_sym_pre
- merger_install_sym_post
- merger_install_dir_pre
- merger_install_dir_post
- merger_unlink_file_pre
- merger_unlink_file_post
- merger_unlink_dir_pre
- merger_unlink_dir_post
- merger_unlink_sym_pre
- merger_unlink_sym_post
- merger_unlink_misc_pre
- merger_unlink_misc_post
Again, ROOT and IMAGE are available. For
install hooks, INSTALL_SOURCE, INSTALL_DESTINATION are
set, and for uninstall hooks, UNLINK_TARGET.
The unmerger hooks are used for uninstalling a package, but not when existing things have to be removed for an install (the merger does that). The following unmerger hooks are available:
- unmerger_unlink_pre
- unmerger_unlink_post
- unmerger_unlink_file_pre
- unmerger_unlink_file_post
- unmerger_unlink_dir_pre
- unmerger_unlink_dir_post
- unmerger_unlink_sym_pre
- unmerger_unlink_sym_post
- unmerger_unlink_misc_pre
- unmerger_unlink_misc_post
The UNLINK_TARGET environment variable specifies the file about
to be unlinked, and ROOT is the filesystem root.
User Defined Hooks
User defined hooks should be files named *.bash, *.hook,
*.py or *.so. .bash and .hook
scripts should be executable (chmod a+x). They can live in three locations
(or be symlinked there, to allow a single script to be shared between hooks):
- confdir/hooks/hookname/, where- confdiris the directory in which- use.confet al. reside.
- DATADIR/paludis/hooks/hookname/. On most systems,- DATADIRis- /usr/share.
- LIBEXECDIR/paludis/hooks/hookname/. On most systems,- LIBEXECDIRis- /usr/libexec.
For .hook and .so hooks, rather than using hookname, the
auto directory may be used. In this case, Paludis will ask the hook for which hook names it should be
run.
Bash Hooks
A .bash hook is merely executed when the associated action is
triggered. There is no guarantee as to execution order.
Hook Hooks
A .hook hook is more powerful. It must not run anything in
global scope, but instead defines all its actions in functions. It must, at
minimum, define a function called hook_run_$HOOK for each hook
that it can handle. It may also define functions called hook_depend_$HOOK,
which should output names of any other hooks upon which it depends, and
hook_after_$HOOK, which is similar but indicates an ordering
rather than hard dependency (the named hooks not existing is not an error).
For example:
#!/usr/bin/env bash
hook_run_install_all_post()
{
    # ensure that einfo etc are available
    export PATH="$(${PALUDIS_EBUILD_DIR}/utils/canonicalise ${PALUDIS_EBUILD_DIR}/utils/ ):${PATH}"
    source ${PALUDIS_EBUILD_DIR}/echo_functions.bash
    echo
    einfo "Checking for monkeys..."
    if [[ -d "${ROOT}/var/lib/monkeys" ]] ; then
        for m in "${ROOT}"/var/lib/monkeys/* ; do
            ewarn "Found monkey $(basename "${m}" )"
        done
    else
        einfo "No monkeys found"
    fi
}
hook_depend_install_all_post()
{
    # we need to run after the Paludis standard eselect_env_update hook
    echo eselect_env_update
}
hook_after_install_all_post()
{
    # if checking for rabbits or squirrels, do those first
    echo check_for_rabbits check_for_squirrels
}
If the hook is located in an auto directory, the hook_auto_names function must also be
provided. This function should output the hook names under which the hook should be run. For example:
hook_auto_names() {
    echo install_all_pre install_all_post
}
Note that the hook_depend_, hook_after_ and hook_auto_names functions are
cached, and are generally only called once per session, so the output should not vary based upon outside parameters.
Python Hooks
A .py hook is much like .hook hook, but written
in Python and with full access to the current Paludis environment through
Python bindings. For each hook it can handle it must, at minimum, define
a function named hook_run_$HOOK which accepts exactly two positional
arguments: the current Environment used by Paludis, and the additional Hook environment variables
represented by a Python dictionary. It may also define the hook_depend_$HOOK
and hook_after_$HOOK functions which must take exactly one argument,
the Hook environment, and return a list of strings.
For example:
def hook_run_install_all_post(env, hook_env):
    from paludis import *
    print "* Checking for monkeys..."
    if list(env[Selection.SomeArbitraryVersion(Generator.Package("nice/monkey"))]):
        print "Found a monkey!"
    else:
        print "No monkeys found"
def hook_depend_install_all_post(hook_env):
    # we need to run after the Paludis standard eselect_env_update hook
    return ["eselect_env_update"]
def hook_after_install_all_post(hook_env):
    # if checking for rabbits or squirrels, do those first
    return ["check_for_rabbits", "check_for_squirrels"]
.so Hooks
A .so hook is written in C++ and has full access to the Paludis public API.
The hook takes the form of a shared library with a filename ending in .so.N,
where N is the first component of the Paludis version number multiplied by 100,
plus the second component of the version number (for example, 26 for Paludis 0.26.x,
or 102 for Paludis 1.2.y).  The library must export a function with prototype
paludis::HookResult paludis_hook_run_3(const paludis::Environment *,
    const paludis::Hook &, const std::shared_ptr<paludis::OutputManager> &)
that performs the action, and optionally one with prototype
void paludis_hook_add_dependencies(const paludis::Environment *, const paludis::Hook &,
    paludis::DirectedGraph<std::string, int> &)
if it needs to define ordering dependencies with other hooks. If the hook is to be placed in an auto
directory, it must also define const std::tr1::shared_ptr<const Sequence<std::string> >
paludis_hook_auto_phases(const paludis::Environment *). All functions are
declared in the header <paludis/hook.hh>, including any necessary
extern or visibility declarations.
The parameters and return values have the following meanings:
- const paludis::Environment *
- The usual Environment, as used by all Paludis clients.
- const paludis::Hook &
- Contains information about the hook being called.  In paludis_hook_add_dependencies, the only useful member isname().
- const std::shared_ptr<paludis::OutputManager> &
- The output manager being used when the hook is run. Will sometimes be a null pointer, as not all hooks are run with output managed -- in this case, use of stdout is normal.
- paludis::DirectedGraph<std::string, int> &
- A graph containing, as nodes, all named hooks that will be executed along with
this one.  The paludis_hook_add_dependenciesfunction should add any edges required to indicate its desired execution order relative to the other hooks, as follows:g.add_edge("after", "before", 0);(the 0 is not significant, but required by theDirectedGraphAPI).
- paludis::HookResult
- The HookResultconstructor takes two arguments: anint, which should be zero if the hook is successful, or positive if not, and astd::stringcontaining any information that should be passed back to the hook's caller (only used if theHook'soutput_destmember ishod_grab).
Package Manager Defined Hooks
Paludis places some of its own hooks in
LIBEXECDIR/hooks/hookname. These directories are
not for end user use.
The PALUDIS_CMDLINE Variables
Sometimes hooks need access to the commandline used to invoke
paludis.  However, manual parsing of the commandline by hooks will
lead to bugs when people forget to emulate certain behaviour (say, short
options, aliases or -- support).  To work around this issue,
Paludis provides environment variables prefixed PALUDIS_CMDLINE_
that specify the parsed command line:
- The PALUDIS_CMDLINE_PARAMSvariable contains the parameters (that is, the parts that aren't-xor--blahor values for these).
- For each --param-name,PALUDIS_CMDLINE_param_name(note the case and the underscores) is set. If--param-nametakes an argument, this argument is used for the environment variable's value.
- For short options (-x) and aliases, the appropriate long option's variable is set instead.
