BUILD 檔案格式設定與 Go 相同,標準化工具會處理大部分的格式設定問題。Buildifier 是一種工具,可剖析原始碼並以標準樣式發出。因此,每個 BUILD 檔案都會以相同的方式自動格式化,在程式碼審查期間不會發生格式問題。此外,工具也能更輕鬆地瞭解、編輯及產生 BUILD 檔案。
BUILD 檔案格式必須與 buildifier 的輸出內容相符。
格式範例
# Test code implementing the Foo controller.
package(default_testonly = True)
py_test(
name = "foo_test",
srcs = glob(["*.py"]),
data = [
"//data/production/foo:startfoo",
"//foo",
"//third_party/java/jdk:jdk-k8",
],
flaky = True,
deps = [
":check_bar_lib",
":foo_data_check",
":pick_foo_port",
"//pyglib",
"//testing/pybase",
],
)
檔案結構
建議:使用下列順序 (每個元素都是選用):
套件說明 (註解)
所有
load()對帳單package()函式。規則和巨集的呼叫
Buildifier 會區分獨立註解和附加至元素的註解。如果註解未附加至特定元素,請在註解後使用空白行。進行自動化變更時 (例如刪除規則時保留或移除留言),這項區別非常重要。
# Standalone comment (such as to make a section in a file)
# Comment for the cc_library below
cc_library(name = "cc")
目前套件中目標的參照
檔案應以相對於套件目錄的路徑參照 (切勿使用向上參照,例如 ..)。產生的檔案應加上「:」前置字串,表示這些檔案並非來源。來源檔案不得以 : 為前置字串。規則應以 : 為前置字串。舉例來說,假設 x.cc 是來源檔案:
cc_library(
name = "lib",
srcs = ["x.cc"],
hdrs = [":gen_header"],
)
genrule(
name = "gen_header",
srcs = [],
outs = ["x.h"],
cmd = "echo 'int x();' > $@",
)
目標命名
目標名稱應具描述性,如果目標包含一個來源檔案,目標名稱通常應衍生自該來源 (例如,chat.cc 的 cc_library 可命名為 chat,或 DirectMessage.java 的 java_library 可命名為 direct_message)。
套件的同名目標 (與所含目錄同名的目標) 應提供目錄名稱所述的功能。如果沒有這類目標,請勿建立同名目標。
參照同名目標時,請盡量使用簡短名稱 (//x,而非 //x:x)。如果您位於相同套件中,請盡量使用本機參照 (:x,而非 //x)。
請避免使用具有特殊意義的「保留」目標名稱。包括 all、__pkg__ 和 __subpackages__,這些名稱具有特殊語意,使用時可能會造成混淆和非預期行為。
如果沒有通用的團隊慣例,以下是 Google 廣泛使用的部分非約束性建議:
- 一般來說,請使用「snake_case」
- 如果特定目標有多個變體,請新增後置字元來消除歧義 (例如
:foo_dev、:foo_prod或:bar_x86,:bar_x64) - 以
_test、_unittest、Test或Tests為目標的後置字串_test - 避免使用無意義的後置字元,例如
_lib或_library(除非為避免_library目標與對應的_binary發生衝突,否則請勿使用) - 適用於 proto 相關目標:
proto_library目標的名稱結尾應為_proto- 特定語言的
*_proto_library規則應與基礎原型相符,但要將_proto替換為特定語言的後置字串,例如:cc_proto_library:_cc_protojava_proto_library:_java_protojava_lite_proto_library:_java_proto_lite
顯示設定
可見度應盡可能縮小範圍,同時仍允許測試和反向依附元件存取。視情況使用 __pkg__ 和 __subpackages__。
避免將套件 default_visibility 設為 //visibility:public。
//visibility:public 只能針對專案公開 API 中的目標個別設定。這些可能是專為外部專案依附而設計的程式庫,或是可供外部專案建構程序使用的二進位檔。
依附元件
依附元件應僅限於直接依附元件 (規則中列出的來源所需依附元件)。請勿列出遞移依附元件。
套件本機的依附元件應列在最前面,並以與上方「參照目前套件中的目標」一節相容的方式參照 (而非使用絕對套件名稱)。
建議直接列出依附元件,做為單一清單。將多個目標的「通用」依附元件放入變數中,會降低可維護性,導致工具無法變更目標的依附元件,並可能導致未使用的依附元件。
Globs
使用 [] 表示「沒有目標」。請勿使用不相符的 glob,因為這比空白清單更容易出錯,也較不明顯。
遞迴
請勿使用遞迴 glob 來比對來源檔案 (例如 glob(["**/*.java"]))。
遞迴 glob 會略過含有 BUILD 檔案的子目錄,因此難以推斷 BUILD 檔案。
一般來說,遞迴 glob 的效率不如每個目錄都有 BUILD 檔案,且檔案之間定義了依附元件圖表,因為這樣可提升遠端快取和並行處理的效率。
建議您在每個目錄中撰寫 BUILD 檔案,並定義目錄之間的依附元件關係圖。
非遞迴
一般來說,非遞迴的 glob 都可以接受。
其他慣例
使用大寫和底線宣告常數 (例如
GLOBAL_CONSTANT),使用小寫和底線宣告變數 (例如my_variable)。即使標籤長度超過 79 個字元,也不應分割。 標籤應盡可能為字串常值。理由:方便尋找及取代。同時提升可讀性。
名稱屬性的值應為常數字串 (巨集除外)。理由:外部工具會使用名稱屬性參照規則。他們需要找出規則,而不必解讀程式碼。
設定布林值類型的屬性時,請使用布林值,而非整數值。 基於舊版原因,規則仍會視需要將整數轉換為布林值,但我們不建議這麼做。理由:
flaky = 1可能會誤讀為「deflake this target by rerunning it once」(重新執行一次即可解決這個目標的問題)。flaky = True明確指出「這項測試不穩定」。
與 Python 樣式指南的差異
雖然目標是與 Python 樣式指南相容,但仍有幾項差異:
沒有嚴格的行長度限制。長註解和長字串通常會分割成 79 欄,但這並非必要。不應在程式碼審查或預先提交指令碼中強制執行。原因:標籤可能很長,超出這個限制。工具通常會產生或編輯
BUILD檔案,這與行長度限制不相容。系統不支援隱含字串串連。使用
+運算子。 理由:BUILD檔案包含許多字串清單。很容易忘記逗號,導致結果完全不同。這在過去造成許多錯誤。另請參閱這項討論。在規則中,關鍵字引數的
=符號前後要加上空格。理由:具名引數比 Python 更常使用,且一律位於獨立一行。空格可提升可讀性。這項慣例已存在很長一段時間,不值得修改所有現有的BUILD檔案。根據預設,字串會使用雙引號。理由:Python 樣式指南未指定此項目,但建議保持一致。因此我們決定只使用雙引號字串。許多語言會使用雙引號標註字串常值。
在兩個頂層定義之間使用單一空白行。理由:
BUILD檔案的結構與一般 Python 檔案不同。當中只包含頂層陳述式。使用單一空白行可縮短BUILD檔案。