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 gerçekleştirilir. Kilit dosyası, tutarlı geliştirme ortamları sağlayarak yeniden üretilebilir derlemeleri destekler. Ayrıca, Bazel'in proje bağımlılıklarındaki değişikliklerden etkilenmeyen çözümleme süreci kısımlarını atlamasına izin vererek 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 hata oluşma riskini azaltır.
Kilit dosyası oluşturma
Kilit dosyası, çalışma alanı kökü altında 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ılması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, kilit dosyasının mevcut derleme için gereken belirli bağımlılıklar kümesine odaklanmasını sağlayarak projenin çözümlenmiş bağımlılıklarının doğru bir şekilde gösterilmesini sağlar.
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 iptal edilen sürümler gibi değiştirilebilir bilgileri de yenilemez.refresh:update'a benzer ancak bu moda geçildiğinde ve bu moddayken yaklaşık her saatte bir değiştirilebilir bilgiler yenilenir.error:updategibi, 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ğ istekleri gerçekleştirmez. Kendilerinireproducibleolarak 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 tahmin edilebilir sonuçlar elde edebilir.
Hızlı artımlı çözümler. Kilit dosyası, Bazel'in önceki bir derlemede zaten kullanılmış olan kayıt dosyalarını indirmesini engeller. Bu, özellikle çözümlemenin 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 hata oluşma riskini azaltabilirsiniz.
uyumsuz veya test edilmemiş güncellemeler nedeniyle azalır.
Gizli kilit dosyası
Bazel ayrıca "$(bazel info output_base)"/MODULE.bazel.lock konumunda başka bir kilit dosyası 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 aracılığıyla çı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 durumda oluşturulmasının sonucu da yer alır. Kilit dosyası iki ana bölümden oluşur:
- Modül çözümlemesine giriş olarak kullanılan tüm uzak dosyaların karma değerleri.
- Her modül uzantısı için kilit dosyası,
bzlTransitiveDigest,usagesDigestve diğer alanlarla gösterilen, uzantıyı etkileyen girişlerin yanı sırageneratedRepoSpecsolarak 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. Çözümleme algoritması, aynı girişler verildiğinde tamamen deterministik olduğundan ve tüm uzak girişler karma oluşturma işlemine tabi tutulduğundan, bu durum, kilit dosyasında aşırı uzak bilgi kopyalanmasını ö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şebilir olan bu bilgiler bazel mod deps --lockfile_mode=refresh aracılığıyla güncellenebilir.
Bazel, indirmeden önce kayıt dosyalarını depodaki önbellekte aramak için kilit dosyasındaki karma değerlerini kullanır. Bu da sonraki çözümleri hızlandırır.
Seçilen geri çekilmiş sürümler
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ümler için boş değildir.
Bu alan, modül dosyalarına kıyasla geri çekilen sürüm bilgilerinin doğası gereği değiştirilebilir olması ve bu nedenle karma ile referans verilememesi nedeniyle 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. Başka 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, bu uzantıyla ilişkili bilgileri içerir:
bzlTransitiveDigest, uzantı uygulamasının ve bu uygulama tarafından geçişli olarak yüklenen .bzl dosyalarının özetidir.usagesDigest, tüm etiketleri içeren bağımlılık grafiğindeki uzantı kullanımlarının özetidir.- 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).
generatedRepoSpecs, uzantı tarafından oluşturulan depoları mevcut girişle kodlar.- İsteğe bağlı
moduleExtensionMetadataalanı, uzantı tarafından sağlanan meta verileri içerir. Örneğin, oluşturduğu belirli depoların kök modül tarafındanuse_repoaracılığıyla içe aktarılıp aktarılmayacağı gibi. Bu bilgiler,bazel mod tidykomutunu 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ık kümesine dayalı olması sağlanır. Tüm uzantıları aynı anda kilitlemek için
bazel mod deps --lockfile_mode=updatekomutunu çalıştırın.İşbirliğini 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 dahil edin. Bu sayede, proje genelinde tutarlı geliştirme ortamları sağlanır.
Bazel'i çalıştırmak için
bazeliskkomutunu kullanın ve kilit dosyasına karşılık gelen Bazel sürümünü belirten bir.bazelversiondosyasını sürüm kontrolüne 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.bazeliskkullanı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 çözmeye 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:
- jq'yu (1.5 veya sonraki sürümler) yükleyin.
- 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:
git reset MODULE.bazel.lock && git checkout MODULE.bazel.lockile kilit dosyasının önceki durumunu geri yükleyin.MODULE.bazeldosyasındaki çakışmaları giderin.- Kilit dosyasını güncellemek için
bazel mod depskomutunu çalıştırın.