0

随着我的进步,我正在编写一些规则并学习 Starlark。

假设我有自己的提供者:

ModularResources = provider(
    doc = "Modular resources",
    fields = {
        "artifactId": "Former Maven artifact id (don't ask me why)",
        "srcs": "List of labels (a glob(..) thing)",
    },
)

def _modular_resources_impl(ctx):
    return ModularResources(
        artifactId = ctx.attr.artifactId,
        srcs = ctx.attr.srcs,
    )

modular_resources = rule(
    implementation = _modular_resources_impl,
    attrs = {
        "artifactId": attr.string(
            mandatory = True,
        ),
        "srcs": attr.label_list(
            allow_files = True,
            mandatory = True,
        ),
    },
)

然后我有一个需要这些的生成器规则:

some_generator = rule(
    attrs = {
        "deps": attr.label_list(
            providers = [ ModularResources ]
        ),
        ...
    },
    ...
)

在我的实现中,我发现我需要做一些解包来获取文件:

def _get_files(deps):
    result = []
    for dep in deps:
        for target in dep[ModularResources].srcs:
            result += target.files.to_list()
    return result

有没有更有效的方法来执行收集?

至于我为什么这样做,生成器实际上需要一个特殊的文件列表,如下所示:

def _format_files(deps):
    formatted = ""
    for dep in deps:
        for target in dep[ModularResources].srcs:
            formatted += ",".join([dep[ModularResources].artifactId + ":" + f.path for f in target.files.to_list()])
    return formatted

FWIW,这是一个如何使用的示例:

a/BUILD

modular_resources(
    name = "generator_resources",
    srcs = glob(
        ["some/path/**/*.whatever"],
    ),
    artifactId = "a",
    visibility = ["//visibility:public"],
)

b/BUILD

some_generator(
    name = "...",
    deps = [
        "//a:generator_resources"
    ]
)
4

1 回答 1

0

如果你想用内存换取更好的性能,如果在提供程序中完成,也许操作可以更容易地被 blaze 并行化:

def _modular_resources_impl(ctx):
    return ModularResources(
        artifactId = ctx.attr.artifactId,
        formatted_srcs = ",".join([artifactId + ":" + f.path for f in ctx.files.src])
    )
于 2020-01-22T18:21:23.757 回答