DERLEME Stil Kılavuzu

Sorun bildir Kaynağı göster Nightly · 8.0 · 7.4 · 7.3 · 7.2 · 7.1 · 7.0 · 6.5

BUILD dosya biçimlendirmesi, Go ile aynı yaklaşımı izler. Bu yaklaşımda, standartlaştırılmış bir araç çoğu biçimlendirme sorununu çözer. 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ı 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)

  • Tüm load() hesap özetleri

  • package() işlevi.

  • Kural ve makro çağrıları

Buildifier, bağımsız yorumlar ile bir öğeye eklenmiş yorumlar arasında ayrım yapar. Bir 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 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")

Mevcut paketteki hedeflere referanslar

Dosyalara, paket dizine göreli yollarıyla referans verilmelidir (.. gibi üst referanslar kullanılmamalıdır). Oluşturulan dosyaların önüne, kaynak olmadıklarını belirtmek için ":" eklenmelidir. Kaynak dosyaların önüne : 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 hedeften bahsederken kısa adı 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" değerini kullanın
    • Bir src içeren java_library için bu, uzantı olmadan dosya adıyla aynı olmayan bir ad kullanılması anlamına gelir.
    • Java *_binary ve *_test kuralları için "Büyük CamelCase" kullanın. Bu, hedef adının src değerlerinden biriyle eşleşmesini sağlar. java_test için bu, test_class özelliğinin hedefin adından çıkarılmasını sağlar.
  • 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, _unittest, Test veya Tests ile _test son eki hedefleri
  • _lib veya _library gibi anlamsız son ekler kullanmaktan kaçının (_library hedefi ile ilgili _binary arasında çakışmaları önlemek için gerekli olmadığı sürece)
  • Proto ile ilgili hedefler için:
    • proto_library hedeflerinin adları _proto ile bitmelidir
    • Dillere özgü *_proto_library kuralları, temel proto ile eşleşmelidir ancak _proto, aşağıdaki gibi dile özgü bir son ek ile değiştirilmelidir:
      • 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. Uygun durumlarda __pkg__ ve __subpackages__ özelliğini 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

"Hedef yok"u [] ile belirtin. Hiçbir şeyle eşleşmeyen bir glob kullanmayın: Boş bir listeden daha hatalara açık ve daha belirsizdir.

Yinelemeli

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 globlar, genellikle daha iyi uzaktan önbelleğe alma ve paralellik sağladığı için dizin başına aralarında bir bağımlılık grafiği tanımlanmış bir BUILD dosyasına sahip olmaktan daha az verimlidir.

Her dizinde bir BUILD dosyası oluşturmak 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 sözleşmeler

  • Sabitler için büyük harf ve alt çizgi (GLOBAL_CONSTANT gibi), değişkenler için 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şmezleri olmalıdır. Rationale: 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 dize olmalıdır (makrolarda hariç). Rationale: 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ğerleri değil, boole değerleri kullanın. Eskiden olduğu gibi kurallar, gerektiğinde tam sayıları doğru/yanlış değerlere dönüştürmeye devam eder ancak bu işlemden kaçınılması önerilir. Rationale: flaky = 1, "bu hedefi bir kez yeniden çalıştırarak deflake et" şeklinde yanlış okunabilir. flaky = True, "bu test kararsız" ifadesini net bir şekilde belirtmelidir.

Python stil kılavuzuyla arasındaki farklar

Python stil kılavuzu ile uyumluluk hedef olsa da birkaç fark vardır:

  • Satır uzunluğu için katı bir 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 komut dosyalarında zorunlu kılınmamalıdır. Rationale: 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 da satır uzunluğu sınırıyla uyumlu değildir.

  • Örtülü dize birleştirme desteklenmez. + operatörünü kullanın. Rationale: BUILD dosyaları birçok dize listesi içerir. 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 etrafında boşluk kullanın. Rationale: Adlandırılmış bağımsız değişkenler, Python'a kıyasla ç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 zamandır kullanılıyor ve mevcut tüm BUILD dosyalarını değiştirmeye değmez.

  • Varsayılan olarak, dizelerde çift tırnak kullanın. Rationale: Bu, Python stil kılavuzunda belirtilmemiştir ancak tutarlılık önerilir. Bu nedenle, yalnızca çift tırnak içine alınmış dizeleri 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. Rationale: BUILD dosyasının yapısı, tipik bir Python dosyasına benzemez. Yalnızca üst düzey ifadeler içerir. Tek boş satır kullanmak BUILD dosyalarını kısaltır.