Bazel'deki kilit dosyası özelliği, bir projenin ihtiyaç duyduğu yazılım kitaplıklarının veya paketlerinin belirli sürümlerinin ya da bağımlılıklarının kaydedilmesini sağlar. Bunu, modül çözümleme ve uzantı değerlendirmesinin sonucunu saklayarak yapar. Kilit dosyası, tutarlı geliştirme ortamları sağlayarak yeniden üretilebilir derlemeleri destekler. Ayrıca, Bazel'in çözüm sürecinin proje bağımlılıklarına yapılan değişikliklerden etkilenmeyen bölümlerini atlamasına olanak tanıyarak derleme verimliliğini artırır. Ayrıca kilit dosyası, harici kitaplıklarda beklenmedik güncellemeleri veya bozucu değişiklikleri önleyerek kararlılığı artırır ve böylece hata oluşturma riskini azaltır.
Kilit dosyası oluşturma
Kilit dosyası, MODULE.bazel.lock
adlı çalışma alanı kökü altında oluşturulur. Derleme işlemi sırasında, özellikle modül çözümleme ve uzantı değerlendirmesinden sonra oluşturulur veya güncellenir. Önemli bir nokta, yalnızca derlemenin mevcut çağrısına dahil edilen bağımlılıkları içermesidir.
Projede bağımlılıkları 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ık grubuna odaklanmaya devam eder ve projenin çözülmüş bağımlılıklarının doğru bir temsilini sağlar.
Kilit Dosyası 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 defteri dosyalarının indirme işlemlerini 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 kilit dosyasına eklenir. Bu modda Bazel, değişmeyen bağımlılıklarda da geri çekilen sürümler gibi değişken bilgileri yenilemekten kaçınır.refresh
:update
ile aynıdır ancak değişken bilgiler bu moda geçişte ve bu moddayken yaklaşık her saat yenilenir.error
:update
ile aynıdır ancak herhangi bir bilgi eksikse veya güncel değilse Bazel bir hatayla başarısız olur. Bu mod, kilit dosyasını hiçbir zaman değiştirmez veya çözüm sırasında ağ istekleri gerçekleştirmez. Kendilerinireproducible
olarak işaretleyen modül uzantıları, ağ isteklerini yerine getirmeye devam edebilir, ancak her zaman aynı sonucu vermeleri beklenir.off
: Kilit dosyası kontrol edilmez veya güncellenmez.
Kilit dosyası avantajları
Kilit dosyası çeşitli avantajlar sunar ve çeşitli şekillerde kullanılabilir:
Yeniden oluşturulabilir 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çlara güvenebilir.
Hızlı artımlı çözümler. Kilit dosyası, Bazel'in önceki bir derlemede kullanılmış olan kayıt defteri dosyalarını indirmesini önler. 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 bozucu değişiklikleri önleyerek kararlılığı korumaya yardımcı olur. Bağımlılıkları belirli sürümlere kilitleyerek uyumsuz veya test edilmemiş güncellemeler nedeniyle hata oluşma riski azaltılır.
Kilit Dosyası İçerikleri
Kilit dosyası, proje durumunun değişip değişmediğini belirlemek için gerekli tüm bilgileri içerir. Ayrıca projeyi mevcut haliyle kurmanın sonucunu da içerir. Kilit dosyası iki ana bölümden oluşur:
- Modül çözme işlemine giriş olan tüm uzak dosyaların karma oluşturma işlemleri.
- Kilit dosyası, her bir modül uzantısı için onu etkileyen girişleri (
bzlTransitiveDigest
,usagesDigest
ve diğer alanlarla temsil edilen) ve bu uzantıyı çalıştırmanın çıkışını (generatedRepoSpecs
olarak adlandırılır) içerir
Aşağıda, kilit dosyasının yapısını ve her bölümün açıklamalarını gösteren bir örnek 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ümlemesi sırasında erişilen uzaktan kayıt defterlerindeki tüm dosyaların karmalarını içerir. Çözüm algoritması aynı girişler verildiğinde tamamen belirlenir ve tüm uzak girişler karma oluşturma işlemine tabi tutulur. Bu sayede, kilit dosyasında uzak bilgilerin aşırı şekilde kopyalanmasını önlerken tamamen yeniden üretilebilir bir çözüm sonucu elde edilir. Bunun, belirli bir modülün belirli bir kayıt defterinde bulunmadığı ancak daha düşük önceliğe sahip bir kayıt defterinde bulunduğu durumlarda da kaydı gerektirdiğini unutmayın (örneğin, "not found" girişine bakın). Doğası gereği değişken olan bu bilgiler bazel mod deps --lockfile_mode=refresh
aracılığıyla güncellenebilir.
Bazel, indirmeden önce depo önbelleğinde kayıt defteri dosyalarını aramak için kilit dosyasındaki karmaları kullanır. Bu sayede sonraki çözümlemeleri hızlanır.
Seçilen Yanklanan Sürümler
selectedYankedVersions
bölümünde, modül çözünürlüğüne göre seçilen modüllerin kaldırılmış sürümleri yer alır. Bu durum, derleme sırasında genellikle bir hatayla sonuçlandığından yalnızca yankılanan sürümlere --allow_yanked_versions
veya BZLMOD_ALLOW_YANKED_VERSIONS
aracılığıyla açıkça izin verildiğinde bu bölüm boş bırakılamaz.
Modül dosyalarıyla karşılaştırıldığında yankı uygulanmış sürüm bilgileri doğası gereği değişebildiğinden ve bu nedenle karma tarafından referans gösterilemediğinden bu alan 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 kullanılan veya daha önce çağrılan uzantıları içeren ve artık kullanılmayan uzantıları hariç tutan bir haritadır. Diğer bir deyişle, bağımlılık grafiğinde artık kullanılmayan uzantılar 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 sisteminin, mimarinin veya her ikisinin adından yola çıkılarak adlandırılan birden fazla giriş eklenir. Bu girişlerin her biri, uzantının bu özelliklerle ilgili olarak değerlendirilmesinin sonucuna karşılık gelir.
Uzantı haritasındaki her giriş, kullanılan bir uzantıya karşılık gelir ve içeren dosyası ve adıyla tanımlanır. Her girişe karşılık gelen değer, söz konusu uzantıyla ilişkili bilgileri içerir:
bzlTransitiveDigest
, uzantı uygulamasının ve bu uygulama tarafından aktarmalı 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ıdaki 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ı geçerli 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ğı. Bu bilgilerbazel mod tidy
komutunu destekler.
Modül uzantıları, döndürülen meta verileri reproducible = True
ile ayarlayarak kilit dosyasına dahil edilmeyi devre dışı bırakabilir. Böylece, aynı girişlerle her zaman aynı depoları oluşturacaklarını taahhüt ederler.
En İyi Uygulamalar
Kilit dosyası özelliğinin avantajlarını en üst düzeye çıkarmak için aşağıdaki en iyi uygulamaları göz önünde bulundurun:
Kilit dosyasını, proje bağımlılıklarındaki veya yapılandırmadaki değişiklikleri yansıtacak şekilde düzenli olarak güncelleyin. Bu sayede, sonraki derlemeler en güncel ve doğru bağımlılık grubuna dayanır. Tüm uzantıları tek seferde 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şebilmesini sağlamak için kilit dosyasını sürüm kontrolüne dahil edin. Böylece proje genelinde tutarlı geliştirme ortamları oluşturabilirsiniz.
Bazel'i çalıştırmak için
bazelisk
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, derlemenizin bir 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
kullanmak, tüm geliştiricilerin kilit dosyasıyla eşleşen bir Bazel sürümü kullandığından emin olmanızı sağlar.
Bu en iyi uygulamaları izleyerek Bazel'deki kilit dosyası özelliğini etkili bir şekilde kullanarak daha verimli, güvenilir ve ortak çalışmaya dayalı yazılım geliştirme iş akışları elde edebilirsiniz.
Çakışmaları Birleştir
Kilit dosyası biçimi, birleştirme çakışmalarını en aza indirmek için tasarlanmıştır ancak yine de çakışmalar yaşanabilir.
Otomatik Çözünürlük
Bazel, bu çakışmaların otomatik olarak çözülmesine yardımcı olmak için özel bir git birleştirme sürücüsü sağlar.
Git deponuzun kökündeki bir .gitattributes
dosyasına şu satırı 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
Daha sonra, sürücüyü kullanmak isteyen her geliştiricinin aşağıdaki adımları uygulayarak sürücüyü bir kez kaydetmesi gerekir:
- jq'yi (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ında bulunan 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ışması türleri manuel olarak çözülmemelidir. Bunun yerine:
git reset MODULE.bazel.lock && git checkout MODULE.bazel.lock
aracılığıyla kilit dosyasının önceki durumunu geri yükleyin.MODULE.bazel
dosyasında çakışmaları giderin.- Kilit dosyasını güncellemek için
bazel mod deps
'ü çalıştırın.