Modül uzantıları

Sorun bildir Kaynağı göster Gece · 7,3 · 7,2 · 7,1 · 7,0 · 6,5

Modül uzantıları, kullanıcıların giriş verilerini okuyarak modül sistemini genişletmesine olanak tanır bağımlılık grafiğindeki modüllerden yararlanarak, sorunları çözmek için gerekli mantığı ve son olarak kod deposu kurallarını çağırarak depolar oluşturmayı öğreneceksiniz. Bu uzantılar depo kurallarına benzer özelliklere sahiptir, bu da dosya G/Ç işlemlerini gerçekleştirmelerini, ağ istekleri gönderebilir. Bunların yanı sıra, Bazel'in diğer paket yönetimi sistemleriyle etkileşimde bulunurken bağımlılık grafiği oluşturabilirsiniz.

.bzl dosyalarında modül uzantılarını, depo kurallarında olduğu gibi tanımlayabilirsiniz. Onlar doğrudan çağrılmaz; her modül etiketler adı verilen veri parçalarını bir şablondur. Bazel, herhangi bir modülü değerlendirmeden önce uzantılar. Uzantı, tarayıcı genelinde kendisine ait tüm etiketleri okur bağımlılık grafiğidir.

Uzantı kullanımı

Uzantılar Bazel modüllerinde barındırılır. Bir uzantıyı modülünde, ilk olarak uzantıyı barındıran modüle bir bazel_dep ekleyin ve ardından use_extension yerleşik işlevini çağırın çok önemli. Şu örneği inceleyelim: "maven"i kullanmak için MODULE.bazel dosyası , rules_jvm_external modül:

bazel_dep(name = "rules_jvm_external", version = "4.5")
maven = use_extension("@rules_jvm_external//:extensions.bzl", "maven")

Bu, use_extension işlevinin döndürülen değerini bir değişkene bağlar ve böylece kullanıcının uzantıya ilişkin etiketleri belirtmek için nokta söz dizimi kullanmasını öneririz. Etiketler uzantı tanımı. Örneğin, maven.install ve maven.artifact etiketleri:

maven.install(artifacts = ["org.junit:junit:4.13.2"])
maven.artifact(group = "com.google.guava",
               artifact = "guava",
               version = "27.0-jre",
               exclusions = ["com.google.j2objc:j2objc-annotations"])

Kod depolarını getirmek için use_repo yönergesini kullanın oluşturulan kodu geçerli modülün kapsamına girer.

use_repo(maven, "maven")

Bir uzantı tarafından oluşturulan depolar, bu uzantının API'sinin parçasıdır. Bu örnekte "maven" modül uzantısı maven adında bir depo oluşturmayı taahhüt ediyor. Şununla yukarıda belirtilen şekilde değiştirirseniz uzantı, "maven" tarafından oluşturulan depoya işaret etmek için @maven//:org_junit_junit uzantısına sahip olur.

Uzantı tanımı

Modül uzantılarını kod deposu kurallarına benzer şekilde tanımlamak için module_extension işlevini kullanın. Ancak, depo kurallarının birçok özelliği vardır, modül uzantıları ise Her biri çeşitli tag_classlar özellikleri hakkında daha fazla bilgi edinin. Etiket sınıfları, bu uzantı tarafından kullanılan etiketler için şemaları tanımlar. Örneğin, örneğin, "maven" uzantı şöyle tanımlanabilir:

# @rules_jvm_external//:extensions.bzl

_install = tag_class(attrs = {"artifacts": attr.string_list(), ...})
_artifact = tag_class(attrs = {"group": attr.string(), "artifact": attr.string(), ...})
maven = module_extension(
  implementation = _maven_impl,
  tag_classes = {"install": _install, "artifact": _artifact},
)

Bu bildirimler, maven.install ve maven.artifact etiketlerinin belirtilen özellik şeması kullanılarak belirtilir.

Modül uzantılarının uygulama işlevi, deponunkilere benzer bir module_ctx nesnesi almaları dışında, Bu, uzantıyı ve ilgili tüm etiketleri kullanan tüm modüllere erişim izni verir. Ardından uygulama işlevi, depo oluşturmak için depo kurallarını çağırır.

# @rules_jvm_external//:extensions.bzl

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_file")  # a repo rule
def _maven_impl(ctx):
  # This is a fake implementation for demonstration purposes only

  # collect artifacts from across the dependency graph
  artifacts = []
  for mod in ctx.modules:
    for install in mod.tags.install:
      artifacts += install.artifacts
    artifacts += [_to_artifact(artifact) for artifact in mod.tags.artifact]

  # call out to the coursier CLI tool to resolve dependencies
  output = ctx.execute(["coursier", "resolve", artifacts])
  repo_attrs = _process_coursier_output(output)

  # call repo rules to generate repos
  for attrs in repo_attrs:
    http_file(**attrs)
  _generate_hub_repo(name = "maven", repo_attrs)

Uzantı kimliği

Modül uzantıları, adla ve görüntülenen .bzl dosyasıyla tanımlanır use_extension adlı kişiye yapılan aramada. Aşağıdaki örnekte maven uzantısı .bzl dosyası @rules_jvm_external//:extension.bzl ve ad maven:

maven = use_extension("@rules_jvm_external//:extensions.bzl", "maven")

Bir uzantı farklı bir .bzl dosyasından yeniden dışa aktarıldığında uzantı yeni bir kimlik kazanır Geçişli modül grafiğinde uzantının her iki sürümü de kullanılıyorsa ayrı olarak değerlendirilirler ve yalnızca ilişkili oldukları etiketleri daha kolay oluyor.

Uzantı yazarı olarak, kullanıcıların yalnızca sizin modül uzantısını tek bir .bzl dosyasından sağlayabilirsiniz.

Kod deposu adları ve görünürlüğü

Uzantılar tarafından oluşturulan kod depoları module_repo_canonical_name+extension_name+repo_name biçiminde standart adlara sahiptir. Standart adın biçimi, bağımlı olmanız gereken bir API değildir ve her an değişebilir.

Bu adlandırma politikası, her uzantının kendi "depo ad alanına" sahip olduğu anlamına gelir. iki Farklı uzantıların her biri risk almadan aynı ada sahip bir depo tanımlayabilir emin olun. Aynı zamanda, repository_ctx.name işlevinin standart adı bildirdiği anlamına da gelir. deponun adı; depo kuralında belirtilen adla aynı değildir çağrısına bir tıklama URL'si eklemeniz gerekir.

Modül uzantıları tarafından oluşturulan depolar göz önünde bulundurulduğunda, birkaç depo görünürlük kuralı vardır:

  • Bazel modül deposu, MODULE.bazel dosyasında sunulan tüm depoları görebilir bazel_dep ve use_repo.
  • Bir modül uzantısı tarafından oluşturulan bir depo, uzantıyı barındıran modülün artı aynı modül uzantısı kullanılarak (depo kuralı çağrılarında belirtilen adlar kullanılır: görünen adlarını kullanabilirsiniz.
    • Bu durum bir çakışmaya yol açabilir. Modül deposu, görünen adı foo belirtir ve uzantı, belirtilen ad foo, ardından bu uzantı tarafından oluşturulan tüm kod depoları için foo, ilkini ifade eder.

En iyi uygulamalar

Bu bölümde, uzantılarla ilgili en iyi uygulamalar açıklanır. kolayca kullanılabilir, sürdürülebilir ve zaman içindeki değişikliklere iyi uyum sağlanabilir.

Her uzantıyı ayrı bir dosyaya yerleştirin

Uzantılar farklı bir dosyada yer aldığında bir uzantının yüklenmesine olanak tanır başka bir uzantı tarafından oluşturulan kod depoları. Bunu kullanmasanız bile kullanmanız gerekiyorsa, daha sonra ihtiyacınız olması ihtimaline karşı bunları ayrı dosyalara daha sonra. Bunun nedeni, uzantının kimliğinin dosyaya dayalı olmasıdır. Bu nedenle, uzantıyı başka bir dosyaya eklemek daha sonra herkese açık API'nizi değiştirir ve kullanıcılarınız için uyumsuz bir değişikliktir.

Yeniden oluşturulabilirliği belirtin

Uzantınız her zaman aynı girişlerle aynı depoları tanımlıyorsa (uzantı etiketleri, okuduğu dosyalar vb.) gösterir ve özellikle de tarafından korunmayan tüm indirmeler sağlamazsanız, extension_metadata - reproducible = True. Bu sayede, Bazel'in kilit dosyasıdır.

İşletim sistemini ve mimariyi belirtin

Uzantınız işletim sistemine veya mimari türüne dayalıysa Bunu uzantı tanımında os_dependent kullanarak belirttiğinizden emin olun ve arch_dependent boole özellikleri. Bu, Bazel'in ikisinde de değişiklik olursa yeniden değerlendirme gerektirir.

Ana makineye bu tür bir bağımlılık, bu tür bir bağımlılığın sürdürülmesini zorlaştırdığı için, kilit dosyası girişini yapmak için, uzantıyı yeniden oluşturulabilir olarak işaretleme hakkında daha fazla bilgi edinin.

Kod deposu adlarını yalnızca kök modül doğrudan etkilemelidir

Bir uzantı, depo oluşturduğunda uzantının ad alanına girin. Bu da, soruna yol açan kişinin birbirinden farklı olması durumunda modüller aynı uzantıyı kullanır ve sonunda aynı uzantıyı dokunun. Bu durum genellikle modül uzantısının tag_class öğesinin name değerine sahip olmasıyla kendini gösterir. kod deposu kuralının name değeri olarak aktarılan bağımsız değişken.

Örneğin, kök modülün (A) B modülüne bağlı olduğunu varsayalım. Her iki modül mylang modülüne bağlıdır. Hem A hem de B mylang.toolchain(name="foo") depolanıyorsa her ikisi de adlı bir depo oluşturmaya çalışır mylang modülünde foo. Bir hata oluşur.

Bunu önlemek için depo adını doğrudan ayarlama özelliğini kaldırın, veya sadece kök modülün bunu yapmasına izin verin. Kök modülün bu şekilde çalıştırılmasına sahip olacağınız anlamına gelmez ve bunun için endişelenmenize çakışan bir ada neden oluyor.