forked from conan-io/conan
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhook_manager.py
61 lines (53 loc) · 2.59 KB
/
hook_manager.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
import os
from conans.client.loader import load_python_file
from conan.errors import ConanException
valid_hook_methods = ["pre_export", "post_export",
"pre_validate", "post_validate",
"pre_source", "post_source",
"pre_generate", "post_generate",
"pre_build", "post_build", "post_build_fail",
"pre_package", "post_package",
"pre_package_info", "post_package_info"]
class HookManager:
def __init__(self, hooks_folder):
self._hooks_folder = hooks_folder
self.hooks = {}
self._load_hooks() # A bit dirty, but avoid breaking tests
def execute(self, method_name, conanfile):
assert method_name in valid_hook_methods, \
"Method '{}' not in valid hooks methods".format(method_name)
hooks = self.hooks.get(method_name)
if hooks is None:
return
for name, method in hooks:
# TODO: This display_name is ugly, improve it
display_name = conanfile.display_name
try:
conanfile.display_name = "%s: [HOOK - %s] %s()" % (conanfile.display_name, name,
method_name)
method(conanfile)
except Exception as e:
raise ConanException("[HOOK - %s] %s(): %s" % (name, method_name, str(e)))
finally:
conanfile.display_name = display_name
def _load_hooks(self):
hooks = {}
for root, dirs, files in os.walk(self._hooks_folder):
for f in files:
if f.startswith("hook_") and f.endswith(".py"):
hook_path = os.path.join(root, f)
name = os.path.relpath(hook_path, self._hooks_folder).replace("\\", "/")
hooks[name] = hook_path
# Load in alphabetical order, just in case the order is important there is a criteria
# This is difficult to test, apparently in most cases os.walk is alphabetical
for name, hook_path in sorted(hooks.items()):
self._load_hook(hook_path, name)
def _load_hook(self, hook_path, hook_name):
try:
hook, _ = load_python_file(hook_path)
for method in valid_hook_methods:
hook_method = getattr(hook, method, None)
if hook_method:
self.hooks.setdefault(method, []).append((hook_name, hook_method))
except Exception as e:
raise ConanException("Error loading hook '%s': %s" % (hook_path, str(e)))