DERLEME Stil Kılavuzu

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çeren java_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ın src öğelerinden biriyle eşleşmesini sağlar. java_test için bu, test_class özelliğinin hedef adından çıkarılabilmesini sağlar.
  • 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 veya Tests 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üm BUILD 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 kullanmak BUILD dosyalarını kısaltır.