我有一个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),
},
)
只要依赖关系图发生更改(如文档https://docs.bazel.build/versions/master/skylark/repository_rules.html#when-is-the-implementation-function-executed中所述),就会重新计算local_checksum并执行其工作。
但是由于数据库不是由bazel管理的,是否有任何方法可以强制每次调用bazel以确保所有依赖项都可用时运行此特定规则?
答案 0 :(得分:2)
睡了一会儿,我把一些东西弄碎了。仍在寻找更好的答案,我认为有一种一流的方法可以解决这个问题。
我在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}" "$@"
然后我在规则中添加了用于读取该文件的属性:
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.
"""),
},
最后,我在规则中为这些文件创建路径,以便存储库认为其图已更改。
# 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,
),
)
现在,每次运行构建时,如果数据库更改,则local_checksum文件也会更改,并且可以触发其他规则来重新构建(在我的情况下,我正在生成jooq类,因此查询进入表中),如果数据库和表是稳定的,那么它不会触发重建。