You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:44:37