BUILD
檔案格式與 Go 相同,而標準化工具會處理大部分的格式問題。建構工具是一項工具,可剖析及發出標準樣式的原始碼。因此,每個 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()
函式。對規則和巨集的呼叫
建構工具會區分獨立註解和元素附加的註解。如果註解並未附加至特定元素,請在該元素後方使用空白行。區別在執行自動化變更時非常重要 (例如,在刪除規則時保留或移除註解)。
# 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"
- 對於具有
src
的java_library
,這表示使用的名稱與沒有副檔名的檔案名稱不同。 - 如果是 Java
*_binary
和*_test
規則,請使用「Upper CamelCase」。這樣一來,目標名稱就會與其中一個src
相符。對於java_test
,這可以讓系統從目標名稱推斷test_class
屬性。
- 對於具有
- 如果特定目標有多個變化版本,請新增後置字串以便區分 (例如
: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_proto
java_proto_library
:_java_proto
java_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
檔案,並定義檔案之間的依附元件圖表。
非遞迴
一般而言,可接受非遞迴的斑點。
其他慣例
請使用大寫和底線宣告常數 (例如
GLOBAL_CONSTANT
),請使用小寫和底線來宣告變數 (例如my_variable
)。即便超過 79 個字元,也不應分割標籤。標籤應盡可能包含字串常值。原因:您就能輕鬆尋找與取代物件。改善可讀性。
名稱屬性的值應為常值常數字串 (巨集除外)。理由:外部工具會使用名稱屬性參照規則。需要找出規則而無需解讀程式碼。
設定布林類型屬性時,請使用布林值,而非整數值。就舊版而言,規則仍會視需要將整數轉換為布林值,但我們不建議這麼做。理由:
flaky = 1
可能會寫錯為「藉由重新執行一次這個目標來防禦這個目標」。flaky = True
會明確表示「這項測試不穩定」。
與 Python 樣式指南的差異
雖然目標是與 Python 樣式指南的相容性,但還是有幾點差異:
沒有嚴格的行長度限制。長註解和長字串通常會分割為 79 個資料欄,但並非必要。因此請勿在程式碼審查或預先提交指令碼中強制執行。理由:標籤可以過長,超過此限制。
BUILD
檔案常由工具產生或編輯,這種工具不會超出行長度限制。不支援隱式字串串連。使用
+
運算子。理由:BUILD
檔案包含許多字串清單。使用者很容易忘記一個逗號,因此會產生完全不同的結果。這在過去產生了許多錯誤另請參閱此討論。請在規則中的
=
符號前後加上空格。理由:已命名的引數比 Python 頻率高,而且一律以單獨行顯示。聊天室可提高可讀性。此慣例長期以來行之有年,不值得修改所有現有的BUILD
檔案。根據預設,字串會使用雙引號。理由:這未在 Python 樣式指南中指定,但建議的一致性。因此,我們決定僅使用雙引號的字串。許多語言會在字串常值中使用雙引號。
兩個頂層定義之間請使用一行空白行,理由:
BUILD
檔案的結構與一般 Python 檔案不同。其中只有頂層陳述式。使用單空白行可讓BUILD
檔案縮短。