繁体   English   中英

有没有办法在每次 bazel 调用时使用 local=True 执行 repository_rule ?

[英]Is there a way to execute a repository_rule with local=True on every bazel invocation?

我有一个 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),
    },
)

每当依赖关系图发生变化时,都会重新计算 local_checksum 并执行其工作(如文档https://docs.bazel.build/versions/master/skylark/repository_rules.html#when-is-the-implementation-function中所述-执行)。

但是由于数据库不是由 bazel 管理的,有没有办法在每次调用 bazel 时强制运行此特定规则以确保所有依赖项都可用?

睡了一觉后,我拼凑了一些东西。 仍在寻找更好的答案,我认为有第一个 class 方法来解决这个问题。

我在 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 类,所以我的查询进入表中),如果数据库和表是稳定的,那么它不会触发重建。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM