如何通过Bazel查询指定目标的所有外部依赖及对应版本
Bazel获取指定目标外部依赖及对应版本的实现方法
原bazel query "kind(rule, deps(//foo:target))" --output=package命令仅能返回依赖包路径,无法提取版本信息,可通过以下几种方式实现「依赖:版本」信息的获取:
直接命令行查询(无需修改构建配置)
使用基于配置后目标图的cquery命令,配合Starlark输出表达式直接提取版本属性,命令如下:bazel cquery "kind('.*_repository', deps(//foo:target))" --output=starlark --starlark:expr="str(attr.name) + ':' + str(attr.revision if hasattr(attr, 'revision') else attr.tag if hasattr(attr, 'tag') else attr.version if hasattr(attr, 'version') else 'version_undeclared')"这个命令会自动匹配不同外部仓库规则的版本字段:覆盖git类依赖的commit/revision、标签拉取依赖的tag、http_archive/各语言包管理规则的version字段,绝大多数场景下可以直接输出结构化结果。
构建流程内嵌版本报告生成
如果需要在构建过程中自动固化依赖版本记录,可以添加自定义构建规则把查询结果输出为构建产物,示例BUILD配置:genrule( name = "generate_dep_version_report", outs = ["dependency_versions.txt"], cmd = """ bazel cquery "kind('.*_repository', deps(//foo:target))" \ --output=starlark \ --starlark:expr="str(attr.name) + ':' + str(attr.version if hasattr(attr, 'version') else attr.tag if hasattr(attr, 'tag') else attr.revision if hasattr(attr, 'revision') else 'unknown')" > $@ """, tools = ["@bazel_tools//tools/bash:runfiles"], )执行
bazel build //:generate_dep_version_report后,可直接在bazel-bin路径下拿到生成的版本映射文件。特定语言依赖的快速提取
如果使用对应语言的专用依赖规则,可通过更简单的方式提取:- Maven(Java/Kotlin)依赖:直接查看
maven_install生成的锁文件,或执行bazel query 'kind("maven_install", //external:*)' --output=build提取坐标与版本映射 - Go依赖:执行
bazel query 'kind("go_repository", deps(//foo:target))' --output=build | grep -E ' name| version'可批量输出依赖名与对应版本 - Node.js依赖:直接读取
npm_install/yarn_install生成的lockfile副本即可拿到全量版本信息
- Maven(Java/Kotlin)依赖:直接查看
注意:原生
bazel query读取的是加载阶段的未配置目标,无法获取外部仓库最终生效的属性值,涉及版本、编译参数这类配置相关的信息,必须使用cquery或aquery查询才能拿到准确结果。
内容的提问来源于stack exchange,提问作者aneeq011
相关产品推荐
相关产品推荐

