如何自定义Bazel中sh_binary/sh_test的数据文件目录结构
当前源文件目录结构:
. ├── config.json └── test.sh
需要基于上述文件创建sh_test规则,测试运行时test.sh要求config.json必须位于configs/prod.json路径,即运行时目录结构为:
. ├── configs │ └── prod.json # 对应原根目录的config.json └── test.sh
要求不能调整现有源码目录结构,也不能在test.sh开头添加文件复制/移动逻辑,期望支持类似如下的配置语法直接定义数据文件的运行时路径:
sh_test( name = "test", srcs = [ "test.sh" ], data = { "configs/prod.json": "config.json", }, )
原生sh_test/sh_binary的data属性仅支持传入文件标签列表声明依赖,不直接支持字典形式的路径映射配置,但可以通过构建期预生成目标路径文件的方式完全满足需求,全程无侵入:
方案1:使用内置
genrule完成单文件路径映射
不需要引入任何外部依赖,通过Bazel内置的生成规则在构建阶段提前把源文件复制到目标路径,再将生成的文件作为测试的data依赖即可,配置示例:# 构建阶段自动将根目录config.json输出到configs/prod.json路径 genrule( name = "generate_prod_config", srcs = ["config.json"], outs = ["configs/prod.json"], cmd = "cp $< $@", ) sh_test( name = "test", srcs = ["test.sh"], data = [":generate_prod_config"], )测试运行时,执行工作目录下会自动存在符合路径要求的
configs/prod.json文件,test.sh可以直接按预期路径读取,不需要改动任何现有源码或脚本逻辑。方案2:使用官方基础库的复制规则简化多文件配置
如果需要映射的文件数量较多,可以使用Bazel官方维护的基础规则库中封装的copy_file、copy_to_directory规则,写法更简洁,批量映射时维护成本更低,单文件映射示例:# 加载官方基础库提供的文件复制规则 load("@bazel_skylib//rules:copy_file.bzl", "copy_file") copy_file( name = "copy_prod_config", src = "config.json", out = "configs/prod.json", ) sh_test( name = "test", srcs = ["test.sh"], data = [":copy_prod_config"], )如果需要一次性配置多个文件的映射路径,使用
copy_to_directory可以实现接近期望的字典式配置效果,批量定义不同源文件对应的目标存放路径。
实现原理:Bazel中测试、二进制目标的运行时文件结构,和构建输出树的相对路径完全一致。
sh_test运行时不会主动修改依赖文件的存放位置,只要在构建阶段通过规则把源文件输出到需要的目标路径,运行时文件自然会出现在对应位置,不需要在脚本运行阶段做额外的文件操作。
内容的提问来源于stack exchange,提问作者sdgfsdh

