Как использовать вывод genrule в качестве строки для подстановок expand_template в Bazel? - PullRequest
0 голосов
/ 26 апреля 2019

Похоже, что genrule может выводить только Target, а подстановки expand_template принимают только string_dict, как я могу использовать вывод genrule для expand_template?

gen.bzl

def _expand_impl(ctx):
    ctx.actions.expand_template(
        template = ctx.file._template,
        output = ctx.outputs.source_file,
        substitutions = {
            "{version}": ctx.attr.version,
        }
    )

expand = rule(
    implementation = _expand_impl,
    attrs = {
        "version": attr.string(mandatory = True),
        "_template": attr.label(
            default = Label("//version:local.go.in"),
            allow_single_file = True,
        ),
    },
    outputs = {"source_file": "local.go"},
)

BUILD

load("@io_bazel_rules_go//go:def.bzl", "go_library")

filegroup(
    name = "templates",
    srcs = ["local.go.in"],
)

genrule(
    name = "inject",
    outs = ["VERSION"],
    local = 1,
    cmd = "git rev-parse HEAD",
)

load(":gen.bzl", "expand")

expand(
    name = "expand",
    version = ":inject",
)

go_library(
    name = "go_default_library",
    srcs = [
        "default.go",
        ":expand", # Keep
    ],
    importpath = "go.megvii-inc.com/brain/data/version",
    visibility = ["//visibility:public"],
)

и local.go.in

package version

func init() {
    V = "{version}"
}

Я ожидаю, что {version} в local.go.in можно заменить выводом git rev-parse HEAD.

1 Ответ

0 голосов
/ 30 апреля 2019

Проблема здесь в том, что аргумент substitutions для ctx.actions.expand_template() должен быть известен на этапе анализа (т. Е. При запуске _expand_impl), который происходит до того, как будет выполнена команда git rev-parse HEAD в genrule ( т.е. на этапе выполнения).

Есть несколько способов сделать это. Самое простое - сделать все в жанре:

genrule(
    name = "gen_local_go",
    srcs = ["local.go.in"],
    outs = ["local.go"],
    local = 1,
    cmd = 'sed "s/{VERSION}/$(git rev-parse HEAD)/" "$<" > "$@"',
)

Это зависит от доступности sed на хост-компьютере, но любая другая программа, которая может вводить один файл, изменять текст и выводить его в другой файл, будет работать.

Другой вариант - использовать комбинацию - workspace_status_command Здесь есть более подробная информация: Как запустить команду оболочки во время анализа в bazel? Преимущество этого подхода состоит в том, что он избегает локальных жанров.

...