Каков наиболее эффективный способ извлечения / сбора файлов из списка целей / поставщиков в Bazel?

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

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

def _modular_resources_impl(ctx):
    return ModularResources(
        artifactId = ctx.attr.artifactId,
        formatted_srcs = ",".join([artifactId + ":" + f.path for f in ctx.files.src])
    )
Другие вопросы по тегам