我想从--define
标志中迁移出来并根据以下内容构建设置:https ://docs.bazel.build/versions/5.0.0/skylark/config.html
这是我想传递命令行值的规则。
- 在使用加载规则时,这可以在实践中完成吗?
- 可以访问 .bazel 文件的规则字段中的构建设置值,还是只能访问 Starlark 配置?
- 有没有办法有效地“子类化”加载的规则而无需访问已发布的实现?如果
_impl
是公开的,似乎我可以用我自己的实现来包装它,并传递标志。
我对 Bazel 有点陌生,并且仍在寻找正确的方法来概念化这些东西。任何指导表示赞赏!
当前方法
后端/BUILD.bazel:
load("@io_bazel_rules_docker//container:container.bzl", "container_image", "container_push")
# container_image :run_server definition
container_push(
name = "push_server",
format = "Docker",
image = ":run_server",
registry = "gcr.io",
repository = "$(PROJECT_ID)/chat/server",
tag = "$(CONTAINER_TAG)",
)
然后我运行:
bazel run \
--platforms=@io_bazel_rules_go//go/toolchain:linux_amd64 \
--define PROJECT_ID=$(gcloud config get-value project) \
--define CONTAINER_TAG=some_feature_branch \
-- //backend:push_server
我试过的
几种变体:
load("//backend:rules.bzl", "gcr_container_push")
load("@bazel_skylib//rules:common_settings.bzl", "string_flag")
load("@io_bazel_rules_docker//container:container.bzl", "container_image")
string_flag(
name = "container_tag",
build_setting_default = "latest",
visibility = ["//visibility:public"],
)
string_flag(
name = "project_id",
build_setting_default = "",
visibility = ["//visibility:public"],
)
# container_image :run_server definition
gcr_container_push(
name = "push_server",
image = ":run_server",
path = "chat/server",
)
后端/rules.bzl:
load("@bazel_skylib//rules:common_settings.bzl", "BuildSettingInfo")
load("@bazel_skylib//lib:paths.bzl", "paths")
load("@io_bazel_rules_docker//container:container.bzl", "container_push")
def _gcr_container_push_impl(ctx):
project_id = ctx.attr._project_id[BuildSettingInfo].value
if len(project_id) == 0:
fail("Please provide a GCP project ID via --//backend:project_id=<PROJECT ID>.")
container_push(
name = ctx.label.name,
format = "Docker",
image = ctx.attr.image,
registry = "gcr.io",
repository = paths.join(project_id, ctx.attr.path),
tag = ctx.attr._container_tag[BuildSettingInfo].value,
)
_gcr_container_push_attrs = {
"image": attr.label(
allow_single_file = [".tar"],
mandatory = True,
doc = "The label of the image to push.",
),
"path": attr.string(
mandatory = True,
doc = "The name of the image within the repository. Ex. gcr.io/project_id/<PATH>:tag.",
),
"_container_tag": attr.label(default = Label("//backend:container_tag")),
"_project_id": attr.label(default = Label("//backend:project_id")),
}
gcr_container_push = rule(
implementation = _gcr_container_push_impl,
attrs = _gcr_container_push_attrs,
executable = True,
)
然后我运行:
bazel run \
--platforms=@io_bazel_rules_go//go/toolchain:linux_amd64 \
--//backend:project_id=ggx-prototype \
-- //backend:push_server
返回:
Error in container_push_: 'container_push_' can only be called during the loading phase