與 Bazel 的日常互動主要是透過幾個指令進行:
build
、test
和run
。然而,您可能會遇到以下問題:
您可能會想將套件推送至存放區、為使用者發布說明文件
運用 Kubernetes 部署應用程式但 Bazel 沒有 publish
deploy
指令 – 這些動作的顯示位置為何?
bazel run 指令
Bazel 著重在遺傳性、可重現性和成效增幅
build
和 test
指令對上述工作沒有幫助。這些動作
可以在網路存取有限的沙箱中執行,
每次 bazel build
重新執行。
請改用 bazel run
,也就是您「想」執行的工作該工作。
副作用Bazel 使用者習慣建立執行檔的規則
規則作者可遵循一組通用模式,將這層關係延伸到
「自訂動詞」
對外:rules_k8s
例如 rules_k8s
Bazel 的 Kubernetes 規則假設您的目標如下:
# BUILD file in //application/k8s
k8s_object(
name = "staging",
kind = "deployment",
cluster = "testing",
template = "deployment.yaml",
)
k8s_object
規則會建構
staging
上使用 bazel build
時的標準 Kubernetes YAML 檔案
目標。不過,k8s_object
也會建立其他目標
巨集,例如 staging.apply
和 :staging.delete
等名稱。這些版本
指令碼執行這些動作;當使用 bazel run
staging.apply
執行時,這些動作的行為就像我們專屬的 bazel k8s-apply
或 bazel
k8s-delete
指令。
其他範例:ts_api_guardian_test
您也可以在 Angular 專案中查看這個模式。
ts_api_guardian_test
巨集
會產生兩個目標第一個是標準 nodejs_test
目標,用於比較
某些生成的輸出內容也就是含有
預期的輸出內容)。透過一般 bazel
test
叫用,即可建構及執行這項功能。在 angular-cli
中,您可以執行
目標
搭配 bazel test //etc/api:angular_devkit_core_api
。
一段時間後,這個黃金檔案可能基於正當理由需要更新。
手動更新這個程序既繁瑣又容易出錯,因此這個巨集也提供
更新黃金檔案的 nodejs_binary
目標,而不是比較
互相對抗實際上,相同的測試指令碼可以直接在「verify」中執行
或「接受」並自動切換模式。也遵循相同的模式
您已瞭解:沒有原生 bazel test-accept
指令,但
也能達到相同效果
bazel run //etc/api:angular_devkit_core_api.accept
。
這個模式的功能可能非常強大 辨識出來的方法
自行調整規則
巨集是這個模式的核心。巨集的用途類似 但可以建立多個指定目標他們通常會建立 目標為指定名稱,執行主要建構動作:或許 容器則會建構一般二進位檔、Docker 映像檔或原始碼封存檔於 因此會建立其他目標 例如發布主要目標的輸出內容 二進位檔,或更新預期的測試輸出內容。
為了方便說明,請包裝一個能產生一個網站的虛構規則, 將 Sphinx 與巨集搭配使用,以建立額外的 讓使用者在準備就緒時即可發布影片請考量下列要點 使用 Sphinx 產生網站的現有規則:
_sphinx_site = rule(
implementation = _sphinx_impl,
attrs = {"srcs": attr.label_list(allow_files = [".rst"])},
)
接著,請設想一個建立指令碼的規則,在執行時 發布產生的網頁:
_sphinx_publisher = rule(
implementation = _publish_impl,
attrs = {
"site": attr.label(),
"_publisher": attr.label(
default = "//internal/sphinx:publisher",
executable = True,
),
},
executable = True,
)
最後,請定義下列巨集,為上述兩個 整體有幾項規則
def sphinx_site(name, srcs = [], **kwargs):
# This creates the primary target, producing the Sphinx-generated HTML.
_sphinx_site(name = name, srcs = srcs, **kwargs)
# This creates the secondary target, which produces a script for publishing
# the site generated above.
_sphinx_publisher(name = "%s.publish" % name, site = name, **kwargs)
在 BUILD
檔案中,使用巨集就如同建立主要巨集
目標:
sphinx_site(
name = "docs",
srcs = ["index.md", "providers.md"],
)
在這個範例中,「文件」就如同
標準、單一 Bazel 規則規則會在建構完成後產生一些設定
並執行 Sphinx 製作 HTML 網站以手動檢查。不過
額外的「docs.publish」也會建立相應的指令碼
或是發布網站檢查主要目標的輸出內容後
使用 bazel run :docs.publish
發布資訊供大眾使用,就像
虛構的 bazel publish
指令
如何立即瞭解 _sphinx_publisher
的實作方式
看起來會像這樣這類動作通常會編寫啟動器殼層指令碼。
這種方法通常需要使用
ctx.actions.expand_template
敬上
編寫非常簡單的 shell 指令碼,本例是叫用發布商二進位檔
其中包含主要目標的輸出內容路徑如此一來
實作可以保持一般性,_sphinx_site
規則只需產生
若要結合這兩種程式碼
。
在 rules_k8s
中,這就是 .apply
的功用:
expand_template
敬上
編寫非常簡單的 Bash 指令碼
apply.sh.tpl
,
這會以主要目標的輸出內容執行 kubectl
。這個指令碼可以
然後透過 bazel run :staging.apply
建構及執行,有效提供
k8s_object
目標的 k8s-apply
指令。