如何在run_binary规则中使用pip安装的hatch工具?
解决Bazel中调用pip_parse安装的Hatch可执行文件问题
问题背景
通过WORKSPACE中的pip_parse安装了hatch依赖,希望将其作为工具在run_binary规则中执行hatch build,但直接指定tool = "hatch"时出现找不到目标的错误,需求是找到正确引用pip安装二进制文件的方法,或替代实现方案。
原配置文件
WORKSPACE
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") http_archive( name = "bazel_skylib", sha256 = "b8a1527901774180afc798aeb28c4634bdccf19c4d98e7bdd1ce79d1fe9aaad7", urls = [ "https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.4.1/bazel-skylib-1.4.1.tar.gz", "https://github.com/bazelbuild/bazel-skylib/releases/download/1.4.1/bazel-skylib-1.4.1.tar.gz", ] ) http_archive( name = "rules_python", sha256 = "ffc7b877c95413c82bfd5482c017edcf759a6250d8b24e82f41f3c8b8d9e287e", strip_prefix = "rules_python-0.19.0", url = "https://github.com/bazelbuild/rules_python/releases/download/0.19.0/rules_python-0.19.0.tar.gz", ) http_archive( name = "aspect_bazel_lib", sha256 = "2518c757715d4f5fc7cc7e0a68742dd1155eaafc78fb9196b8a18e13a738cea2", strip_prefix = "bazel-lib-1.28.0", url = "https://github.com/aspect-build/bazel-lib/releases/download/v1.28.0/bazel-lib-v1.28.0.tar.gz", ) # for aspect's run_binary rule load("@aspect_bazel_lib//lib:repositories.bzl", "aspect_bazel_lib_dependencies") aspect_bazel_lib_dependencies() # install Python requirements load("@rules_python//python:pip.bzl", "pip_parse") pip_parse( name = "py_mod_deps", requirements_lock = "//py-mod:requirements.txt" ) load("@py_mod_deps//:requirements.bzl", "install_deps") install_deps()
py-mod/requirements.txt
hatch==1.6.3 # other dependencies from pip-compile requirements.in
原py-mod/BUILD
load("@aspect_bazel_lib//lib:run_binary.bzl", "run_binary") run_binary( name = "mymodule", tool = "hatch", args = ["build"], srcs = glob(["**/*.py"]), out_dirs = ["dist/"] )
报错信息
ERROR: .../py-mod/BUILD: RunBinary py-mod/dist failed: missing input file '//py-mod:hatch' ERROR: .../py-mod/BUILD: RunBinary py-mod/dist failed: 1 input file(s) do not exist
解决方案
方案一:直接引用pip_parse生成的Hatch目标
pip_parse会为每个包含可执行入口的Python包生成对应的Bazel目标,格式为@<pip_parse_name>//:<package_name>,这里pip_parse的name是py_mod_deps,因此Hatch的目标是@py_mod_deps//:hatch。
修改后的py-mod/BUILD:
load("@aspect_bazel_lib//lib:run_binary.bzl", "run_binary") run_binary( name = "mymodule", tool = "@py_mod_deps//:hatch", args = ["build"], # 包含hatch构建所需的所有配置文件,比如pyproject.toml srcs = glob(["**/*.py", "pyproject.toml"]), out_dirs = ["dist/"], )
关键提示
- 必须确保
srcs包含Hatch构建依赖的所有文件,比如pyproject.toml,否则Hatch会因找不到配置文件而失败。
方案二:用py_binary包装Hatch调用(替代方案)
如果需要更灵活的控制,可以编写Python脚本包装Hatch的调用,通过py_binary生成可执行目标后供run_binary使用。
- 在
py-mod目录下创建run_hatch.py:
from hatch.cli.main import main import sys if __name__ == "__main__": sys.exit(main())
- 修改
py-mod/BUILD:
load("@aspect_bazel_lib//lib:run_binary.bzl", "run_binary") load("@rules_python//python:defs.bzl", "py_binary") py_binary( name = "hatch_wrapper", srcs = ["run_hatch.py"], deps = ["@py_mod_deps//:hatch"], main = "run_hatch.py", ) run_binary( name = "mymodule", tool = ":hatch_wrapper", args = ["build"], srcs = glob(["**/*.py", "pyproject.toml"]), out_dirs = ["dist/"], )
验证执行
修改完成后,执行以下命令即可正常构建:
bazel build //py-mod:mymodule
内容的提问来源于stack exchange,提问作者tomocafe
相关产品推荐
相关产品推荐

