Bazel modülleri

Sorun bildir Kaynağı göster

Bazel modülü, her biri bağlı olduğu diğer modüller hakkında meta veri yayınlayan birden çok sürümü olabilen bir Bazel projesidir. Bu; Maven yapısı, npm paketi, Go modülü veya kargo sandığı gibi diğer bağımlılık yönetimi sistemlerindeki bilindik kavramlara benzer.

Bir modülün deposunda MODULE.bazel dosyası olmalıdır. Bu dosya modülün manifest dosyasıdır. Burada dosyanın adı, sürümü, doğrudan bağımlılık listesi ve diğer bilgiler belirtilir. Temel bir örnek vermek gerekirse:

module(name = "my-module", version = "1.0")

bazel_dep(name = "rules_cc", version = "0.0.1")
bazel_dep(name = "protobuf", version = "3.19.0")

MODULE.bazel dosyalarında bulunan yönergelerin tam listesini inceleyin.

Bazel, modül çözümlemesi gerçekleştirmek için işe kök modülün MODULE.bazel dosyasını okuyarak başlar ve ardından bağımlılık grafiğinin tamamını keşfedene kadar Bazel kayıt defterinden herhangi bir bağımlılığın MODULE.bazel dosyasını sürekli olarak ister.

Varsayılan olarak Bazel, kullanılacak her bir modülün bir sürümünü seçer. Bazel her modülü bir depo ile temsil eder ve her depoyu tanımlamayı öğrenmek için kayıt otoritesine tekrar danışır.

Sürüm biçimi

Bazel çeşitlilik içeren bir ekosisteme sahiptir ve projelerde farklı sürüm oluşturma şemaları kullanılmaktadır. Açık farkla en popüler olan SemVer ancak Abseil gibi farklı şemaların kullanıldığı önemli projeler de vardır. Bu tür projeler tarih tabanlıdır (ör. 20210324.2).

Bu nedenle Bzlmod, SemVer spesifikasyonunun daha rahat bir sürümünü kullanır. Aralarındaki farklar şunlardır:

  • SemVer, sürümün "yayınlama" bölümünün 3 segmentten oluşması gerektiğini belirtir: MAJOR.MINOR.PATCH. Bazel'de bu şart gevşetilerek istenilen sayıda segmente izin verilir.
  • SemVer'de, "sürüm" bölümündeki her segment yalnızca rakamlardan oluşmalıdır. Bazel'de bu ayar harflere izin verilecek şekilde gevşetildi ve karşılaştırma semantiği, "yayın öncesi" bölümündeki "tanımlayıcılar"la eşleşiyor.
  • Ayrıca ana, küçük ve yama sürümlerinin anlamları zorunlu kılınmaz. Ancak geriye dönük uyumluluğu nasıl belirttiğimiz hakkında ayrıntılar için uyumluluk düzeyi konusuna bakın.

Geçerli SemVer sürümleri, geçerli bir Bazel modülü sürümüdür. Ayrıca, iki SeVer sürümü a ve b a < b, yalnızca Bazel modülü sürümleriyle karşılaştırıldığında aynı durum geçerliyse ve bu iki uygulamayı da karşılaştırır.

Sürüm seçimi

Sürümlü bağımlılık yönetimi alanının en önemli özelliklerinden biri olan elmas bağımlılık sorununu düşünün. Bağımlılık grafiğinin mevcut olduğunu varsayalım:

       A 1.0
      /     \
   B 1.0    C 1.1
     |        |
   D 1.0    D 1.1

Hangi D sürümü kullanılmalıdır? Bzlmod, bu soruyu çözmek için Go modül sisteminde sunulan Minimal Sürüm Seçimi (MVS) algoritmasını kullanır. MVS, bir modülün tüm yeni sürümlerinin geriye dönük uyumlu olduğunu varsayar ve bu nedenle herhangi bir bağımlı (örneğimizde D 1.1) tarafından belirtilen en yüksek sürümü seçer. D 1.1, gereksinimlerimizi karşılayabilecek en eski sürüm olduğundan "minimal" olarak adlandırılmıştır. D 1.2 veya daha yeni bir sürüm mevcut olsa bile bu sürüm seçilmez. MVS kullanmak, yüksek kaliteli ve yeniden oluşturulabilir bir sürüm seçme süreci oluşturur.

Yanked sürümleri

Kayıt defteri, belirli sürümlerin kaçınılması gerekiyorsa (güvenlik açıkları gibi) yanklandı olarak tanımlanabilir. Bazel, bir modülün uzaktaki sürümünü seçirken hata veriyor. Bu hatayı düzeltmek için daha yeni, yakalanmamış bir sürüme yükseltin veya çekilen sürüme açıkça izin vermek için --allow_yanked_versions işaretini kullanın.

Uyumluluk düzeyi

Go'da MVS'nin geriye dönük uyumluluk varsayımı, bir modülün geriye dönük uyumsuz sürümlerini ayrı bir modül olarak işlediği için işe yarar. SeVer açısından bu, A 1.x ve A 2.x'nin ayrı modüller olarak kabul edildiği ve çözülmüş bağımlılık grafiğinde bir arada bulunabileceği anlamına gelir. Bu da Go'daki paket yolundaki ana sürümün kodlanmasıyla mümkün olur. Böylece herhangi bir derleme zamanı veya bağlantı süresi çakışması olmaz.

Ancak Bazel, bu tür garantiler veremeyeceğinden geriye dönük olarak uyumsuz sürümlerin algılanması için "ana sürüm" numarası gereklidir. Bu sayı, uyumluluk düzeyi olarak adlandırılır ve her modül sürümü tarafından module() yönergesinde belirtilir. Bazel bu bilgileri kullanarak aynı modülün farklı uyumluluk düzeylerine sahip sürümlerinin çözümlenmiş bağımlılık grafiğinde bulunduğunu tespit ettiğinde hata verebilir.

Geçersiz kılar:

Bazel modül çözünürlüğünün davranışını değiştirmek için MODULE.bazel dosyasında geçersiz kılmaları belirtin. Yalnızca kök modülün geçersiz kılmaları geçerli olur. Modül bağımlılık olarak kullanılıyorsa geçersiz kılma işlemleri yoksayılır.

Her geçersiz kılma, belirli bir modül adı için belirtilir ve bağımlılık grafiğindeki tüm sürümlerini etkiler. Yalnızca kök modülün geçersiz kılmaları etkili olsa da, kök modülün doğrudan bağımlı olmadığı geçişli bağımlılıklarda olabilirler.

Tek sürüm geçersiz kılma

single_version_override birden fazla amaca hizmet eder:

  • version özelliğini kullanarak, bağımlılık grafiğinde hangi sürümlerin istendiğine bakılmaksızın, bir bağımlılığı belirli bir sürüme sabitleyebilirsiniz.
  • registry özelliğiyle, bu bağımlılığı normal kayıt otoritesi seçim süreci yerine belirli bir kayıt defterinden gelmeye zorlayabilirsiniz.
  • patch* özellikleriyle, indirilen modüle uygulanacak bir yama grubu belirtebilirsiniz.

Bu özelliklerin tümü isteğe bağlıdır ve birbirleriyle karıştırılıp eşleştirilebilir.

Birden çok sürümü geçersiz kılma

multiple_version_override, çözümlenen bağımlılık grafiğinde aynı modülün birden fazla sürümünün bir arada bulunmasını sağlamak için belirtilebilir.

Modül için izin verilen sürümlerin açık bir listesini belirtebilirsiniz. Bu listenin çözümlenmeden önce bağımlılık grafiğinde bulunması gerekir. İzin verilen her sürüme bağlı olarak bir geçişli bağımlılık olmalıdır. Çözümlendikten sonra yalnızca modülün izin verilen sürümleri kalırken Bazel, modülün diğer sürümlerini aynı uyumluluk düzeyinde izin verilen en yakın sürüme yükseltir. Aynı uyumluluk düzeyinde izin verilen daha yüksek bir sürüm yoksa Bazel bir hata bildirir.

Örneğin, bağımlılık grafiğinde çözümden önce 1.1, 1.3, 1.5, 1.7 ve 2.0 sürümleri yer alıyorsa ve ana sürüm uyumluluk düzeyiyse:

  • 1.3, 1.7 ve 2.0 uygulamalarına izin veren çoklu sürüm geçersiz kılma işlemi, 1.1 uygulamasının 1.3 sürümüne yükseltilmesine, 1.5 uygulamasının 1.7 sürümüne yükseltilmesine ve diğer sürümlerde aynı kalmanın sağlanmasına neden olur.
  • 1.7 ürününün yükseltme yapılacak aynı uyumluluk düzeyinde daha yüksek bir sürümü olmadığından 1.5 ve 2.0 uygulamalarına izin veren birden çok sürüm geçersiz kılma işlemi hatayla sonuçlanır.
  • Çözümden önce bağımlılık grafiğinde 1.9 bulunmadığından, 1.9 ve 2.0 uygulamalarına izin veren çok sürümlü bir geçersiz kılma hata verir.

Ayrıca kullanıcılar, tek sürüm geçersiz kılmalarına benzer şekilde registry özelliğini kullanarak kayıt defterini de geçersiz kılabilir.

Kayıt otoritesi dışında geçersiz kılma işlemleri

Kayıt defteri dışı geçersiz kılmalar, bir modülü sürüm çözünürlüğünden tamamen kaldırır. Bazel, bu MODULE.bazel dosyalarını bir kayıt defterinden değil, deponun kendisinden ister.

Bazel, aşağıdaki kayıt defteri olmayan geçersiz kılma işlemlerini destekler:

Bazel modüllerini temsil etmeyen depolar tanımlama

bazel_dep ile diğer Bazel modüllerini temsil eden depolar tanımlayabilirsiniz. Bazen bir Bazel modülünü temsil etmeyen bir depo (ör. veri olarak okunacak düz bir JSON dosyası içeren) tanımlanması gerekir.

Bu durumda, bir depo kuralı çağırarak doğrudan bir depo tanımlamak için use_repo_rule yönergesini kullanabilirsiniz. Bu depo yalnızca tanımlandığı modül tarafından görülebilir.

Temel olarak bu işlem, modül uzantıları ile aynı mekanizma kullanılarak uygulanır. Bu da depoları daha esnek bir şekilde tanımlamanıza olanak tanır.

Depo adları ve katı depolar

Bir modülü doğrudan bağımlılarına destekleyen bir deponun görünen adı, bazel_dep yönergesinin repo_name özelliği aksini söylemediği sürece varsayılan olarak modül adına ayarlanır. Bunun, bir modülün yalnızca doğrudan bağımlılıklarını bulabileceği anlamına geldiğini unutmayın. Böylece geçişli bağımlılıklardaki değişikliklerden dolayı kazayla bozulmalar yaşanmayabilir.

Bağımlılık grafiğinin tamamında modülün birden fazla sürümünün olup olmamasına bağlı olarak, modülü destekleyen bir deponun standart adı module_name~version (ör. bazel_skylib~1.0.3) veya module_name~ (ör. bazel_features~) şeklindedir (bkz. multiple_version_override). Standart ad biçiminin güvenmeniz gereken bir API olmadığını ve her an değişebileceğini unutmayın. Standart adı sabit bir şekilde kodlamak yerine, doğrudan Bazel'den almak için desteklenen bir yol kullanın: * BUILD ve .bzl dosyalarında, kod deposunun görünen adıyla verilen bir etiket dizesinden oluşturulan Label örneğinde Label.repo_name kullanın. Label("@bazel_skylib").repo_name. * Runfile ararken @bazel_tools//tools/{bash,cpp,java}/runfiles içindeki $(rlocationpath ...) veya runfiles kitaplıklarından birini ya da rules_foo kural kümesi için @rules_foo//foo/runfiles içinde kullanın. * IDE veya dil sunucusu gibi harici bir araçtan Bazel ile etkileşim kurarken, belirli bir depo grubu için görünen adlardan standart adlara eşlemeyi almak için bazel mod dump_repo_mapping komutunu kullanın.

Modül uzantıları, bir modülün görünür kapsamına ek depolar da ekleyebilir.