Каков наиболее эффективный способ извлечь / собрать файлы из списка целей / поставщиков в Bazel? - PullRequest
0 голосов
/ 22 января 2020

Я пишу некоторые правила и изучаю 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"
    ]
)

1 Ответ

0 голосов
/ 22 января 2020

Если вы хотите обменять память на лучшую производительность, возможно, операция будет проще распараллелить, если вместо этого она выполняется в провайдере:

def _modular_resources_impl(ctx):
    return ModularResources(
        artifactId = ctx.attr.artifactId,
        formatted_srcs = ",".join([artifactId + ":" + f.path for f in ctx.files.src])
    )
...