简体   繁体   English

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

[英]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.

相关问题 bazel repository_rule 没有被执行 - bazel repository_rule not getting executed Bazel 的`repository_rule` 如何调整`label_flag`(或者更普遍的`config_setting`)? - How can a Bazel `repository_rule` adjust a `label_flag` (or a `config_setting` more generally)? 如何设置基本的repository_rule? - How to setup a basic repository_rule? Bazel存储库规则-在repository_ctx.execute中下载文件 - Bazel repository rule- downloading a file in repository_ctx.execute bazel-LLVM构建文件中的bazel规则不在TensorFlow中执行 - bazel - bazel rule in LLVM build file does not execute in TensorFlow 尝试使用 pip_install 会导致:“repository_rule 中的错误:'repository rule http_archive' 只能在工作空间加载期间调用” - Attempt to use pip_install results in: "Error in repository_rule: 'repository rule http_archive' can only be called during workspace loading" bazel-使用本地LLVM存储库构建TensorFlow时出错 - bazel - Error building TensorFlow with local LLVM repository 执行从 bazel 规则作为参数传递的打字稿文件 - Execute typescript files passed as arguments from a bazel rule 如何在 Bazel 中加载 local_repository 对外部依赖的依赖? - How to load local_repository dependencies on external dependency in Bazel? bazel 中的错误“名称‘new_local_repository’未定义” - error “name 'new_local_repository' is not defined” in bazel
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM