Hooks
Warning
This is an experimental feature subject to breaking changes in future releases.
The Conan hooks are Python functions that are intended to extend the Conan functionalities and let users customize the client behavior at determined execution points. Check the hooks section in extending Conan to see some examples of how to use them and already available ones providing useful functionality.
Hook interface
Here you can see a complete example of all the hook functions available and the different parameters for each of them depending on the context:
def pre_export(output, conanfile, conanfile_path, reference, **kwargs):
assert conanfile
output.info("conanfile_path={}".format(conanfile_path))
output.info("reference={}".format(reference.full_str()))
def post_export(output, conanfile, conanfile_path, reference, **kwargs):
assert conanfile
output.info("conanfile_path={}".format(conanfile_path))
output.info("reference={}".format(reference.full_str()))
def pre_source(output, conanfile, conanfile_path, **kwargs):
assert conanfile
output.info("conanfile_path={}".format(conanfile_path))
if conanfile.in_local_cache:
output.info("reference={}".format(kwargs["reference"].full_str()))
def post_source(output, conanfile, conanfile_path, **kwargs):
assert conanfile
output.info("conanfile_path={}".format(conanfile_path))
if conanfile.in_local_cache:
output.info("reference={}".format(kwargs["reference"].full_str()))
def pre_build(output, conanfile, **kwargs):
assert conanfile
if conanfile.in_local_cache:
output.info("reference={}".format(kwargs["reference"].full_str()))
output.info("package_id={}".format(kwargs["package_id"]))
else:
output.info("conanfile_path={}".format(kwargs["conanfile_path"]))
def post_build(output, conanfile, **kwargs):
assert conanfile
if conanfile.in_local_cache:
output.info("reference={}".format(kwargs["reference"].full_str()))
output.info("package_id={}".format(kwargs["package_id"]))
else:
output.info("conanfile_path={}".format(kwargs["conanfile_path"]))
def pre_package(output, conanfile, conanfile_path, **kwargs):
assert conanfile
output.info("conanfile_path={}".format(conanfile_path))
if conanfile.in_local_cache:
output.info("reference={}".format(kwargs["reference"].full_str()))
output.info("package_id={}".format(kwargs["package_id"]))
def post_package(output, conanfile, conanfile_path, **kwargs):
assert conanfile
output.info("conanfile_path={}".format(conanfile_path))
if conanfile.in_local_cache:
output.info("reference={}".format(kwargs["reference"].full_str()))
output.info("package_id={}".format(kwargs["package_id"]))
def pre_upload(output, conanfile_path, reference, remote, **kwargs):
output.info("conanfile_path={}".format(conanfile_path))
output.info("reference={}".format(reference.full_str()))
output.info("remote.name={}".format(remote.name))
def post_upload(output, conanfile_path, reference, remote, **kwargs):
output.info("conanfile_path={}".format(conanfile_path))
output.info("reference={}".format(reference.full_str()))
output.info("remote.name={}".format(remote.name))
def pre_upload_recipe(output, conanfile_path, reference, remote, **kwargs):
output.info("conanfile_path={}".format(conanfile_path))
output.info("reference={}".format(reference.full_str()))
output.info("remote.name={}".format(remote.name))
def post_upload_recipe(output, conanfile_path, reference, remote, **kwargs):
output.info("conanfile_path={}".format(conanfile_path))
output.info("reference={}".format(reference.full_str()))
output.info("remote.name={}".format(remote.name))
def pre_upload_package(output, conanfile_path, reference, package_id, remote, **kwargs):
output.info("conanfile_path={}".format(conanfile_path))
output.info("reference={}".format(reference.full_str()))
output.info("package_id={}".format(package_id))
output.info("remote.name={}".format(remote.name))
def post_upload_package(output, conanfile_path, reference, package_id, remote, **kwargs):
output.info("conanfile_path={}".format(conanfile_path))
output.info("reference={}".format(reference.full_str()))
output.info("package_id={}".format(package_id))
output.info("remote.name={}".format(remote.name))
def pre_download(output, reference, remote, **kwargs):
output.info("reference={}".format(reference.full_str()))
output.info("remote.name={}".format(remote.name))
def post_download(output, conanfile_path, reference, remote, **kwargs):
output.info("conanfile_path={}".format(conanfile_path))
output.info("reference={}".format(reference.full_str()))
output.info("remote.name={}".format(remote.name))
def pre_download_recipe(output, reference, remote, **kwargs):
output.info("reference={}".format(reference.full_str()))
output.info("remote.name={}".format(remote.name))
def post_download_recipe(output, conanfile_path, reference, remote, **kwargs):
output.info("conanfile_path={}".format(conanfile_path))
output.info("reference={}".format(reference.full_str()))
output.info("remote.name={}".format(remote.name))
def pre_download_package(output, conanfile, conanfile_path, reference, package_id, remote, **kwargs):
output.info("conanfile.name={}".format(conanfile.name))
output.info("conanfile_path={}".format(conanfile_path))
output.info("reference={}".format(reference.full_str()))
output.info("package_id={}".format(package_id))
output.info("remote.name={}".format(remote.name))
def post_download_package(output, conanfile, conanfile_path, reference, package_id, remote, **kwargs):
output.info("conanfile.name={}".format(conanfile.name))
output.info("conanfile_path={}".format(conanfile_path))
output.info("reference={}".format(reference.full_str()))
output.info("package_id={}".format(package_id))
output.info("remote.name={}".format(remote.name))
def pre_package_info(output, conanfile, reference, **kwargs):
output.info("reference={}".format(reference.full_str()))
output.info("conanfile.cpp_info.defines={}".format(conanfile.cpp_info.defines))
def post_package_info(output, conanfile, reference, **kwargs):
output.info("reference={}".format(reference.full_str()))
output.info("conanfile.cpp_info.defines={}".format(conanfile.cpp_info.defines))
Functions of the hooks are intended to be self-descriptive regarding to the execution of them. For example, the pre_package()
function
is called just before the package()
method of the recipe is executed.
For download/upload functions, the pre_download()
/pre_upload()
function is executed first in an
conan download/conan upload command. Then pre and post download_recipe()
/upload_recipe()
and its
subsequent pre/post download_package()
/upload_package()
if that is the case. Finally the general
post_download()
/post_upload()
function is called to wrap up the whole execution.
Important
Pre and post download_recipe()
/download_package()
are also executed when installing new recipes/packages from remotes
using conan create or conan install.
Function parameters
Here you can find the description for each parameter:
output: Output object to print formatted messages during execution with the name of the hook and the function executed, e.g.,
[HOOK - complete_hook] post_download_package(): This is the remote name: default
.conanfile: It is a regular
ConanFile
object loaded from the recipe that received the Conan command. It has its normal attributes and dynamic objects such asbuild_folder
,package_folder
…conanfile_path: Path to the conanfile.py file whether it is in local cache or in user space.
reference: Named tuple with attributes
name
,version
,user
, andchannel
. Its representation will be a reference like:box2d/2.1.0@user/channel
package_id: String with the computed package ID.
remote: Named tuple with attributes
name
,url
andverify_ssl
.
Hook function* |
Parameters |
||||
|
|
|
|
|
|
export() |
Yes |
pre/post |
Yes |
No |
No |
source() |
Yes |
Yes |
cache |
No |
No |
build() |
Yes |
user space |
cache |
cache |
No |
package() |
Yes |
pre/post |
cache |
Yes |
No |
upload() upload_recipe() upload_package() |
No |
Yes |
Yes |
Yes |
Yes |
download() download_recipe() |
Yes |
post |
Yes |
Yes |
Yes |
download_package() |
Yes |
Yes |
Yes |
Yes |
Yes |
package_info() |
Yes |
No |
Yes |
No |
No |
*Hook functions are indicated without pre
and post
prefixes for simplicity.
- Table legend:
Yes: Availability in
pre
andpost
functions in any context.No: Not available.
pre / post: Availability in both
pre
andpost
functions with different values. e.g.conanfile_path
pointing to user space inpre
and to local cache inpost
.post: Only available in
post
function.cache: Only available when the context of the command executed is the local cache. e.g. conan create, conan install…
user space: Only available when the context of the command executed is the user space. e.g. conan build
Note
Path to the different folders of the Conan execution flow may be accessible as usual through the conanfile
object. See
source_folder to learn more.
Some of this parameters does not appear in the signature of the function as they may not be always available (Mostly depending on the recipe
living in the local cache or in user space). However, they can be checked with the kwargs
parameter.
Important
Hook functions should have a **kwargs
parameter to keep compatibility of new parameters that may be introduced in future versions
of Conan.