BUILD
dosya biçimlendirmesi, Go ile aynı yaklaşımı izler. Burada standart bir araç, çoğu biçimlendirme sorununu halleder.
Buildifier, kaynak kodunu standart bir biçimde ayrıştıran ve yayınlayan bir araçtır. Dolayısıyla her BUILD
dosyası aynı otomatik şekilde biçimlendirilir. Böylece, kod incelemeleri sırasında biçimlendirme bir sorun teşkil etmez. 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 sırayı kullanın (her öğe isteğe bağlıdır):
Paket açıklaması (yorum)
load()
ekstrelerinin tümüpackage()
işlevi.Kural ve makrolara yönelik çağrılar
Geliştirici, bağımsız bir yorum ile bir öğeye eklenmiş yorum arasında ayrım yapar. Yorum belirli bir öğeye eklenmemişse yorumdan sonra boş bir satır kullanın. Bu ayrım, otomatik değişiklikler yaparken (örneğin, bir kuralı silerken bir yorumu tutmak veya kaldırmak) ö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öreli yollara başvurulmalıdır (hiçbir zaman ..
gibi yukarı başvurular kullanılmadan). Oluşturulan dosyaların kaynak olmadığını belirtmek için önek olarak ":
" eklenmelidir. Kaynak dosyaların başına :
eklenmemelidir. Kuralların önüne :
gelmelidir. Örneğin, x.cc
dosyası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. Bir hedefte bir kaynak dosya varsa hedef, genellikle söz konusu kaynaktan türetilmiş bir ada sahip olmalıdır (örneğin, chat.cc
için cc_library
chat
olarak adlandırılabilir veya DirectMessage.java
için java_library
öğesi direct_message
olarak adlandırılabilir).
Bir paketin adını veren hedef (içeren dizinle aynı ada sahip olan hedef), dizin adı ile açıklanan işlevi sağlamalıdır. Böyle bir hedef yoksa benzer 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. 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.
Geçerli bir ekip kurallarının olmadığı durumlarda, Google'da yaygın olarak kullanılan ve bağlayıcı olmayan bazı öneriler şunlar olabilir:
- Genel olarak "snake_case" parametresini kullanın
- Bir
src
içerenjava_library
için bu, uzantısı olmayan 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ı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 belirsizliği netleştirmek için bir son ek ekleyin (ör.
:foo_dev
,:foo_prod
veya:bar_x86
,:bar_x64
) _test
son eki;_test
,_unittest
,Test
veyaTests
ile hedefler_lib
veya_library
gibi anlamsız soneklerden kaçının (bir_library
hedefi ile karşılık gelen_binary
arasındaki çakışmaları önlemek için gerekli olmadığı sürece)- Proto ile ilgili hedefler için:
proto_library
hedefin adı_proto
ile biten olmalıdır- Dillere özgü
*_proto_library
kuralları, temel protokolle eşleşmeli ancak_proto
yerine aşağıdaki gibi dile özgü bir son ek getirilmelidir: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 kapsamı mümkün olduğunca dar olmalıdır. Ancak testler ve ters bağımlılıklarla erişime izin vermeye devam etmelidir. __pkg__
ve __subpackages__
öğelerini uygun şekilde kullanın.
default_visibility
paketini //visibility:public
değerine ayarlamaktan kaçının.
//visibility:public
, yalnızca projenin herkese açık API'sindeki hedefler için ayrı ayrı ayarlanmalıdır. Bunlar, harici projeler tarafından kullanılmak üzere tasarlanmış kitaplıklar veya harici bir projenin oluşturma süreci tarafından kullanılabilecek ikili programlar olabilir.
Bağımlılıklar
Bağımlılıklar, doğrudan bağımlılıklarla (kuralda listelenen kaynakların ihtiyaç duyduğu bağımlılıklar) ile sınırlı olmalıdır. Geçişli bağımlılıkları listelemeyin.
Paket-yerel bağımlılıkları ilk sırada listelenmeli ve yukarıdaki Mevcut paketteki hedeflere referanslar bölümüyle (mutlak paket adıyla değil) uyumlu bir şekilde atıfta bulunulmalıdır.
Bağımlılıkları doğrudan tek bir liste halinde listelemeyi tercih eder. Birkaç hedefin "ortak" bağımlılıkları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 hale getirir ve kullanılmayan bağımlılıklara yol açabilir.
Küre
[]
ile "hedef yok" seçeneğini belirtin. Hiçbir şeyle eşleşmeyen bir glob kullanmayın: Boş bir listeye göre hataya daha açıktır ve daha az belirgindir.
Yinelemeli
Kaynak dosyaları eşleştirmek için özyinelemeli glob'lar kullanmayın (örneğin, glob(["**/*.java"])
).
Yinelemeli glob'lar, BUILD
dosyalarını içeren alt dizinleri atladığı için BUILD
dosyalarıyla ilgili mantık yürütmeyi zorlaştırır.
Yinelemeli küreler genellikle, daha iyi bir uzaktan önbelleğe alma ve paralellik sağladığından, dizin başına bir bağımlılık grafiği içeren BUILD
dosyasına sahip olmaktan daha az verimlidir.
Her dizinde bir BUILD
dosyası yazmak ve bunlar arasında bir bağımlılık grafiği tanımlamak iyi bir uygulamadır.
Yinelemeli değil
Yinelemeli olmayan glob'lar genellikle kabul edilir.
Diğer kurallar
Sabit değerler belirtmek için büyük harf ve alt çizgi (
GLOBAL_CONSTANT
gibi), değişkenleri belirtmek için küçük ve alt çizgi kullanın (my_variable
gibi).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. Rasyonel: Bulma ve değiştirme işlemini kolaylaştırır. Ayrıca okunabilirliği de iyileştirir.
Ad özelliğinin değeri sabit bir dize olmalıdır (makrolar hariç). Rasyonale: Harici araçlar, bir kurala referans vermek için name özelliğini kullanır. Kodu yorumlamak zorunda kalmadan kuralları bulmaları gerekir.
Boole türü özellikleri ayarlarken tam sayı değerleri değil, boole değerleri kullanın. Eski nedenlerden dolayı, kurallar gerektiğinde tam sayıları yine de boole değerlerine dönüştürür, ancak bu önerilmez. Gerekçe:
flaky = 1
, "bu hedefi bir kez yeniden çalıştırarak bu hedefi rafa kaldırın" şeklinde yanlış anlaşılabilir.flaky = True
açık bir şekilde "bu test güvenilir değil" diyor.
Python stil kılavuzundaki farklar
Python stil kılavuzu ile uyumluluk hedef olsa da birkaç farklılık vardır:
Kesin bir satır uzunluğu sınırı yok. Uzun yorumlar ve uzun dizeler genellikle 79 sütuna bölünür, ancak zorunlu değildir. Kod incelemelerinde veya gönderim öncesi komut dosyalarında zorunlu kılınmamalıdır. Gerekçe: Etiketler uzun olabilir ve bu sınırı aşabilir.
BUILD
dosyalarının araçlar tarafından oluşturulması veya düzenlenmesi sık karşılaşılan bir durumdur. Bu da, satır uzunluğu sınırıyla iyi sonuç vermez.Dolaylı dize birleştirme desteklenmiyor.
+
operatörünü kullanın. Gerekçe:BUILD
dosya çok sayıda dize listesi içerir. Virgülü unutmak çok kolaydır, bu durumda bambaşka bir sonuç ortaya çıkar. Geçmişte bu durum pek çok hataya sebep 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. Rasyonale: Adlandırılmış bağımsız değişkenler Python'da olduğundan çok daha sıktır ve her zaman ayrı bir satırdadır. Alanlar, okunabilirliği iyileştirir. Bu kural uzun zamandır kullanılmaktadır ve mevcut tümBUILD
dosyalarını değiştirmeye değmez.Varsayılan olarak, dizeler için çift tırnak işareti kullanın. Rasyonale: Bu Python stil kılavuzunda belirtilmemiştir ancak tutarlılık önerilir. Bu yüzden sadece çift tırnaklı dizeleri kullanmaya karar verdik. Birçok dilde dize değişmez değerleri için çift tırnak kullanılır.
İki üst düzey tanım arasında tek bir boş satır kullanın. Rasyonale:
BUILD
dosyasının yapısı, tipik bir Python dosyası gibi değildir. Sadece üst düzey ifadeler içeriyor. Tek boş satır kullanmakBUILD
dosyalarını kısaltır.