如何让Bazel目标依赖目录中所有Git追踪的文件?
解决方案
核心思路
利用git ls-files精准获取Git追踪的文件列表,结合Bazel的genrule生成校验和,再通过diff_test对比基准文件,实现对生成文件手动修改的检测。
步骤1:生成Git追踪文件列表
通过genrule调用git ls-files命令,输出generated目录下所有被Git追踪的文件路径:
genrule( name = "tracked_generated_files", outs = ["tracked_generated_files.txt"], cmd = "git ls-files -- $(rootpath //generated/...) | grep -E '^generated/' > $@", tools = ["@bazel_tools//tools/bash/runfiles"], )
git ls-files只会返回仓库中已追踪的文件,自动排除Git忽略或未提交的文件$(rootpath //generated/...)确保Bazel能正确解析目录路径
步骤2:生成当前文件的校验和
基于上面的文件列表,计算所有目标文件的SHA256校验和并排序(避免文件顺序影响结果):
genrule( name = "current_generated_checksum", outs = ["current_generated_checksum.sha256"], cmd = "sha256sum $(cat $(rootpath :tracked_generated_files)) | sort > $@", data = [":tracked_generated_files"] + glob(["generated/**/*"], exclude_directories = 1), )
glob(["generated/**/*"])确保Bazel能追踪到目录下所有文件的变化,触发重新计算- 排序后输出校验和,保证文件顺序变动不会导致校验值差异
步骤3:对比基准校验和
用diff_test对比当前生成的校验和与源码树中预先提交的基准文件:
diff_test( name = "check_generated_modifications", file1 = "//:generated_checksum_base.sha256", file2 = ":current_generated_checksum", )
- 基准文件
generated_checksum_base.sha256需要预先生成一次:
生成后提交到Git仓库作为对比基准。sha256sum $(git ls-files generated/**/*) | sort > generated_checksum_base.sha256
宏封装(复用性优化)
可以把上述步骤封装成Bazel宏,方便在多个项目或目录中复用:
def verify_generated_files(name, generated_dir, base_checksum_file): # 提取目录名(去掉//前缀) dir_name = generated_dir[2:] if generated_dir.startswith("//") else generated_dir genrule( name = name + "_tracked_files", outs = [name + "_tracked_files.txt"], cmd = "git ls-files -- $(rootpath " + generated_dir + "/...) | grep -E '^" + dir_name + "/' > $@", tools = ["@bazel_tools//tools/bash/runfiles"], ) genrule( name = name + "_checksum", outs = [name + "_checksum.sha256"], cmd = "sha256sum $(cat $(rootpath :" + name + "_tracked_files)) | sort > $@", data = [":" + name + "_tracked_files"] + glob([dir_name + "/**/*"], exclude_directories = 1), ) diff_test( name = name, file1 = base_checksum_file, file2 = ":" + name + "_checksum", )
调用示例:
verify_generated_files( name = "verify_generated_code", generated_dir = "//generated", base_checksum_file = "//:generated_checksum_base.sha256", )
关键注意事项
- Git环境依赖:确保Bazel构建环境中能执行
git命令,若使用容器构建需提前安装Git - 新增文件自动触发:当
generated目录下新增Git追踪文件时,git ls-files会自动包含该文件,触发校验和重新计算 - 排除未追踪文件:依赖
git ls-files的特性,天然排除未提交、被Git忽略的文件,无需额外配置
内容的提问来源于stack exchange,提问作者Ant
相关产品推荐
相关产品推荐

