Aturan Repositori

7/0.9/2.5. Lihat sumber Nightly {/3/}

Halaman ini membahas cara menentukan aturan repositori dan memberikan contoh untuk detail lebih lanjut.

Repositori eksternal adalah hierarki direktori, yang berisi file sumber yang dapat digunakan dalam build Bazel, yang dibuat on-demand dengan menjalankan aturan repo yang sesuai. Repositori dapat ditentukan dengan berbagai cara, tetapi pada akhirnya, setiap repo ditentukan dengan memanggil aturan repo, sama seperti target build yang ditentukan dengan memanggil aturan build. Library ini dapat digunakan untuk bergantung pada library pihak ketiga (seperti library paket Maven) dan juga untuk menghasilkan file BUILD khusus untuk host yang menjalankan Bazel.

Definisi aturan repositori

Dalam file .bzl, gunakan fungsi repository_rule untuk menentukan aturan repo baru dan menyimpannya dalam variabel global. Setelah ditentukan, aturan repo dapat dipanggil sebagai fungsi untuk menentukan repositori. Pemanggilan ini biasanya dilakukan dari dalam fungsi implementasi ekstensi modul.

Dua komponen utama definisi aturan repo adalah skema atribut dan fungsi implementasinya. Skema atribut menentukan nama dan jenis atribut yang diteruskan ke pemanggilan aturan repo, dan fungsi implementasi dijalankan saat repo perlu diambil.

Atribut

Atribut adalah argumen yang diteruskan ke pemanggilan aturan repo. Skema atribut yang diterima oleh aturan repo ditentukan menggunakan argumen attrs saat aturan repo ditentukan dengan panggilan ke repository_rule. Contoh yang menentukan atribut url dan sha256 sebagai string:

http_archive = repository_rule(
    implementation=_impl,
    attrs={
        "url": attr.string(mandatory=True)
        "sha256": attr.string(mandatory=True)
    }
)

Untuk mengakses atribut dalam fungsi implementasi, gunakan repository_ctx.attr.<attribute_name>:

def _impl(repository_ctx):
    url = repository_ctx.attr.url
    checksum = repository_ctx.attr.sha256

Semua repository_rule memiliki atribut name yang ditentukan secara implisit. Ini adalah atribut string yang berperilaku ajaib: saat ditetapkan sebagai input untuk pemanggilan aturan repo, nama repo ini akan terlihat jelas; tetapi saat dibaca dari fungsi penerapan aturan repo menggunakan repository_ctx.attr.name, nama repo kanonis akan ditampilkan.

Fungsi penerapan

Setiap aturan repo memerlukan fungsi implementation. Kode ini berisi logika aturan yang sebenarnya dan dijalankan secara ketat dalam Fase Pemuatan.

Fungsi ini memiliki tepat satu parameter input, repository_ctx. Fungsi ini menampilkan None untuk menunjukkan bahwa aturan dapat direproduksi berdasarkan parameter yang ditentukan, atau dict dengan kumpulan parameter untuk aturan tersebut yang akan mengubah aturan tersebut menjadi aturan yang dapat direproduksi yang menghasilkan repo yang sama. Misalnya, untuk aturan yang melacak repositori git yang berarti menampilkan ID commit tertentu, bukan cabang mengambang yang awalnya ditentukan.

Parameter input repository_ctx dapat digunakan untuk mengakses nilai atribut, dan fungsi non-hermetik (menemukan biner, mengeksekusi biner, membuat file dalam repositori, atau mendownload file dari Internet). Lihat dokumen API untuk mengetahui konteks selengkapnya. Contoh:

def _impl(repository_ctx):
  repository_ctx.symlink(repository_ctx.attr.path, "")

local_repository = repository_rule(
    implementation=_impl,
    ...)

Kapan fungsi implementasi dieksekusi?

Fungsi penerapan aturan repo dijalankan saat Bazel memerlukan target dari repositori tersebut, misalnya saat target lain (dalam repositori lain) bergantung pada aturan tersebut atau jika disebutkan pada command line. Fungsi implementasi kemudian diharapkan membuat repo dalam sistem file. Tindakan ini disebut "mengambil" repo.

Berbeda dengan target reguler, repositori tidak harus diambil ulang saat ada perubahan yang akan menyebabkan repo berbeda. Hal ini karena ada hal-hal yang tidak dapat dideteksi perubahannya atau akan menyebabkan terlalu banyak overhead pada setiap build (misalnya, hal-hal yang diambil dari jaringan). Oleh karena itu, repositori diambil ulang hanya jika salah satu hal berikut berubah:

  • Atribut yang diteruskan ke pemanggilan aturan repo.
  • Kode Starlark yang terdiri dari implementasi aturan repo.
  • Nilai variabel lingkungan apa pun yang diteruskan ke metode getenv() repository_ctx atau dideklarasikan dengan atribut environ dari repository_rule. Nilai variabel lingkungan ini dapat dihubungkan ke command line dengan flag --repo_env.
  • Konten file apa pun yang diteruskan ke read(), execute(), dan metode serupa dari repository_ctx yang dirujuk oleh label (misalnya, //mypkg:label.txt, tetapi bukan mypkg/label.txt)
  • Saat bazel fetch --force dieksekusi.

Ada dua parameter repository_rule yang mengontrol kapan repositori diambil ulang:

  • Jika tanda configure ditetapkan, repositori hanya diambil ulang pada bazel fetch saat parameter --configure diteruskan ke repositori tersebut (jika atribut tidak disetel, perintah ini tidak akan menyebabkan pengambilan ulang)
  • Jika tanda local ditetapkan, selain kasus di atas, repo juga akan diambil ulang saat server Bazel dimulai ulang.

Memulai ulang fungsi implementasi

Fungsi implementasi dapat dimulai ulang saat repo diambil jika dependensi yang dimintanya tidak ada. Dalam hal ini, eksekusi fungsi implementasi akan berhenti, dependensi yang tidak ada akan diselesaikan, dan fungsi akan dieksekusi kembali setelah dependensi diselesaikan. Untuk menghindari mulai ulang yang tidak perlu (yang mahal, karena akses jaringan mungkin harus diulang), argumen label akan diambil data sebelumnya, asalkan semua argumen label dapat di-resolve ke file yang sudah ada. Perhatikan bahwa me-resolve jalur dari string atau label yang hanya dibuat selama eksekusi fungsi masih dapat menyebabkan mulai ulang.

Memaksa pengambilan kembali repositori eksternal

Terkadang, repo eksternal dapat menjadi usang tanpa perubahan pada definisi atau dependensinya. Misalnya, sumber pengambilan repo mungkin mengikuti cabang tertentu dari repositori pihak ketiga, dan commit baru tersedia di cabang tersebut. Dalam hal ini, Anda dapat meminta bazel untuk mengambil kembali semua repositori eksternal tanpa syarat dengan memanggil bazel fetch --force --all.

Selain itu, beberapa aturan repo memeriksa komputer lokal dan mungkin menjadi usang jika komputer lokal diupgrade. Di sini Anda dapat meminta Bazel untuk hanya mengambil ulang repositori eksternal tersebut yang definisi repository_rule memiliki atribut configure yang disetel, gunakan bazel fetch --all --configure.

Contoh

  • Toolchain yang dikonfigurasi secara otomatis C++: menggunakan aturan repo untuk otomatis membuat file konfigurasi C++ untuk Bazel dengan mencari compiler C++ lokal, lingkungan, dan flag yang didukung oleh compiler C++.

  • Repositori Go menggunakan beberapa repository_rule untuk menentukan daftar dependensi yang diperlukan untuk menggunakan aturan Go.

  • rules_jvm_external membuat repositori eksternal bernama @maven secara default yang menghasilkan target build untuk setiap artefak Maven dalam hierarki dependensi transitif.