Bazel Kilit Dosyası

Sorun bildir Kaynağı görüntüle Nightly · 8.4 · 8.3 · 8.2 · 8.1 · 8.0 · 7.6

Bazel'deki kilit dosyası özelliği, bir proje için gereken yazılım kitaplıklarının veya paketlerin belirli sürümlerinin ya da bağımlılıklarının kaydedilmesini sağlar. Bu, modül çözünürlüğünün ve uzantı değerlendirmesinin sonucunu depolayarak sağlanır. Kilit dosyası, tutarlı geliştirme ortamları sağlayarak tekrarlanabilir derlemeleri destekler. Ayrıca, Bazel'in çözümleme sürecinin proje bağımlılıklarındaki değişikliklerden etkilenmeyen kısımlarını atlamasına olanak tanıyarak derleme verimliliğini artırır. Ayrıca, kilit dosyası harici kitaplıklarda beklenmedik güncellemeleri veya değişiklikleri önleyerek kararlılığı artırır ve böylece hataların ortaya çıkma riskini azaltır.

Kilit dosyası oluşturma

Kilit dosyası, çalışma alanı kökünde MODULE.bazel.lock adıyla oluşturulur. Derleme işlemi sırasında, özellikle modül çözümü ve uzantı değerlendirmesinden sonra oluşturulur veya güncellenir. Önemli olarak, yalnızca derlemenin mevcut çağrısına dahil edilen bağımlılıkları içerir.

Projede bağımlılıklarını etkileyen değişiklikler olduğunda, kilit dosyası yeni durumu yansıtacak şekilde otomatik olarak güncellenir. Bu sayede, kilit dosyası mevcut derleme için gereken belirli bağımlılıklar kümesine odaklanmaya devam eder ve projenin çözümlenmiş bağımlılıklarını doğru bir şekilde temsil eder.

Lockfile Kullanımı

Proje durumu kilit dosyasından farklı olduğunda Bazel'in davranışını özelleştirmek için kilit dosyası --lockfile_mode işaretiyle kontrol edilebilir. Kullanılabilir modlar şunlardır:

  • update (Varsayılan): Bilinen kayıt dosyalarının indirilmesini atlamak ve sonuçları hâlâ güncel olan uzantıların yeniden değerlendirilmesini önlemek için kilit dosyasında bulunan bilgileri kullanın. Eksik bilgiler varsa kilit dosyasına eklenir. Bu modda Bazel, değişmeyen bağımlılıklar için geri çekilen sürümler gibi değiştirilebilir bilgileri de yenilemekten kaçınır.
  • refresh: update'a benzer ancak bu moda geçildiğinde ve bu moddayken yaklaşık her saatte bir değiştirilebilir bilgiler yenilenir.
  • error: update gibi, ancak herhangi bir bilgi eksikse veya güncel değilse Bazel hata vererek başarısız olur. Bu mod, çözümleme sırasında hiçbir zaman kilit dosyasını değiştirmez veya ağ isteğinde bulunmaz. Kendilerini reproducible olarak işaretleyen modül uzantıları, ağ istekleri gerçekleştirmeye devam edebilir ancak her zaman aynı sonucu üretmesi beklenir.
  • off: Kilit dosyası ne kontrol edilir ne de güncellenir.

Lockfile'ın avantajları

Kilit dosyası çeşitli avantajlar sunar ve farklı şekillerde kullanılabilir:

  • Yeniden üretilebilir derlemeler. Kilit dosyası, yazılım kitaplıklarının belirli sürümlerini veya bağımlılıklarını yakalayarak derlemelerin farklı ortamlarda ve zaman içinde yeniden üretilebilir olmasını sağlar. Geliştiriciler, projelerini oluştururken tutarlı ve öngörülebilir sonuçlar elde edebilir.

  • Hızlı artımlı çözümler. Kilit dosyası, Bazel'in önceki bir derlemede zaten kullanılan kayıt dosyalarını indirmesini engeller. Bu, özellikle çözümün zaman alabileceği senaryolarda derleme verimliliğini önemli ölçüde artırır.

  • Kararlılık ve risk azaltma. Kilit dosyası, harici kitaplıklarda beklenmedik güncellemeleri veya önemli değişiklikleri önleyerek kararlılığın korunmasına yardımcı olur. Bağımlılıkları belirli sürümlere kilitleyerek hataların ortaya çıkma riskini azaltabilirsiniz.

    uyumsuz veya test edilmemiş güncellemeler nedeniyle azalır.

Gizli kilit dosyası

Bazel, "$(bazel info output_base)"/MODULE.bazel.lock konumunda başka bir kilit dosyası da tutar. Bu kilit dosyasının biçimi ve içeriği açıkça belirtilmemiştir. Yalnızca performans optimizasyonu olarak kullanılır. bazel clean --expunge ile çıktı tabanıyla birlikte silinebilse de bunu yapma ihtiyacı, Bazel'in kendisinde veya bir modül uzantısında bir hatadır.

Lockfile İçeriği

Kilit dosyası, proje durumunun değişip değişmediğini belirlemek için gerekli tüm bilgileri içerir. Ayrıca, projenin mevcut durumdaki halinin oluşturulmasıyla ilgili sonuç da yer alır. Kilit dosyası iki ana bölümden oluşur:

  1. Modül çözünürlüğüne giriş olan tüm uzak dosyaların karma değerleri.
  2. Her modül uzantısı için kilit dosyası, bzlTransitiveDigest, usagesDigest ve diğer alanlarla gösterilen, uzantıyı etkileyen girişlerin yanı sıra generatedRepoSpecs olarak adlandırılan, uzantının çalıştırılmasının sonucunu içerir.

Aşağıda, kilit dosyasının yapısını gösteren bir örnek ve her bölümle ilgili açıklamalar verilmiştir:

{
  "lockFileVersion": 10,
  "registryFileHashes": {
    "https://bcr.bazel.build/bazel_registry.json": "8a28e4af...5d5b3497",
    "https://bcr.bazel.build/modules/foo/1.0/MODULE.bazel": "7cd0312e...5c96ace2",
    "https://bcr.bazel.build/modules/foo/2.0/MODULE.bazel": "70390338... 9fc57589",
    "https://bcr.bazel.build/modules/foo/2.0/source.json": "7e3a9adf...170d94ad",
    "https://registry.mycorp.com/modules/foo/1.0/MODULE.bazel": "not found",
    ...
  },
  "selectedYankedVersions": {
    "foo@2.0": "Yanked for demo purposes"
  },
  "moduleExtensions": {
    "//:extension.bzl%lockfile_ext": {
      "general": {
        "bzlTransitiveDigest": "oWDzxG/aLnyY6Ubrfy....+Jp6maQvEPxn0pBM=",
        "usagesDigest": "aLmqbvowmHkkBPve05yyDNGN7oh7QE9kBADr3QIZTZs=",
        ...,
        "generatedRepoSpecs": {
          "hello": {
            "bzlFile": "@@//:extension.bzl",
            ...
          }
        }
      }
    },
    "//:extension.bzl%lockfile_ext2": {
      "os:macos": {
        "bzlTransitiveDigest": "oWDzxG/aLnyY6Ubrfy....+Jp6maQvEPxn0pBM=",
        "usagesDigest": "aLmqbvowmHkkBPve05y....yDNGN7oh7r3QIZTZs=",
        ...,
        "generatedRepoSpecs": {
          "hello": {
            "bzlFile": "@@//:extension.bzl",
            ...
          }
        }
      },
      "os:linux": {
        "bzlTransitiveDigest": "eWDzxG/aLsyY3Ubrto....+Jp4maQvEPxn0pLK=",
        "usagesDigest": "aLmqbvowmHkkBPve05y....yDNGN7oh7r3QIZTZs=",
        ...,
        "generatedRepoSpecs": {
          "hello": {
            "bzlFile": "@@//:extension.bzl",
            ...
          }
        }
      }
    }
  }
}

Kayıt defteri dosyası karmaları

registryFileHashes bölümü, modül çözümü sırasında erişilen uzak kayıt defterlerindeki tüm dosyaların karma değerlerini içerir. Aynı girişler verildiğinde çözümleme algoritması tamamen deterministik olduğundan ve tüm uzak girişler karma oluşturma işlemine tabi tutulduğundan, bu durum, kilit dosyasında uzak bilgilerin aşırı derecede yinelenmesini önlerken tamamen yeniden üretilebilir bir çözümleme sonucu sağlar. Bunun, belirli bir kayıt defteri belirli bir modülü içermediğinde ancak daha düşük önceliğe sahip bir kayıt defteri içerdiğinde de kayıt gerektirdiğini unutmayın (örnekteki "bulunamadı" girişine bakın). Doğası gereği değiştirilebilir olan bu bilgiler bazel mod deps --lockfile_mode=refresh aracılığıyla güncellenebilir.

Bazel, kayıt dosyalarını indirmeden önce depo önbelleğinde aramak için kilit dosyasındaki karma değerlerini kullanır. Bu da sonraki çözümleri hızlandırır.

Seçilen Yanked Sürümleri

selectedYankedVersions bölümü, modül çözümleme tarafından seçilen modüllerin kaldırılmış sürümlerini içerir. Bu durum genellikle derleme sırasında hataya neden olduğundan bu bölüm yalnızca --allow_yanked_versions veya BZLMOD_ALLOW_YANKED_VERSIONS aracılığıyla açıkça izin verilen yanked sürümlerinde boş değildir.

Bu alan, modül dosyalarına kıyasla geri çekilen sürüm bilgileri doğası gereği değiştirilebilir olduğundan ve bu nedenle karma ile referans verilemediğinden gereklidir. Bu bilgiler bazel mod deps --lockfile_mode=refresh üzerinden güncellenebilir.

Modül Uzantıları

moduleExtensions bölümü, yalnızca mevcut çağrıda veya daha önce çağrılan uzantıları içeren, artık kullanılmayan uzantıları ise hariç tutan bir haritadır. Diğer bir deyişle, bir uzantı bağımlılık grafiğinde artık kullanılmıyorsa moduleExtensions haritasından kaldırılır.

Bir uzantı işletim sisteminden veya mimari türünden bağımsızsa bu bölümde yalnızca tek bir "genel" giriş bulunur. Aksi takdirde, işletim sistemine, mimariye veya her ikisine göre adlandırılmış birden fazla giriş eklenir. Her giriş, uzantının bu özellikler üzerinde değerlendirilmesinin sonucuna karşılık gelir.

Uzantı eşlemesindeki her giriş, kullanılan bir uzantıya karşılık gelir ve içerdiği dosya ve adıyla tanımlanır. Her girişin karşılık gelen değeri, ilgili uzantıyla ilişkili bilgileri içerir:

  1. bzlTransitiveDigest, uzantı uygulamasının ve bu uygulama tarafından geçişli olarak yüklenen .bzl dosyalarının özetidir.
  2. usagesDigest, tüm etiketleri içeren bağımlılık grafiğindeki uzantı kullanımlarının özetidir.
  3. Uzantıya yapılan diğer girişleri izleyen, belirtilmemiş diğer alanlar (ör. okuduğu dosyaların veya dizinlerin içeriği ya da kullandığı ortam değişkenleri).
  4. generatedRepoSpecs, uzantı tarafından oluşturulan depoları mevcut girişle kodlar.
  5. İsteğe bağlı moduleExtensionMetadata alanı, uzantı tarafından sağlanan meta verileri içerir. Örneğin, oluşturduğu belirli depoların kök modül tarafından use_repo aracılığıyla içe aktarılıp aktarılmayacağı gibi bilgiler bu meta veriler arasındadır. Bu bilgiler, bazel mod tidy komutunu destekler.

Modül uzantıları, reproducible = True ile döndürülen meta verileri ayarlayarak kilit dosyasına dahil edilmeyi devre dışı bırakabilir. Bunu yaparak, aynı girişler verildiğinde her zaman aynı depoları oluşturacaklarını taahhüt ederler.

En İyi Uygulamalar

Kilit dosyası özelliğinin avantajlarından en iyi şekilde yararlanmak için aşağıdaki en iyi uygulamaları göz önünde bulundurun:

  • Proje bağımlılıklarındaki veya yapılandırmadaki değişiklikleri yansıtmak için kilit dosyasını düzenli olarak güncelleyin. Bu sayede, sonraki derlemelerin en güncel ve doğru bağımlılıklar kümesine dayalı olması sağlanır. Tüm uzantıları aynı anda kilitlemek için bazel mod deps --lockfile_mode=update komutunu çalıştırın.

  • Ortak çalışmayı kolaylaştırmak ve tüm ekip üyelerinin aynı kilit dosyasına erişmesini sağlamak için kilit dosyasını sürüm kontrolüne ekleyin. Böylece proje genelinde tutarlı geliştirme ortamları sağlanır.

  • Bazel'i çalıştırmak için bazelisk komutunu kullanın ve sürüm kontrolüne, kilit dosyasına karşılık gelen Bazel sürümünü belirten bir .bazelversion dosyası ekleyin. Bazel'in kendisi derlemenizin bağımlılığı olduğundan kilit dosyası Bazel sürümüne özeldir ve geriye dönük uyumlu Bazel sürümleri arasında bile değişir. bazelisk kullanıldığında tüm geliştiricilerin kilit dosyasıyla eşleşen bir Bazel sürümü kullandığından emin olunur.

Bu en iyi uygulamaları izleyerek Bazel'deki kilit dosyası özelliğini etkili bir şekilde kullanabilir, böylece daha verimli, güvenilir ve işbirlikçi yazılım geliştirme iş akışları oluşturabilirsiniz.

Birleştirme Çakışmaları

Kilit dosyası biçimi, birleştirme çakışmalarını en aza indirecek şekilde tasarlanmıştır ancak yine de çakışmalar yaşanabilir.

Otomatik Çözüm

Bazel, bu çakışmaları otomatik olarak çözmenize yardımcı olmak için özel bir git merge sürücüsü sağlar.

Bu satırı, Git deponuzun kökündeki bir .gitattributes dosyasına ekleyerek sürücüyü ayarlayın:

# A custom merge driver for the Bazel lockfile.
# https://bazel.build/external/lockfile#automatic-resolution
MODULE.bazel.lock merge=bazel-lockfile-merge

Ardından, sürücüyü kullanmak isteyen her geliştiricinin aşağıdaki adımları uygulayarak sürücüyü bir kez kaydetmesi gerekir:

  1. jq'yu (1.5 veya sonraki sürümler) yükleyin.
  2. Aşağıdaki komutları çalıştırın:
jq_script=$(curl https://raw.githubusercontent.com/bazelbuild/bazel/master/scripts/bazel-lockfile-merge.jq)
printf '%s\n' "${jq_script}" | less # to optionally inspect the jq script
git config --global merge.bazel-lockfile-merge.name   "Merge driver for the Bazel lockfile (MODULE.bazel.lock)"
git config --global merge.bazel-lockfile-merge.driver "jq -s '${jq_script}' -- %O %A %B > %A.jq_tmp && mv %A.jq_tmp %A"

Manuel Çözüm

registryFileHashes ve selectedYankedVersions alanlarındaki basit birleştirme çakışmaları, çakışmanın her iki tarafındaki tüm girişler korunarak güvenli bir şekilde çözülebilir.

Diğer birleştirme çakışmaları manuel olarak çözülmemelidir. Bunun yerine:

  1. git reset MODULE.bazel.lock && git checkout MODULE.bazel.lock ile kilit dosyasının önceki durumunu geri yükleyin.
  2. MODULE.bazel dosyasındaki çakışmaları giderin.
  3. Kilit dosyasını güncellemek için bazel mod deps komutunu çalıştırın.