BUILD dosya biçimlendirmesi, standartlaştırılmış bir aracın çoğu biçimlendirme sorununu ele aldığı Go ile aynı yaklaşımı izler.
Buildifier, 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. Böylece, biçimlendirme işlemi kod incelemeleri sırasında sorun oluşturmaz. 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 çıkışı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)
Tüm
load()ekstreleripackage()işlevi.Kurallara ve makrolara yapılan çağrılar
Buildifier, bağımsız yorum ile bir öğeye eklenmiş yorum arasında ayrım yapar. Bir yorum belirli bir öğeye eklenmemişse yorumdan sonra boş bir satır kullanın. Otomatik değişiklikler yaparken (ör. bir kuralı silerken yorumu tutmak veya kaldırmak) bu ayrım ö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 yapılan referanslar
Dosyalara, paket dizinine göre yollarıyla (.. gibi yukarı referanslar kullanılmadan) başvurulmalıdır. Oluşturulan dosyalar, kaynak olmadıklarını belirtmek için ":" ile öneklenmelidir. Kaynak dosyaların başına : eklenmemelidir. Kuralların önüne : eklenmelidir. Örneğin, x.cc dosyasının kaynak dosya olduğunu varsayarsak:
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 dosyası içeriyorsa hedef genellikle bu 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, direct_message olarak adlandırılabilir).
Bir paketin adaş hedefi (içeren dizinle aynı ada sahip hedef), dizin adıyla açıklanan işlevselliği sağlamalıdır. Böyle bir hedef yoksa aynı adlı bir hedef oluşturmayın.
Adını taşıyan bir hedefi (//x yerine //x:x) belirtirken kısa adı kullanın. Aynı paketteyseniz yerel referansı (:x yerine //x) kullanın.
Özel anlamı olan "ayrılmış" hedef adları kullanmaktan kaçının. all, __pkg__ ve __subpackages__ gibi adlar özel semantiğe sahiptir ve kullanıldıklarında kafa karışıklığına ve beklenmedik davranışlara neden olabilir.
Geçerli bir ekip kuralı yoksa bunlar Google'da yaygın olarak kullanılan, bağlayıcı olmayan bazı önerilerdir:
- Genel olarak "snake_case" kullanın.
- Bir
java_libraryiçin bu, uzantısız dosya adıyla aynı olmayan bir ad kullanmak anlamına gelir.src - Java
*_binaryve*_testkuralları için "Upper CamelCase" kullanın. Bu sayede hedef adı,srcdeğerlerinden biriyle eşleşebilir.java_testiçin bu,test_classözelliğinin hedefin adından çıkarılmasını sağlar.
- Bir
- Belirli bir hedefin birden fazla varyantı varsa netleştirmek için bir sonek ekleyin (ör.
:foo_dev,:foo_prodveya:bar_x86,:bar_x64) _testhedeflerine_test,_unittest,TestveyaTestsekleyin_libveya_librarygibi anlamsız eklerden kaçının (_libraryhedefi ile karşılık gelen_binaryarasındaki çakışmaları önlemek için gerekli olmadığı sürece)- Proto ile ilgili hedefler için:
proto_libraryhedeflerinin adları_protoile bitmelidir- Dile özgü
*_proto_librarykurallar, temel protokolle eşleşmeli ancak_proto, dile özgü bir sonek ile değiştirilmelidir. Örneğin:cc_proto_library:_cc_protojava_proto_library:_java_protojava_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 verecek şekilde mümkün olduğunca dar kapsamlı olmalıdır. Uygun şekilde __pkg__ ve __subpackages__ özelliğini 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ı ayrı ayarlanmalıdır. Bunlar, harici projelerin bağımlı olması için tasarlanmış kitaplıklar veya harici bir projenin derleme sürecinde kullanılabilecek ikili dosyalar olabilir.
Bağımlılıklar
Bağımlılıklar doğrudan bağımlılıklarla (kuralda listelenen kaynaklar için gereken bağımlılıklar) sınırlı olmalıdır. Geçişli bağımlılıkları listelemeyin.
Pakete özel bağımlılıklar önce listelenmeli ve yukarıdaki Geçerli paketteki hedeflere yapılan referanslar bölümüyle uyumlu bir şekilde (mutlak paket adlarıyla değil) referans verilmelidir.
Bağımlılıkları tek bir liste olarak doğrudan listelemeyi tercih edin. Çeşitli hedeflerin "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 hâle getirir ve kullanılmayan bağımlılıklara yol açabilir.
Globs
[] ile "hedef yok" ifadesini belirtin. Hiçbir şeyle eşleşmeyen bir glob kullanmayın. Bu, boş bir listeden daha fazla hataya neden olur ve daha az belirgindir.
Yinelemeli
Kaynak dosyaları eşleştirmek için yinelemeli glob'lar kullanmayın (örneğin, glob(["**/*.java"])).
Yinelemeli glob'lar, BUILD dosyalarını içeren alt dizinleri atladıkları için BUILD dosyaları hakkında akıl yürütmeyi zorlaştırır.
Özyinelemeli globlar, genellikle dizin başına bir BUILD dosyası oluşturmaktan daha az verimlidir. Bu dosyalarda, daha iyi uzaktan önbelleğe alma ve paralellik sağlayan bir bağımlılık grafiği tanımlanır.
Her dizinde bir BUILD dosyası oluşturmak ve bunlar arasında bir bağımlılık grafiği tanımlamak iyi bir uygulamadır.
Özyinelemeli olmayan
Genel olarak, yinelemeli olmayan glob'lar kabul edilebilir.
Diğer kurallar
Sabitleri (ör.
GLOBAL_CONSTANT) tanımlamak için büyük harf ve alt çizgi, değişkenleri (ör.my_variable) tanımlamak için küçük harf ve alt çizgi kullanın.Etiketler 79 karakterden uzun olsa bile asla bölünmemelidir. Etiketler mümkün olduğunda dize değişmezleri olmalıdır. Gerekçe: Bul ve değiştir özelliğini kolaylaştırır. Ayrıca okunabilirliği de artırır.
Ad özelliğinin değeri, değişmez bir sabit dize olmalıdır (makrolar hariç). Gerekçe: Harici araçlar, bir kurala başvurmak için ad özelliğini kullanır. Kullanıcıların, kodu yorumlamadan kuralları bulması gerekir.
Boole türü özellikler ayarlanırken tam sayı değerleri değil, Boole değerleri kullanılmalıdır. Eski nedenlerden dolayı kurallar, gerektiğinde tam sayıları hâlâ boole değerlerine dönüştürmektedir ancak bu durum önerilmez. Gerekçe:
flaky = 1, "Bu hedefi bir kez daha çalıştırarak temizle" şeklinde yanlış okunabilir.flaky = True, "bu test güvenilir değil" ifadesini net bir şekilde belirtiyor.
Python stil kılavuzuyla farklılıklar
Python stil kılavuzu ile uyumluluk hedefimiz olsa da birkaç fark 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 göndermeden önce çalıştırılan komut dosyalarında zorunlu tutulmamalıdır. Gerekçe: Etiketler uzun olabilir ve bu sınırı aşabilir.
BUILDdosyalarının araçlar tarafından oluşturulması veya düzenlenmesi yaygın bir durumdur. Bu durum, satır uzunluğu sınırı ile uyumlu değildir.Örtülü dize birleştirme desteklenmez.
+operatörünü kullanın. Gerekçe:BUILDdosyaları birçok dize listesi içeriyor. Virgülün unutulması kolaydır ve bu da tamamen farklı bir sonuç verir. Bu durum geçmişte birçok hataya neden oldu. Bu tartışmaya da göz atın.Kurallardaki anahtar kelime bağımsız değişkenleri için
=işaretinin etrafında boşluk kullanın. Gerekçe: 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. Boşluklar okunabilirliği artırır. Bu kural uzun süredir kullanılmaktadır ve mevcut tümBUILDdosyalarını değiştirmeye değmez.Varsayılan olarak dizeler için çift tırnak işareti kullanın. Gerekçe: Bu, Python stil kılavuzunda belirtilmemiştir ancak tutarlılık önerilir. Bu nedenle, yalnızca çift tırnaklı dizeler kullanmaya karar verdik. Birçok dilde, dize değişmezleri için çift tırnak kullanılır.
İki üst düzey tanım arasında tek bir boş satır kullanın. Gerekçe:
BUILDdosyasının yapısı, normal bir Python dosyasına benzemez. Yalnızca üst düzey ifadeler içerir. Tek bir boş satır kullanmakBUILDdosyalarını kısaltır.