如何在Skylark规则中获取maven_jar的artifact属性值?
获取maven_jar的artifact属性值
当然可以实现这个需求!不过因为Bazel的规则分析阶段无法直接访问WORKSPACE中定义的repository规则属性,我们需要用一些间接的方法来获取这个值,这里给你两种可行的方案:
方案一:解析依赖仓库的pom.xml文件
maven_jar会自动下载对应依赖的pom.xml并存储在它创建的external仓库中,我们可以读取这个文件并解析出groupId、artifactId和version,拼接成你需要的groupId:artifactId:version格式。
实现代码示例
def _my_rule_impl(ctx): for dep in ctx.attr.deps: # 构建pom.xml的标签路径 repo_name = dep.label.repository_name pom_label = Label("@{}//:pom.xml".format(repo_name)) # 获取pom文件对象 pom_file = ctx.file.get(pom_label) if not pom_file: print("Warning: No pom.xml found for dependency {}".format(dep.label)) continue # 使用xmllint解析pom.xml(需要构建环境中安装xmllint) def extract_pom_field(field_name): result = ctx.execute([ "xmllint", "--xpath", "/*[local-name()='project']/*[local-name()='{}']/text()".format(field_name), pom_file.path ]) return result.stdout.strip() if result.return_code == 0 else "" group_id = extract_pom_field("groupId") artifact_id = extract_pom_field("artifactId") version = extract_pom_field("version") # 处理parent继承的情况(可选) if not group_id or not version: parent_group = extract_pom_field("parent/groupId") parent_version = extract_pom_field("parent/version") group_id = group_id or parent_group version = version or parent_version if group_id and artifact_id and version: artifact = "{}:{}:{}".format(group_id, artifact_id, version) print("Found artifact for {}: {}".format(dep.label, artifact)) else: print("Failed to parse artifact info for {}".format(dep.label)) # 这里添加你的规则逻辑,比如生成输出文件等 return [] my_rule = rule( implementation = _my_rule_impl, attrs = { "deps": attr.label_list(allow_files = False), }, )
注意事项
- 这个方案依赖
xmllint工具,大部分Linux/macOS环境默认自带,Windows可能需要额外安装。 - 如果依赖的pom.xml使用了parent继承groupId或version,上面的代码已经做了简单处理,你可以根据实际情况扩展解析逻辑。
方案二:包装maven_jar规则,主动暴露artifact信息
如果你能修改WORKSPACE中的maven_jar调用,可以自定义一个包装规则,在生成的仓库中创建一个包含artifact值的文件,之后在自定义规则中直接读取这个文件。
步骤1:在WORKSPACE中定义包装规则
def my_maven_jar(name, artifact): # 调用原生maven_jar native.maven_jar( name = name, artifact = artifact, ) # 在同一个仓库中生成一个包含artifact信息的文件 native.genrule( name = name + "_artifact_info", outs = ["@{}//:artifact.txt".format(name)], cmd = "echo '{}' > $@".format(artifact), )
步骤2:修改WORKSPACE中的maven_jar调用
# 替换原来的maven_jar调用 my_maven_jar( name = "com_google_guava_guava", artifact = "com.google.guava:guava:20.0", )
步骤3:在自定义规则中读取artifact信息
def _my_rule_impl(ctx): for dep in ctx.attr.deps: repo_name = dep.label.repository_name artifact_file_label = Label("@{}//:artifact.txt".format(repo_name)) artifact_file = ctx.file.get(artifact_file_label) if artifact_file: artifact = ctx.read(artifact_file).strip() print("Found artifact for {}: {}".format(dep.label, artifact)) # 你的规则逻辑 return [] my_rule = rule( implementation = _my_rule_impl, attrs = { "deps": attr.label_list(allow_files = False), }, )
这个方案更可靠,不需要依赖外部工具,也不用处理pom.xml的复杂解析,缺点是需要修改WORKSPACE中的maven_jar调用方式。
内容的提问来源于stack exchange,提问作者Simon
相关产品推荐
相关产品推荐

