BUILD
dosya biçimlendirmesi, standart biçimlendirme araçlarının çoğunun biçimlendirme sorunlarını giderdiği Go ile aynı yaklaşımı izler.
Oluşturucu, kaynak kodu standart bir stilde ayrıştırıp yayınlayan bir araçtır. Bu nedenle her BUILD
dosyası aynı otomatik şekilde biçimlendirilir. Bu da kod incelemeleri sırasında biçimlendirmenin sorun yaşanmasına neden olur. Ayrıca, araçların BUILD
dosyalarını anlamasını, düzenlemesini ve oluşturmasını kolaylaştırır.
BUILD
dosya biçimlendirmesi, buildifier
çıktısıyla eşleşmelidir.
Biçimlendirme örneği
# 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",
],
)
Dosya yapısı
Öneri: Aşağıdaki düzeni kullanın (her öğe isteğe bağlıdır):
Paket açıklaması (yorum)
Tüm
load()
ifadeleripackage()
işlevi.Kurallara ve makrolara yapılan çağrılar
Haftalık, bağımsız bir yorum ile bir öğeye eklenen yorum arasında ayrım yapar. Belirli bir öğeye ekli olmayan bir yorumun boşluğunu kullanın. Otomatik değişiklikler yapılırken ayrım yapmak önemlidir (örneğin, bir kuralı silerken yorumu saklamak veya kaldırmak için).
# Standalone comment (such as to make a section in a file)
# Comment for the cc_library below
cc_library(name = "cc")
Geçerli paketteki hedeflere referanslar
Dosyalar, paket diziniyle göreli yollarla (..
gibi yukarı başvurular kullanılmadan) başvurulmalıdır. Oluşturulan dosyalar, kaynak olmadıklarını belirtmek için başına ":
" ön eki getirilmelidir. Kaynak dosyaların önüne :
eklenmemelidir. Kuralların başında :
bulunmalıdır. Örneğin, x.cc
ürününün bir kaynak dosya olduğu varsayılır:
cc_library(
name = "lib",
srcs = ["x.cc"],
hdrs = [":gen_header"],
)
genrule(
name = "gen_header",
srcs = [],
outs = ["x.h"],
cmd = "echo 'int x();' > $@",
)
Hedef adlandırma
Hedef adları açıklayıcı olmalıdır. Hedefte tek bir kaynak dosya varsa hedefin genellikle bu kaynaktan türetilen bir adı olmalıdır (örneğin, chat.cc
için cc_library
, chat
veya DirectMessage.java
için java_library
şeklinde adlandırılabilir).
Bir paket için aynı olan hedef (dahil edilen dizinle aynı ada sahip hedef), dizin adında açıklanan işlevi sağlamalıdır. Böyle bir hedef yoksa aynı bir hedef oluşturmayın.
Aynı ada sahip bir kısa adı (//x
yerine //x:x
yerine) tercih edin. Aynı paketteyseniz yerel referansı (//x
yerine :x
) tercih edin.
Özel anlamı olan "ayrılmış" hedef adları kullanmaktan kaçının. Buna all
, __pkg__
ve __subpackages__
dahildir. Bu adlar özel anlamlara sahiptir ve kullanıldıklarında kafa karışıklığına ve beklenmeyen davranışlara neden olabilir.
Yaygın bir ekip sözleşmesi yoksa Google'da yaygın olarak kullanılan bağlayıcı olmayan önerilerden bazıları şunlardır:
- Genel olarak "snake_case"
- Bir
src
içerenjava_library
için bu, uzantısı olmayan dosya adıyla aynı olmayan bir adın kullanılması anlamına gelir - Java
*_binary
ve*_test
kuralları için "Upper CamelCase" ifadesini kullanın. Bu işlem, hedef adınsrc
öğelerinden biriyle eşleşmesini sağlar.java_test
için bu,test_class
özelliğinin hedef adından çıkarılabilmesini sağlar.
- Bir
- Belirli bir hedefin birden çok varyantı varsa, belirsizleştirmek için (ör.
:foo_dev
,:foo_prod
veya:bar_x86
,:bar_x64
) _test
son eki_test
,_unittest
,Test
veyaTests
ile hedefleniyor_lib
veya_library
gibi anlamlı olmayan son eklerden kaçının (_library
hedefi ile karşılık gelen_binary
arasında çakışma olmasını önlemek için gerekli olmadığı sürece)- Proto ile ilgili hedefler için:
proto_library
hedef,_proto
ile biten adlara sahip olmalıdır- Dillere özgü
*_proto_library
kuralları, temel protonunla eşleşmelidir ancak_proto
yerine aşağıdaki gibi dile özgü bir son ek kullanılır:cc_proto_library
:_cc_proto
java_proto_library
:_java_proto
java_lite_proto_library
:_java_proto_lite
Görünürlük
Görünürlüğün mümkün olduğunca iyi bir şekilde sınırlandırılması ve testler ile ters bağımlılıkların erişimine izin verilmesi gerekir. Uygun şekilde __pkg__
ve __subpackages__
kullanın.
default_visibility
paketini //visibility:public
olarak ayarlamaktan kaçının.
//visibility:public
, yalnızca projenin herkese açık API'sindeki hedefler için ayrı olarak ayarlanmalıdır. Bunlar, harici projeler tarafından bağımlı olacak şekilde tasarlanmış kitaplıklar veya harici bir projenin derleme işlemi tarafından kullanılabilecek ikili programlar olabilir.
Bağımlılıklar
Bağımlılıklar, doğrudan bağımlılarla sınırlı olmalıdır (kuralda listelenen kaynaklara bağımlı olmalıdır). Geçişli bağımlılıkları listelemeyin.
Paket yerel bağımlılıkları önce listelenmeli ve yukarıdaki Mevcut paketteki hedeflere referanslar bölümüne (mutlak paket adlarına göre değil) uygun bir şekilde atıfta bulunulmalıdır.
Bağımlıları tek bir liste olarak doğrudan listelemeyi tercih edin. Birkaç hedefin "yaygın" bağımlılarını bir değişkene yerleştirmek, sürdürülebilirliği azaltır, araçların bir hedefin bağımlılıklarını değiştirmesini imkansız kılar ve kullanılmayan bağımlılıklara yol açabilir.
Küre
[]
ile "hedef yok" değerini belirtin. Hiçbir şeyle eşleşmeyen bir glob kullanmayın: Boş bir listeden daha hataya açık ve daha az belirgindir.
Yinelemeli
Kaynak dosyaları eşleştirmek için yinelenen glob'lar kullanmayın (örneğin, glob(["**/*.java"])
).
Yinelemeli hatalar, BUILD
dosyalarını içeren alt dizinleri atladığı için BUILD
dosyalarının geçerli olmasını zorlaştırır.
Yinelenen Glob'lar genellikle dizin başına BUILD
dosyasına sahip olduklarından daha az etkilidir. Bu dosyalar arasında bağımlılık grafiği tanımlanır ve bu da daha iyi önbelleğe alma ve paralellik sağlar.
Her dizinde bir BUILD
dosyası yazmak ve bu dosyalar arasında bir bağımsızlık grafiği tanımlamak iyi bir uygulamadır.
Yinelenmeyen
Yinelenmeyen glob'lar genellikle kabul edilir.
Diğer toplantılar
Sabit değerleri (ör.
GLOBAL_CONSTANT
) bildirmek için büyük harf ve alt çizgi, değişkenleri belirtmek için de küçük harf ve alt çizgi (my_variable
gibi) kullanın.Etiketler, 79 karakterden uzun olsa bile hiçbir zaman bölünmemelidir. Etiketler, mümkün olduğunda dize değişmez değerleri olmalıdır. Rationale: Bulma ve değiştirme işlemlerini kolaylaştırır. Ayrıca okunabilirliği de iyileştirir.
Ad özelliğinin değeri sabit bir sabit dize olmalıdır (makrolar hariç). Rasyonalite: Harici araçlar bir kuralı belirtmek için name özelliğini kullanır. Kuralları yorumlamak zorunda kalmadan kuralları bulmaları gerekir.
Boole türü değerlerini ayarlarken tam sayı değerlerini değil, boole değerlerini kullanın. Eski nedenlerden dolayı, kurallar tam sayıları gerektiğinde boole'ye dönüştürmeye devam etmektedir, ancak önerilmez. Rasyonalite:
flaky = 1
, "Bu hedefi bir kez çalıştırarak hedefi susturmak" olarak yanlış yorumlanabilir.flaky = True
açık bir şekilde "bu test güvenilir değil" diyor.
Python stil kılavuzundaki farklılıklar
Python stil kılavuzuyla uyumluluk bir hedef olsa da birkaç farklılık vardır:
Kesin bir satır uzunluğu sınırı yoktur. Uzun yorumlar ve uzun dizeler genellikle 79 sütuna bölünür ancak zorunlu değildir. Kod incelemelerinde veya ön komut dosyalarında zorunlu kılınmamalıdır. Rasyonel: Etiketler uzun olabilir ve bu sınırı aşabilir.
BUILD
dosyalarının araçlar tarafından oluşturulması veya düzenlenmesi yaygın bir durumdur. Bu, satır uzunluğu sınırı konusunda iyi bir sonuç vermez.Dolaylı dize birleştirme desteklenmiyor.
+
operatörünü kullanın. Rasyonel:BUILD
dosyaları çok sayıda dize listesi içerir. Tamamen farklı bir sonuç veren bir virgül kolayca unutulabilir. Bu da geçmişte çok sayıda hata oluşturmuş oldu. Bu tartışmaya da bakın.Kurallardaki anahtar kelime bağımsız değişkenleri için
=
işaretinin etrafındaki boşlukları kullanın. Rasyonel: Adlandırılmış bağımsız değişkenler Python'da olduğundan çok daha sık kullanılır ve her zaman ayrı bir satırdadır. Alanlar okunabilirliği iyileştirir. Uzun süredir devam eden bu kural, mevcut tümBUILD
dosyalarını değiştirmeye değmez.Varsayılan olarak, dizeler için çift tırnak işareti kullanın. Rasyonalite: Bu, Python stil kılavuzunda belirtilmemiştir ancak tutarlılık önerir. Bu nedenle yalnızca tırnak içine alınmış dizeler kullanmaya karar verdik. Birçok dil, dize değişmez değerleri için çift tırnak kullanır.
İki üst düzey tanım arasında tek bir boş çizgi kullanın. Rasyonalite:
BUILD
dosyasının yapısı tipik bir Python dosyası gibi değildir. Yalnızca üst düzey ifadeler içerir. Tek boş satır kullanmakBUILD
dosyayı kısaltır.