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. Kendilerinireproducible
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:
- Modül çözünürlüğüne giriş olan tüm uzak dosyaların karma değerleri.
- Her modül uzantısı için kilit dosyası,
bzlTransitiveDigest
,usagesDigest
ve diğer alanlarla gösterilen, uzantıyı etkileyen girişlerin yanı sırageneratedRepoSpecs
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:
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ı
moduleExtensionMetadata
alanı, uzantı tarafından sağlanan meta verileri içerir. Örneğin, oluşturduğu belirli depoların kök modül tarafındanuse_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:
- 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.lock
ile kilit dosyasının önceki durumunu geri yükleyin.MODULE.bazel
dosyasındaki çakışmaları giderin.- Kilit dosyasını güncellemek için
bazel mod deps
komutunu çalıştırın.