Bazel modülleri

Sorun bildirin Kaynağı göster

Bazel modülü, her birinin bağlı olduğu diğer modüllerle ilgili meta verileri yayınlayan birden çok sürümü olabilen bir Bazel projesidir. Bu, diğer bağımlılık yönetimi sistemlerindeki (Maven yapı, npm paketi, Go modülü veya kargo kabı) bilinen kavramlara benzer.

Bir modülün kod deposu kökünde bir MODULE.bazel dosyası olmalıdır. Bu dosya, modülün adını, sürümünü, doğrudan bağımlılıkların listesini ve diğer bilgilerini açıklayan manifesttir. Temel bir örnek için:

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.

Modül çözümlemesini gerçekleştirmek için Bazel işe kök modülün MODULE.bazel dosyasını okuyarak başlar ve ardından bütün bağımlılık grafiğini bulana kadar bir Bazel kayıt defterinden bağımlılığın MODULE.bazel dosyasını sürekli olarak ister.

Daha sonra Bazel varsayılan olarak kullanılacak her modülün bir sürümünü seçer. Bazel, her bir modülü bir kod deposuyla temsil eder ve her bir depoyu nasıl tanımlayacağınızı öğrenmek için kayıt otoritesine yeniden başvurur.

Sürüm biçimi

Bazel çeşitlilik içeren bir ekosisteme sahiptir ve projelerde çeşitli sürüm oluşturma şemaları kullanılmaktadır. Şu ana kadar en popüler olan SemVer olsa da Abseil gibi farklı şemaların kullanıldığı öne çıkan projeler de vardır. Bu projelerin versiyonları tarih tabanlıdır (ör. 20210324.2).

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

  • SemVer, sürümün "yayın" bölümünün 3 segmentten oluşması gerektiğini belirtir: MAJOR.MINOR.PATCH. Bazel'de bu koşul gevşetilmiştir. Böylece, istenen sayıda segmente izin verilir.
  • SemVer'de, "sürüm" bölümündeki segmentlerin her biri yalnızca rakamlardan oluşmalıdır. Bazel'de bu değer harflere izin verecek şekilde gevşetilir ve karşılaştırma anlamı, "yayın öncesi" bölümündeki "tanımlayıcılar" ile eşleşir.
  • Ayrıca ana, alt ve yama sürümü artışlarının anlamları zorunlu kılınmaz. Bununla birlikte, geriye dönük uyumluluğu nasıl ifade ettiğimizle ilgili ayrıntılar için uyumluluk düzeyine bakın.

Geçerli herhangi bir SemVer sürümü, geçerli bir Bazel modülü sürümüdür. Ayrıca, iki SemVer sürümü (a ve b) Bazel modül sürümleriyle karşılaştırıldığında aynı muhafazaların olması durumunda a < b ile karşılaştırılır.

Sürüm seçimi

Sürümlü bağımlılık yönetimi alanının vazgeçilmez bir parçası olan elmas bağımlılık problemini düşünün. Aşağıdaki gibi bir bağımlılık grafiğiniz 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 yanıtlamak için Go modül sisteminde sunulan Minimum Sürüm Seçimi (MVS) algoritmasını kullanıyor. MVS, bir modülün tüm yeni sürümlerinin geriye dönük uyumlu olduğunu varsayar ve bu nedenle bağımlı öğeler tarafından belirtilen en yüksek sürümü seçer (örneğimizde D 1.1). Bu "minimal" olarak adlandırılmıştır, çünkü D 1.1, gereksinimlerimizi karşılayabilecek ilk sürümdür. D 1.2 veya daha yeni bir sürüm mevcut olsa bile, bunları seçmeyiz. MVS kullanılması, yüksek kaliteli ve tekrarlanabilir bir sürüm seçme süreci oluşturur.

Yanklanan sürümler

Kaçınılması gereken belirli sürümleri (güvenlik açıkları gibi) kayıt otoritesi yanked olarak bildirebilir. Bazel bir modülün yankılı sürümünü seçerken hata verir. Bu hatayı düzeltmek için daha yeni ve yankı olmayan bir sürüme geçin veya yanked 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 ele aldığı için işe yarar. SemVer açısından bu, A 1.x ve A 2.x'nin ayrı modüller olarak kabul edildiği ve çözümlenen bağımlılık grafiğinde bir arada bulunabileceği anlamına gelir. Bu da Go'da paket yolunda ana sürümün kodlanmasıyla mümkün olur. Böylece, herhangi bir derleme zamanı veya bağlantı zamanı çakışması olmaz.

Ancak Bazel bu tür garantileri sağlayamadığından geriye dönük uyumsuz sürümleri tespit etmek için "ana sürüm" numarasına ihtiyacı vardır. Bu sayı uyumluluk seviyesi olarak adlandırılır ve module() yönergesindeki her modül sürümü tarafından belirtilir. Bazel bu bilgilerden yararlanarak aynı modülün farklı uyumluluk düzeylerine sahip sürümlerinin çözümlenen bağımlılık grafiğinde olduğunu algıladığında 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. Bir modül bağımlılık olarak kullanılırsa geçersiz kılmaları yoksayılır.

Her geçersiz kılma, bağımlılık grafiğindeki tüm sürümlerini etkileyen belirli bir modül adı için belirtilir. Yalnızca kök modülün geçersiz kılmaları geçerli olsa da kök modülün doğrudan bağlı olmadığı geçişli bağımlılıklar söz konusu olabilir.

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

single_version_override birden fazla amaca hizmet eder:

  • version özelliği sayesinde, bağımlılık grafiğinde hangi bağımlılık sürümlerinin istendiğine bakılmaksızın bir bağımlılığı belirli bir sürüme sabitleyebilirsiniz.
  • registry özelliğiyle, normal kayıt defteri seçimi işlemini izlemek yerine bu bağımlılığı 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

Çözülmüş 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 multiple_version_override belirtilebilir.

Modül için izin verilen sürümlerin açık bir listesini belirtebilirsiniz. Bu liste, çözümden önce bağımlılık grafiğinde bulunmalıdır. İzin verilen her sürüme bağlı olarak, geçişli bir bağımlılık olması gerekir. Çözümleme işleminden sonra, modülün yalnızca izin verilen sürümleri kalır. Bazel ise 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 verir.

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

  • 1.3, 1.7 ve 2.0 sürümlerine izin veren birden fazla sürümü geçersiz kılma; 1.1 sürümünün 1.3, 1.5 sürümünün 1.7 sürümüne ve diğer sürümlerin aynı kalmasıyla sonuçlanır.
  • 1.7 için aynı uyumluluk düzeyinde yükseltme yapılabilecek daha yüksek bir sürüm olmadığından, 1.5 ve 2.0 sürümlerine izin veren birden çok sürümün geçersiz kılınması hatayla sonuçlanır.
  • Bağımlılık grafiğinde çözümden önce 1.9 bulunmadığından 1.9 ve 2.0 özelliklerine izin veren birden çok sürümün geçersiz kılınması hatayla sonuçlanır.

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

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

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

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

Bazel modüllerini temsil etmeyen depoları tanımlayın

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

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

Temelde bu, depoları daha esnek bir şekilde tanımlamanızı sağlayan modül uzantıları ile aynı mekanizma kullanılarak uygulanır.

Kod deposu adları ve katı depolar

Bir modülü doğrudan bağımlılarına destekleyen deponun görünen adı, bazel_dep yönergesinin repo_name özelliği aksini belirtmediğ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ğini unutmayın. Bu, geçişli bağımlılıklardaki değişikliklerden kaynaklanan kazayla oluşan kesintileri önlemeye yardımcı olur.

Bir modülü destekleyen deponun standart adı, bağımlılık grafiğinde modülün birden fazla sürümü olup olmamasına bağlı olarak module_name~version (örneğin, bazel_skylib~1.0.3) veya module_name~ (örneğin bazel_features~) şeklindedir (bkz. multiple_version_override). Standart ad biçiminin kullanmanız gereken bir API olmadığını ve her zaman değişebileceğini unutmayın. Standart adı sabit kodlamak yerine doğrudan Bazel'dan almak için desteklenen bir yöntem kullanın: * BUILD ve .bzl dosyalarında, deponun görünen adından (ör.Label.repo_nameLabel Label("@bazel_skylib").repo_name. * Çalıştırma dosyalarını ararken $(rlocationpath ...) ya da @bazel_tools//tools/{bash,cpp,java}/runfiles hizmetindeki veya bir kural kümesi rules_foo olan @rules_foo//foo/runfiles içindeki çalıştırma dosyaları kitaplıklarından birini 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 sağlayabilir.