如何在Bazel中枚举并复制多份文件至源文件夹?
问题:用Bazel替代非Bazel的
cp -R操作,自动同步文件到源目录 需求场景
- 将
protos/目录下多个Bazel包中的.proto文件复制到子项目,供非Bazel构建系统读取 - 将单个Bazel包内目录层级中的大量
.gotmpl模板文件复制到指定文件夹,供本地docker-compose的Docker卷识别 - 将上述
.gotmpl文件同步到GitOps仓库,用于Terraform生产部署
核心要求:输出文件要写入源文件夹而非仅bazel-bin,让非Bazel工具能直接读取;新增文件时无需手动跑外部脚本更新配置,用单一Bazel命令完成所有操作。
现有方案瓶颈
目前依赖外部脚本生成文件列表(比如update_templates_bzl.py),但每次新增模板或proto文件都要手动执行脚本,想完全用Bazel替代该流程,但遇到以下瓶颈:
glob仅能在BUILD文件中使用,无法导出为可复用的文件列表;filegroup能导出目标,但没法被bazel run目标枚举底层文件- 像
cc_library这类支持glob作为srcs的规则是Bazel内置实现的,无法用Starlark复刻类似逻辑 - 尝试过
genquery和aspects,但没找到合适的用法来自动枚举文件并生成复制映射 - 理想方案是用
aspect-build/bazel-lib的write_source_files规则,但需要自动生成files参数,无需手动维护文件列表
现有实现示例
1. src/templates/BUILD
# [...] exports_files(glob(["**/*.gotmpl"])) # [...]
2. src/templates/update_templates_bzl.py
#!/usr/bin/env python from pathlib import Path parent = Path(__file__).parent template_files = [str(f.relative_to(parent)) for f in list(parent.glob('**/*.gotmpl'))] as_python = repr(template_files).replace(",", ",\n ") target_bzl = Path(__file__).parent / "templates.bzl" target_bzl.write_text(f""""Generated template list from {Path(__file__).relative_to(parent)}" TEMPLATES = {as_python}""")
3. src/templates/copy_templates.bzl
"""Utility for working with this list of template files""" load("@aspect_bazel_lib//lib:write_source_files.bzl", "write_source_files") load("templates.bzl", "TEMPLATES") def copy_templates(name, prefix): files = { "%s/%s" % (prefix, f) : "//src/templates:%s" % f for f in TEMPLATES } write_source_files( name = name, files = files, visibility = ["//visibility:public"], )
4. other/module/BUILD
load("//src/templates:copy_templates.bzl", "copy_templates") copy_templates( name = "write_template_files", prefix = "path/to/gitops/repo/templates", )
内容的提问来源于stack exchange,提问作者entropist
相关产品推荐
相关产品推荐

