[英]Is there a way to execute a repository_rule with local=True on every bazel invocation?
I have a repository_rule which is querying to see if the local system has a database running and is fully migrated.我有一个 repository_rule 正在查询以查看本地系统是否正在运行数据库并已完全迁移。
# impl
result = ctx.execute(["mysql", "-u", "root", "--protocol", "tcp", "-e", "select * from %s.flyway_schema_history" % ctx.attr.dbname])
ctx.file(
"local_checksum",
"""
{RETURN_CODE}
{STDERR}
{STDOUT}
""".format(
RETURN_CODE = result.return_code,
STDERR = result.stderr,
STDOUT = result.stdout,
),
)
...
# Rule Def
local_database = repository_rule(
implementation = _local_database,
local = True,
configure=True,
attrs = {
"datasource_configuration": attr.label(providers = [DataSourceConnectionInfo]),
"dbname": attr.string(doc = """
If omitted, will be the name of the repository.
"""),
"migrations": attr.label_list(allow_files = True),
},
)
The local_checksum is re-calculated and does its job whenever the dependency graph changes (as stated in the docs https://docs.bazel.build/versions/master/skylark/repository_rules.html#when-is-the-implementation-function-executed ).每当依赖关系图发生变化时,都会重新计算 local_checksum 并执行其工作(如文档https://docs.bazel.build/versions/master/skylark/repository_rules.html#when-is-the-implementation-function中所述-执行)。
But since the database is not managed by bazel is there any way to force this specific rule to run every time bazel is invoked to ensure all dependencies are available?但是由于数据库不是由 bazel 管理的,有没有办法在每次调用 bazel 时强制运行此特定规则以确保所有依赖项都可用?
After some sleep I cobbled something together.睡了一觉后,我拼凑了一些东西。 Still looking for a better answer, I would think there is a first class way to solve this.
仍在寻找更好的答案,我认为有第一个 class 方法来解决这个问题。
I created a bazel wrapper at tools/bazel我在 tools/bazel 创建了一个 bazel 包装器
#!/bin/bash
set -e
echo "`date`
Generated by tools/bazel" > .bazelexec.stamp
# from https://github.com/grpc/grpc/blob/master/tools/bazel
exec -a "$0" "${BAZEL_REAL}" "$@"
and then I added to the rule an attribute for reading that file:然后我在规则中添加了一个用于读取该文件的属性:
local_database = repository_rule(
implementation = _local_database,
local = True,
configure=True,
attrs = {
"datasource_configuration": attr.label(providers = [DataSourceConnectionInfo]),
"dbname": attr.string(doc = """
If omitted, will be the name of the repository.
"""),
"migrations": attr.label_list(allow_files = True),
"recalculate_when": attr.label_list(allow_files = True, doc = """
Files to watch which will trigger the repository to run when they change.
You can add a tools/bazel script to your local repository, and write a file with a date
every time bazel is executed in order to get the migrator to check each bazel run if
someone changed the database.
"""),
},
and lastly, I create paths for those files in the rule so the repository believes its graph has changed.最后,我在规则中为这些文件创建路径,以便存储库相信它的图表已经改变。
# If you don't do something with the file, then the rule does not recalculate.
[ctx.path(file) for file in ctx.attr.recalculate_when]
# Total mysql hack for now... need java tool which dumps content of a table for different databases
result = ctx.execute(
["mysql", "-u", "root", "--protocol", "tcp", "-e", "show databases"],
)
ctx.file(
"local_database_checksum",
"""
{RETURN_CODE}
{STDERR}
{STDOUT}
""".format(
RETURN_CODE = result.return_code,
STDERR = result.stderr,
STDOUT = result.stdout,
),
)
Now every time I run build, if the databases change, the local_checksum file changes, and can trigger other rules to re-build (in my case I'm generating jooq classes, so my query goes into the tables), if the databases and tables are stable, then it doesn't trigger a rebuild.现在每次我运行构建时,如果数据库发生变化,local_checksum 文件也会发生变化,并且可以触发其他规则重新构建(在我的情况下,我正在生成 jooq 类,所以我的查询进入表中),如果数据库和表是稳定的,那么它不会触发重建。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.