构建钩子插件(Build hook plugins)¶
构建钩子提供了在构建过程的各个阶段执行的代码。有关 构建钩子配置的更多信息,请参阅文档。
知名第三方插件(Known third-party)¶
- hatch-argparse-manpage - 为基于 argparse 的 CLI 生成手册页
- hatch-autorun - 用于向安装中注入代码,自动在第一次导入之前运行
- hatch-build-scripts - 运行任意的 shell 命令,生成构建产物
- hatch-cython - 构建 Cython 扩展
- hatch-gettext - 使用 GNU
gettext
工具编译多语言消息 - hatch-jupyter-builder - 用于 Jupyter 项目生态系统中的包
- hatch-mypyc - 使用 Mypyc 编译代码
- hatch-odoo - 将 Odoo 插件打包到适当的命名空间中
- scikit-build-core - 使用 CMake 构建扩展模块
概述(Overview)¶
构建钩子会在每个选定的构建目标 版本 中运行。
初始化 阶段会在每次构建之前立即执行,而 终结 阶段则在每次构建之后立即执行。每个阶段都有机会查看或修改 构建数据。
构建数据(Build data)¶
构建数据是一个简单的映射,其内容可以影响构建行为。哪些字段存在并被识别取决于每个构建目标。
以下字段始终存在并由构建系统本身识别:
字段 | 类型 | 描述 |
---|---|---|
artifacts | list[str] | 这是一个额外的 artifact 模式 列表,通常只应附加内容 |
force_include | dict[str, str] | 这是一个额外的 强制包含路径 映射,若发生冲突,则优先使用此映射 |
build_hooks | tuple[str, ...] | 这是已配置构建钩子的名称的不可变序列,并与它们的执行顺序一致 |
Attention
虽然用户-facing TOML 选项使用连字符(hyphenated),但构建数据字段应使用下划线命名,以便插件可以将其用作有效的 Python 标识符。
注意事项(Notes)¶
在某些情况下,可能需要使用 force_include
而不是 artifacts
。例如,假设你希望将 lib.so
直接安装到 site-packages
的根目录下,而项目定义了一个名为 src/foo
的 包。如果你创建 src/lib.so
,则不会匹配,因为目录遍历是从 src/foo
开始的,而不是从 src
开始。在这种情况下,必须做以下操作之一:
build_data['force_include']['src/lib.so'] = 'src/lib.so'
或者
build_data['force_include']['/absolute/path/to/src/lib.so'] = 'src/lib.so'
BuildHookInterface
¶
Example usage:
from hatchling.builders.hooks.plugin.interface import BuildHookInterface
class SpecialBuildHook(BuildHookInterface):
PLUGIN_NAME = 'special'
...
from hatchling.plugin import hookimpl
from .plugin import SpecialBuildHook
@hookimpl
def hatch_register_build_hook():
return SpecialBuildHook
Source code in backend/src/hatchling/builders/hooks/plugin/interface.py
class BuildHookInterface(Generic[BuilderConfigBound]): # no cov
"""
Example usage:
```python tab="plugin.py"
from hatchling.builders.hooks.plugin.interface import BuildHookInterface
class SpecialBuildHook(BuildHookInterface):
PLUGIN_NAME = 'special'
...
```
```python tab="hooks.py"
from hatchling.plugin import hookimpl
from .plugin import SpecialBuildHook
@hookimpl
def hatch_register_build_hook():
return SpecialBuildHook
```
"""
PLUGIN_NAME = ''
"""The name used for selection."""
def __init__(
self,
root: str,
config: dict[str, Any],
build_config: BuilderConfigBound,
metadata: ProjectMetadata,
directory: str,
target_name: str,
app: Application | None = None,
) -> None:
self.__root = root
self.__config = config
self.__build_config = build_config
self.__metadata = metadata
self.__directory = directory
self.__target_name = target_name
self.__app = app
@property
def app(self) -> Application:
"""
An instance of [Application](../utilities.md#hatchling.bridge.app.Application).
"""
if self.__app is None:
from hatchling.bridge.app import Application
self.__app = cast(Application, Application().get_safe_application())
return self.__app
@property
def root(self) -> str:
"""
The root of the project tree.
"""
return self.__root
@property
def config(self) -> dict[str, Any]:
"""
The cumulative hook configuration.
```toml config-example
[tool.hatch.build.hooks.<PLUGIN_NAME>]
[tool.hatch.build.targets.<TARGET_NAME>.hooks.<PLUGIN_NAME>]
```
"""
return self.__config
@property
def metadata(self) -> ProjectMetadata:
# Undocumented for now
return self.__metadata
@property
def build_config(self) -> BuilderConfigBound:
"""
An instance of [BuilderConfig](../utilities.md#hatchling.builders.config.BuilderConfig).
"""
return self.__build_config
@property
def directory(self) -> str:
"""
The build directory.
"""
return self.__directory
@property
def target_name(self) -> str:
"""
The plugin name of the build target.
"""
return self.__target_name
def dependencies(self) -> list[str]: # noqa: PLR6301
"""
A list of extra [dependencies](../../config/dependency.md) that must be installed
prior to builds.
!!! warning
- For this to have any effect the hook dependency itself cannot be dynamic and
must always be defined in `build-system.requires`.
- As the hook must be imported to call this method, imports that require these
dependencies must be evaluated lazily.
"""
return []
def clean(self, versions: list[str]) -> None:
"""
This occurs before the build process if the `-c`/`--clean` flag was passed to
the [`build`](../../cli/reference.md#hatch-build) command, or when invoking
the [`clean`](../../cli/reference.md#hatch-clean) command.
"""
def initialize(self, version: str, build_data: dict[str, Any]) -> None:
"""
This occurs immediately before each build.
Any modifications to the build data will be seen by the build target.
"""
def finalize(self, version: str, build_data: dict[str, Any], artifact_path: str) -> None:
"""
This occurs immediately after each build and will not run if the `--hooks-only` flag
was passed to the [`build`](../../cli/reference.md#hatch-build) command.
The build data will reflect any modifications done by the target during the build.
"""
PLUGIN_NAME = ''
class-attribute
instance-attribute
¶
The name used for selection.
__app = app
instance-attribute
¶
__build_config = build_config
instance-attribute
¶
__config = config
instance-attribute
¶
__directory = directory
instance-attribute
¶
__metadata = metadata
instance-attribute
¶
__root = root
instance-attribute
¶
__target_name = target_name
instance-attribute
¶
app: Application
property
¶
An instance of Application.
build_config: BuilderConfigBound
property
¶
An instance of BuilderConfig.
config: dict[str, Any]
property
¶
The cumulative hook configuration.
[tool.hatch.build.hooks.<PLUGIN_NAME>]
[tool.hatch.build.targets.<TARGET_NAME>.hooks.<PLUGIN_NAME>]
[build.hooks.<PLUGIN_NAME>]
[build.targets.<TARGET_NAME>.hooks.<PLUGIN_NAME>]
directory: str
property
¶
The build directory.
metadata: ProjectMetadata
property
¶
root: str
property
¶
The root of the project tree.
target_name: str
property
¶
The plugin name of the build target.
__init__(root: str, config: dict[str, Any], build_config: BuilderConfigBound, metadata: ProjectMetadata, directory: str, target_name: str, app: Application | None = None) -> None
¶
Source code in backend/src/hatchling/builders/hooks/plugin/interface.py
def __init__(
self,
root: str,
config: dict[str, Any],
build_config: BuilderConfigBound,
metadata: ProjectMetadata,
directory: str,
target_name: str,
app: Application | None = None,
) -> None:
self.__root = root
self.__config = config
self.__build_config = build_config
self.__metadata = metadata
self.__directory = directory
self.__target_name = target_name
self.__app = app
clean(versions: list[str]) -> None
¶
This occurs before the build process if the -c
/--clean
flag was passed to the build
command, or when invoking the clean
command.
Source code in backend/src/hatchling/builders/hooks/plugin/interface.py
def clean(self, versions: list[str]) -> None:
"""
This occurs before the build process if the `-c`/`--clean` flag was passed to
the [`build`](../../cli/reference.md#hatch-build) command, or when invoking
the [`clean`](../../cli/reference.md#hatch-clean) command.
"""
dependencies() -> list[str]
¶
A list of extra dependencies that must be installed prior to builds.
Warning
- For this to have any effect the hook dependency itself cannot be dynamic and must always be defined in
build-system.requires
. - As the hook must be imported to call this method, imports that require these dependencies must be evaluated lazily.
Source code in backend/src/hatchling/builders/hooks/plugin/interface.py
def dependencies(self) -> list[str]: # noqa: PLR6301
"""
A list of extra [dependencies](../../config/dependency.md) that must be installed
prior to builds.
!!! warning
- For this to have any effect the hook dependency itself cannot be dynamic and
must always be defined in `build-system.requires`.
- As the hook must be imported to call this method, imports that require these
dependencies must be evaluated lazily.
"""
return []
finalize(version: str, build_data: dict[str, Any], artifact_path: str) -> None
¶
This occurs immediately after each build and will not run if the --hooks-only
flag was passed to the build
command.
The build data will reflect any modifications done by the target during the build.
Source code in backend/src/hatchling/builders/hooks/plugin/interface.py
def finalize(self, version: str, build_data: dict[str, Any], artifact_path: str) -> None:
"""
This occurs immediately after each build and will not run if the `--hooks-only` flag
was passed to the [`build`](../../cli/reference.md#hatch-build) command.
The build data will reflect any modifications done by the target during the build.
"""
initialize(version: str, build_data: dict[str, Any]) -> None
¶
This occurs immediately before each build.
Any modifications to the build data will be seen by the build target.
Source code in backend/src/hatchling/builders/hooks/plugin/interface.py
def initialize(self, version: str, build_data: dict[str, Any]) -> None:
"""
This occurs immediately before each build.
Any modifications to the build data will be seen by the build target.
"""