BUILD
dosya biçimlendirmesi, çoğu biçimlendirme sorununun standart bir araç tarafından ele alındığı Go ile aynı yaklaşımı uygular.
Buildifier, kaynak kodunu standart bir stille 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 olmasını önler. Ayrıca araçların BUILD
dosyalarını anlamasını, düzenlemesini ve oluşturmasını da kolaylaştırır.
BUILD
dosya biçimi, buildifier
sonucuyla 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 sırayı kullanın (her öğe isteğe bağlıdır):
Paket açıklaması (yorum)
load()
ekstresinin tümüpackage()
işlevi.Kurallara ve makrolara yapılan çağrılar
Derleyici, bağımsız bir yorum ile bir öğeye ekli yorum arasında ayrım yapar. Bir yorum belirli bir öğeye ekli değilse arkasından boş bir satır kullanın. Bu ayrım, otomatik değişiklikler yaparken (örneğin, bir kuralı silerken yorumu tutmak veya kaldırmak için) önemlidir.
# 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
Dosyalara, paket dizinine göre kendi yollarıyla başvurulmalıdır (..
gibi yukarı referanslar hiç kullanılmadan). Oluşturulan dosyalara kaynak olmadıklarını belirtmek için ":
" öneki eklenmelidir. Kaynak dosyalara :
ön eki eklenmemelidir. Kurallar :
ile başlamalıdır. Örneğin, x.cc
bir kaynak dosya olduğu varsayıldığında:
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. Bir hedef tek bir kaynak dosya içeriyorsa hedefin adı genellikle bu kaynaktan türetilmelidir (örneğin, chat.cc
için bir cc_library
chat
olarak adlandırılabilir veya DirectMessage.java
için bir java_library
direct_message
olarak adlandırılabilir).
Bir paketin aynı ada sahip hedefi (içeren dizinle aynı ada sahip hedef), dizin adıyla açıklanan işlevi sağlamalıdır. Böyle bir hedef yoksa aynı ada sahip bir hedef oluşturmayın.
Aynı ada sahip bir hedefe atıfta bulunurken kısa adı kullanmayı tercih edin (//x:x
yerine //x
). Aynı paketteyseniz yerel referansı tercih edin (//x
yerine :x
).
Özel anlamı olan "ayrılmış" hedef adları kullanmaktan kaçının. all
, __pkg__
ve __subpackages__
de bu kapsamdadır. Bu adlar özel anlamlara sahiptir ve kullanıldığında karışıklıklara ve beklenmedik davranışlara neden olabilir.
Geçerli bir ekip kuralı olmadığında, Google'da yaygın olarak kullanılan ve bağlayıcı olmayan bazı öneriler aşağıda verilmiştir:
- Genel olarak, "snake_case" kullanın
- Bir
src
içerenjava_library
için bu, uzantı olmadan dosya adıyla aynı olmayan bir ad kullanmak anlamına gelir. - Java
*_binary
ve*_test
kuralları için "Upper CamelCase" değerini kullanın. Bu, hedef adınınsrc
değerlerinden 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 fazla varyantı varsa anlam karışıklığını önlemek için bir son ek ekleyin (ör.
:foo_dev
,:foo_prod
veya:bar_x86
,:bar_x64
) _test
son eki,_test
,_unittest
,Test
veyaTests
ile hedeflenir_lib
veya_library
gibi anlamsız son ekler kullanmaktan kaçının (_library
hedefi ile karşılık gelen_binary
arasında çakışmaları ö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 alınan protokolle eşleşmeli ancak_proto
yerine aşağıdaki gibi bir dile özgü sonek eklemelidir: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ük, testler ve ters bağımlılıklar tarafından erişime izin verirken mümkün olduğunca dar kapsamlı olmalıdır. __pkg__
ve __subpackages__
öğelerini uygun şekilde kullanın.
default_visibility
paketini //visibility:public
olarak ayarlamamaya çalışın.
//visibility:public
yalnızca projenin herkese açık API'sindeki hedefler için ayrı ayrı ayarlanmalıdır. Bunlar, harici projeler tarafından bağımlı olacak şekilde tasarlanmış kitaplıklar veya harici bir projenin derleme süreci tarafından kullanılabilecek ikili dosyalar olabilir.
Bağımlılıklar
Bağımlılıklar, doğrudan bağımlılıklarla (kuraldaki kaynaklar tarafından ihtiyaç duyulan bağımlılıklar) sınırlandırılmalı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üyle uyumlu bir şekilde referans verilmelidir (mutlak paket adlarıyla değil).
Bağımlılıkları doğrudan tek bir liste halinde listelemeyi tercih edin. Birkaç hedefin "ortak" bağımlılıkları bir değişkene yerleştirildiğinde bakım kolaylığı azalır, araçların bir hedefin bağımlılıkları değiştirmesi imkansız hale gelir ve kullanılmayan bağımlılıklara yol açabilir.
Globs
[]
ile "hedef yok" belirtebilirsiniz. Hiçbir şeyle eşleşmeyen bir glob kullanmayın. Bu, boş bir listeye göre daha hataya açık ve daha az belirgindir.
Yinelenen
Kaynak dosyaları eşleştirmek için yinelenen glob'lar kullanmayın (örneğin, glob(["**/*.java"])
).
Yinelenen glob'lar, BUILD
dosyaları içeren alt dizinleri atladığından BUILD
dosyalarının anlaşılmasını zorlaştırır.
Yinelenen glob'lar, daha iyi uzaktan önbelleğe alma ve paralellik sağladığı için genellikle dizin başına bir BUILD
dosyası ve aralarında tanımlanmış bir bağımlılık grafiği bulundurmaktan daha az verimlidir.
Her dizin için bir BUILD
dosyası yazmak ve bunlar arasında bir bağımlılık grafiği tanımlamak iyi bir uygulamadır.
Yinelemesiz
Yinelenen olmayan globlar genellikle kabul edilir.
Diğer kurallar
Sabit değerleri (ör.
GLOBAL_CONSTANT
) bildirmek için büyük harf ve alt çizgi, değişkenleri (ör.my_variable
) bildirmek için küçük harf ve alt çizgi kullanın.79 karakterden uzun olsa bile etiketler hiçbir zaman bölünmemelidir. Etiketler mümkün olduğunda dize değişmezleri olmalıdır. Açıklama: Bul ve değiştir özelliğini kolaylaştırır. Ayrıca okunabilirliği de iyileştirir.
Ad özelliğinin değeri, değişmez bir dize olmalıdır (makrolarda hariç). Mantık: Harici araçlar, bir kurala atıfta bulunmak için ad özelliğini kullanır. Kodu yorumlamak zorunda kalmadan kuralları bulmaları gerekir.
Boole türündeki özellikleri ayarlarken tam sayı değerlerini değil, boole değerlerini kullanın. Eski nedenlerden dolayı, kurallar tam sayıları gerektiğinde boole'lere dönüştürmeye devam eder ancak bu önerilmez. Mantıksal:
flaky = 1
, "bu hedefin tabanını bir kez yeniden çalıştırarak boşaltın" şeklinde yanlış okunabilir.flaky = True
açık bir şekilde "bu testte kesintisiz" diyor.
Python ile farklılıklar stil kılavuzu
Python stil kılavuzu ile uyumluluk hedef olsa da bazı farklılıklar 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 bu zorunlu değildir. Kod incelemelerinde veya ön gönderme komut dosyalarında zorunlu kılınmamalıdır. Mantıksal: 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 durum, satır uzunluğu sınırlamasına uygun değildir.Örtülü dize birleştirme desteklenmez.
+
operatörünü kullanın. Mantıksal:BUILD
dosyaları çok sayıda dize listesi içeriyor. Virgülü unutmak kolaydır ve bu da tamamen farklı bir sonuca yol açar. Bu durum geçmişte birçok hataya yol açmıştır. Bu tartışmaya da göz atın.Kurallardaki anahtar kelime bağımsız değişkenleri için
=
işaretinin çevresindeki boşluklar kullanın. Mantıksal: 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ırda yer alır. Alanlar okunabilirliği iyileştirir. Bu kural uzun zamandır kullanılıyor ve mevcut tümBUILD
dosyalarını değiştirmenize değmez.Varsayılan olarak, dizelerde çift tırnak kullanın. Mantık: Bu, Python stil kılavuzunda belirtilmemiştir ancak tutarlılık önerilir. Bu yüzden yalnızca çift tırnak içeren dizeler kullanmaya karar verdik. Birçok dil, dize değişmezleri için çift tırnak kullanır.
İki üst düzey tanım arasında tek bir boş satır kullanın. Mantıksal:
BUILD
dosyasının yapısı, tipik bir Python dosyasına benzer değildir. Yalnızca üst düzey ifadeler vardır. Tek bir boş satır kullanırsanızBUILD
dosyaları daha kısa olur.