簡體   English   中英

您如何枚舉多個文件並將其復制到 Bazel 中的源文件夾?

[英]How do you enumerate and copy multiple files to the source folder in Bazel?

您如何枚舉多個文件並將其復制到 Bazel 中的源文件夾?

我是 Bazel 的新手,我正在嘗試用慣用的 Bazel 解決方案替換實際上是cp -R的非 Bazel 構建步驟。 具體用例是:

  • 將.proto 文件復制到一個子項目,在那里它們將被非 Bazel 構建系統拾取。 N 個 Bazel 包中有 N .proto文件,都在存儲庫的一個protos/目錄中。
  • 將大量.gotmpl模板文件復制到不同的文件夾,可以在 docker 卷中為本地 docker-compose 開發環境拾取它們。 在一個小文件夾層次結構中,一個 Bazel package 中有 M 個模板文件。 下面的示例代碼。
  • 將這些相同的.gotmpl文件復制到 gitops 類型的存儲庫,以便遠程 terraform 發送到產品。

所有來源都是常規的,在 Bazel 可以枚舉它們的地方簽入文件。 所有目標目錄也是 Bazel 包。 我想寫入源文件夾,而不僅僅是bazel-bin ,所以其他非 Bazel 工具可以看到 output 文件。

當前,當添加模板文件或原型 package 時,必須在 bazel 之外運行腳本以獲取該新文件並將其添加到 generated.bzl 文件中,或者完全在 Bazel 之外執行操作。 我想消除這一步,以更接近擁有一個真正的構建命令。

我可以使用符號鏈接來完成此操作,但對於 .proto 文件,它仍然有一個容易出錯的手動步驟,並且在構建中獲得在 Bazel 中以編程方式操作文件的選項會很好。

我研究過的一些解決方案並遇到了死胡同:

  • glob似乎與當前的 package 相關,我看不出它是如何導出的,因為它需要從 BUILD 中調用。 文件組解決了導出問題,但似乎不允許以bazel run目標可以作為輸入的方式枚舉基礎文件。
  • 像 cc_library 這樣愉快地將 glob 作為 src 輸入的規則內置在 Bazel 源代碼中,而不是用 Starlark 編寫的
  • genquery和方面似乎具有強大的元功能,但我看不出如何用它們實際完成這項任務。
  • 如果我可以以編程方式生成files參數,那么“bazel 可以寫入源文件夾”模式和aspect-build/bazel-lib write_source_files的 write_source_files 可能會很棒。

這是模板示例,它是更簡單的情況。 這是我最新的 bazel-ify cp -R實驗。 我想在 Bazel 中表達 src/templates/update_templates_bzl.py。

src/templates/BUILD

# [...]
exports_files(glob(["**/*.gotmpl"]))
# [...]

src/templates/update_templates_bzl.py

#!/usr/bin/env python

from pathlib import Path

parent = Path(__file__).parent
template_files = [str(f.relative_to(parent)) for f in list(parent.glob('**/*.gotmpl'))]
as_python = repr(template_files).replace(",", ",\n    ")

target_bzl = Path(__file__).parent / "templates.bzl"

target_bzl.write_text(f""""Generated template list from {Path(__file__).relative_to(parent)}"

TEMPLATES = {as_python}""")

src/templates/copy_templates.bzl

"""Utility for working with this list of template files"""

load("@aspect_bazel_lib//lib:write_source_files.bzl", "write_source_files")
load("templates.bzl", "TEMPLATES")

def copy_templates(name, prefix):
    files = {
        "%s/%s" % (prefix, f) : "//src/templates:%s" % f for f in TEMPLATES
    }

    write_source_files(
        name = name,
        files = files,
        visibility = ["//visibility:public"],
    )

other/module

load("//src/templates:copy_templates.bzl", "copy_templates")

copy_templates(
    name = "write_template_files",
    prefix = "path/to/gitops/repo/templates",
)

一種可能的方法是使用google/bazel_rules_install

如項目 README.md 中所述,您需要將以下內容添加到您的 WORKSPACE 文件中;

# file: WORKSPACE
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

http_archive(
    name = "com_github_google_rules_install",
    urls = ["https://github.com/google/bazel_rules_install/releases/download/0.3/bazel_rules_install-0.3.tar.gz"],
    sha256 = "ea2a9f94fed090859589ac851af3a1c6034c5f333804f044f8f094257c33bdb3",
    strip_prefix = "bazel_rules_install-0.3",
)

load("@com_github_google_rules_install//:deps.bzl", "install_rules_dependencies")

install_rules_dependencies()

load("@com_github_google_rules_install//:setup.bzl", "install_rules_setup")

install_rules_setup()

然后在您的src/templates目錄中,您可以添加以下內容以將所有模板捆綁到一個目標中。

# file: src/templates/BUILD.bazel
load("@com_github_google_rules_install//installer:def.bzl", "installer")

installer(
    name = "install_templates",
    data = glob(["**/*.gotmpl"]),
)

然后您可以使用安裝程序安裝到您選擇的目錄中,就像這樣。

bazel run //src/templates:install_templates -- path/to/gitops/repo/templates

還值得查看bazelbuild/rules_docker以僅使用 Bazel 構建您的開發環境。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM