summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/spack/docs/developer_guide.rst10
-rw-r--r--lib/spack/spack/hooks/__init__.py47
2 files changed, 25 insertions, 32 deletions
diff --git a/lib/spack/docs/developer_guide.rst b/lib/spack/docs/developer_guide.rst
index f538f75206..21204ba077 100644
--- a/lib/spack/docs/developer_guide.rst
+++ b/lib/spack/docs/developer_guide.rst
@@ -333,13 +333,9 @@ inserting them at different places in the spack code base. Whenever a hook
type triggers by way of a function call, we find all the hooks of that type,
and run them.
-Spack defines hooks by way of a module at ``lib/spack/spack/hooks`` where we can define
-types of hooks in the ``__init__.py``, and then python files in that folder
-can use hook functions. The files are automatically parsed, so if you write
-a new file for some integration (e.g., ``lib/spack/spack/hooks/myintegration.py``
-you can then write hook functions in that file that will be automatically detected,
-and run whenever your hook is called. This section will cover the basic kind
-of hooks, and how to write them.
+Spack defines hooks by way of a module in the ``lib/spack/spack/hooks`` directory.
+This module has to be registered in ``__init__.py`` so that Spack is aware of it.
+This section will cover the basic kind of hooks, and how to write them.
^^^^^^^^^^^^^^
Types of Hooks
diff --git a/lib/spack/spack/hooks/__init__.py b/lib/spack/spack/hooks/__init__.py
index 0e7e303692..73fad62d6a 100644
--- a/lib/spack/spack/hooks/__init__.py
+++ b/lib/spack/spack/hooks/__init__.py
@@ -21,43 +21,40 @@ systems (e.g. modules, lmod, etc.) or to add other custom
features.
"""
import importlib
-
-from llnl.util.lang import ensure_last, list_modules
-
-import spack.paths
+import types
+from typing import List, Optional
class _HookRunner:
- #: Stores all hooks on first call, shared among
- #: all HookRunner objects
- _hooks = None
+ #: Order in which hooks are executed
+ HOOK_ORDER = [
+ "spack.hooks.module_file_generation",
+ "spack.hooks.licensing",
+ "spack.hooks.sbang",
+ "spack.hooks.windows_runtime_linkage",
+ "spack.hooks.drop_redundant_rpaths",
+ "spack.hooks.absolutify_elf_sonames",
+ "spack.hooks.permissions_setters",
+ # after all mutations to the install prefix, write metadata
+ "spack.hooks.write_install_manifest",
+ # after all metadata is written
+ "spack.hooks.autopush",
+ ]
+
+ #: Contains all hook modules after first call, shared among all HookRunner objects
+ _hooks: Optional[List[types.ModuleType]] = None
def __init__(self, hook_name):
self.hook_name = hook_name
- @classmethod
- def _populate_hooks(cls):
- # Lazily populate the list of hooks
- cls._hooks = []
-
- relative_names = list(list_modules(spack.paths.hooks_path))
-
- # Ensure that write_install_manifest comes last
- ensure_last(relative_names, "absolutify_elf_sonames", "write_install_manifest")
-
- for name in relative_names:
- module_name = __name__ + "." + name
- module_obj = importlib.import_module(module_name)
- cls._hooks.append((module_name, module_obj))
-
@property
- def hooks(self):
+ def hooks(self) -> List[types.ModuleType]:
if not self._hooks:
- self._populate_hooks()
+ self._hooks = [importlib.import_module(module_name) for module_name in self.HOOK_ORDER]
return self._hooks
def __call__(self, *args, **kwargs):
- for _, module in self.hooks:
+ for module in self.hooks:
if hasattr(module, self.hook_name):
hook = getattr(module, self.hook_name)
if hasattr(hook, "__call__"):