【问题标题】:Is there a way to change private attribute of an Aspect progammatically?有没有办法以编程方式更改 Aspect 的私有属性?
【发布时间】:2020-06-25 20:43:30
【问题描述】:

假设我有类似以下的内容。

def _foo_aspect_impl(target, ctx):
    # operations

    return FooInfo(...)

foo_aspect = aspect(implementation = _foo_aspect_impl,
    attr_aspects = ['deps'],
    attrs = dict(
        _tool = attr.Label(
            # defs
        ),
    )
)

def _foo_rule_impl(ctx):
    for dep in ctx.attr.deps:
        # do something with `dep[FooInfo]`

    return DefaultInfo(...)

foo_rule = rule(
    implementation = _foo_rule_impl,
    attrs = dict(
        "deps": attr.label_list(
            aspects = [foo_aspect],
        )
    )
)

有没有办法在WORKSPACE 中或在foo_rule 的调用中更改foo_aspect.attr._tool 的值?前者更可取。

_tool 的版本和存储库来源的用例可能会因项目而异。当切面驻留在两个项目共享的存储库中时,为这两个项目创建两个分支仅用于_tool 的版本控制是没有意义的。

【问题讨论】:

    标签: bazel bazel-rules bazel-aspect


    【解决方案1】:

    经过一番摸索后,我发现了一种相当复杂的方法。

    由于在加载阶段似乎在WORKSPACE.bazel 中唯一可配置的是其他工作区/存储库,因此实际上可以将目标别名与存储库加载一起使用以多路复用可配置目标。

    这是它的工作原理。

    首先,定义一个新的存储库规则new_virtual_repository,它创建的存储库除了加载BUILD.bazelWORKSPACE.bazel 文件之外什么都不做。

    # repo.bzl
    
    load("@bazel_tools//tools/build_defs/repo:utils.bzl", "workspace_and_buildfile")
    
    def _new_virtual_repo_impl(ctx):
        # Create build file
        workspace_and_buildfile(ctx)
        return ctx.attr
    
    new_virtual_repository = repository_rule(
        implementation = _new_virtual_repo_impl,
        attrs = dict(
            build_file = attr.label(allow_single_file = True),
            build_file_content = attr.string(),
            workspace_file = attr.label(allow_single_file = True),
            workspace_file_content = attr.string(),
        ),
        local = True,
    )
    

    然后,创建一个扩展文件config.bzl,它实现了一个生成BUILD.bazel文件并加载虚拟存储库的功能:

    # config.bzl
    
    load(":repo.bzl", "new_virtual_repository")
    def config(tool):
        build_file_content = """
    alias(
        name = "tool",
        actual = "%s",
    """ % (tool)
    
        new_virtual_repository(
            name = "config_repo",
            build_file_content = build_file_content,
        )
    

    现在在方面规范中:

    # aspect.bzl
    
    foo_aspect = aspect(
        ...
        attrs = dict(
            _tool = attr.Label("@config_repo//:tool"),
        )
    )
    

    最后在WORKSPACE.bazel配置实际工具:

    # WORKSPACE.bazel
    
    load("//:config.bzl", "config")
    config(tool="<actual_tool_label>")
    

    【讨论】:

      猜你喜欢
      • 2021-12-13
      • 2020-04-23
      • 1970-01-01
      • 1970-01-01
      • 2020-01-14
      • 1970-01-01
      • 2020-09-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多