Aturan Repositori

Laporkan masalah Lihat sumber Per Malam · 7,2 · 7,1 · 7,0 · 6,5 · 6,4

Halaman ini membahas cara membuat aturan repositori dan memberikan contoh untuk secara lebih mendetail.

Repositori eksternal adalah aturan yang hanya dapat digunakan dalam file WORKSPACE dan memungkinkan operasi non-hermetik pada fase pemuatan dari Bazel. Setiap aturan repositori eksternal membuat ruang kerjanya sendiri, dengan file dan artefak BUILD sendiri. Layanan ini dapat digunakan untuk bergantung pada ketersediaan pihak ketiga. library (seperti library terpaket Maven) tetapi juga untuk menghasilkan file BUILD khusus untuk {i>host<i} yang dijalankan Bazel.

Pembuatan aturan repositori

Dalam file .bzl, gunakan fungsi repository_rule untuk membuat aturan repositori dan menyimpannya dalam variabel global.

Aturan repositori kustom dapat digunakan seperti aturan repositori native. Ini memiliki atribut name wajib dan setiap target yang ada dalam file build-nya dapat disebut sebagai @<name>//package:target dengan <name> adalah nilai Atribut name.

Aturan dimuat ketika Anda secara eksplisit membangunnya, atau jika itu adalah dependensi dari build tersebut. Dalam hal ini, Bazel akan menjalankan fungsi implementation. Ini fungsi yang menjelaskan cara membuat repositori, kontennya, dan file BUILD.

Atribut

Atribut adalah argumen aturan yang diteruskan sebagai dict ke argumen aturan attrs. Atribut dan jenisnya didefinisikan tercantum saat Anda mendefinisikan aturan repositori. Contoh yang menentukan atribut url dan sha256 sebagai string:

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

Untuk mengakses atribut dalam fungsi penerapan, 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 yang ditentukan secara implisit (seperti build aturan). Dua atribut implisit adalah name (seperti untuk aturan build) dan repo_mapping. Nama aturan repositori dapat diakses dengan repository_ctx.name. Arti repo_mapping sama dengan untuk aturan repositori native local_repository dan new_local_repository.

Jika nama atribut diawali dengan _, atribut tersebut bersifat pribadi dan pengguna tidak dapat menyetelnya.

Fungsi penerapan

Setiap aturan repositori memerlukan fungsi implementation. Isinya adalah logika aturan yang sebenarnya dan dijalankan secara ketat pada Fase Pemuatan.

Fungsi ini memiliki tepat satu parameter input, repository_ctx. {i>Function<i} menampilkan None untuk menunjukkan bahwa aturan tersebut dapat direproduksi mengingat parameter tertentu, atau dict dengan set parameter untuk aturan tersebut akan mengubah aturan itu menjadi aturan yang dapat direproduksi yang menghasilkan repositori yang sama. Sebagai misalnya, untuk aturan yang melacak repositori git yang berarti menampilkan ID commit spesifik, dan bukan cabang mengambang yang awalnya yang ditentukan.

Parameter input repository_ctx dapat digunakan untuk mengakses nilai atribut, dan fungsi non-hermetik (menemukan biner, mengeksekusi biner, membuat file dalam repositori atau mengunduh file dari internet). Lihat library untuk mengetahui informasi selengkapnya konteks tambahan. Contoh:

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

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

Kapan fungsi implementasi dieksekusi?

Fungsi implementasi repositori dieksekusi ketika Bazel membutuhkan dari repositori tersebut, misalnya saat target lain (di repositori) tergantung padanya atau jika disebutkan di command line. Tujuan maka fungsi implementasi akan membuat repositori dalam file sistem file. Hal ini disebut "pengambilan" repositori.

Berbeda dengan target reguler, repositori tidak harus diambil ulang saat sesuatu yang berubah yang akan menyebabkan repositori menjadi berbeda. Ini adalah karena ada hal-hal yang tidak bisa dideteksi perubahannya atau yang akan menyebabkan terlalu banyak overhead pada setiap build (misalnya, item yang diambil dari jaringan). Oleh karena itu, repositori diambil ulang hanya jika salah satu hal-hal berikut akan berubah:

  • Parameter yang diteruskan ke deklarasi repositori di File WORKSPACE.
  • Kode Starlark yang terdiri dari implementasi repositori.
  • Nilai variabel lingkungan apa pun yang diteruskan ke repository_ctx metode getenv() atau dideklarasikan dengan atribut environ dari repository_rule. Nilai-nilai dari variabel lingkungan ini dapat dihubungkan dengan baris perintah dengan Flag --repo_env.
  • Konten dari file apa pun yang diteruskan ke read(), execute(), dan sejenisnya metode repository_ctx yang dirujuk oleh label (misalnya, //mypkg:label.txt, tetapi bukan mypkg/label.txt)
  • Saat bazel sync dieksekusi.

Ada dua parameter repository_rule yang mengontrol kapan repositori diambil ulang:

  • Jika flag configure ditetapkan, repositori hanya diambil ulang pada bazel sync saat parameter --configure diteruskan (jika tidak ditetapkan, perintah ini tidak akan menyebabkan pengambilan ulang)
  • Jika flag local ditetapkan, selain kasus di atas, repositori akan diambil ulang saat server Bazel dimulai ulang atau ketika file apa pun deklarasi repositori berubah (misalnya, file WORKSPACE atau file yang dimuat), terlepas dari apakah perubahan tersebut mengakibatkan perubahan pada deklarasi repositori atau kodenya.

    Repositori non-lokal tidak diambil ulang dalam kasus ini. Hal ini karena repositori ini diasumsikan dapat berkomunikasi dengan jaringan atau mahal.

Memulai ulang fungsi implementasi

Fungsi implementasi dapat dimulai ulang saat repositori sedang diambil jika dependensi yang dimintanya tidak ada. Dalam hal ini, eksekusi fungsi implementasi akan berhenti, dependensi yang hilang akan diselesaikan dan fungsi akan dieksekusi kembali setelah dependensi diselesaikan. Kepada menghindari mulai ulang yang tidak perlu (yang mahal, karena akses jaringan mungkin harus diulang), argumen label di-pengambilan data, asalkan semua argumen label dapat di-resolve menjadi file yang sudah ada. Perhatikan bahwa menyelesaikan jalur dari {i>string<i} atau label yang dibuat hanya selama eksekusi fungsi tersebut masih dapat menyebabkan {i>restart<i}.

Memaksa pengambilan kembali repositori eksternal

Terkadang, repositori eksternal bisa menjadi usang tanpa perubahan apa pun pada repositorinya definisi atau dependensi. Misalnya, sumber pengambilan repositori mungkin mengikuti cabang tertentu dari repositori pihak ketiga, dan commit baru yang tersedia di cabang itu. Dalam hal ini, Anda dapat meminta bazel untuk mengambil kembali semua repositori eksternal tanpa syarat dengan memanggil bazel sync.

Selain itu, beberapa aturan memeriksa komputer lokal dan mungkin menjadi usang jika komputer lokal di-upgrade. Di sini Anda dapat meminta bazel untuk hanya mengambil kembali repositori eksternal tersebut repository_rule definisi memiliki atribut configure yang disetel, gunakan bazel sync --configure.

Contoh

  • Toolchain C++ yang dikonfigurasi secara otomatis: ia menggunakan aturan repositori untuk secara otomatis membuat file konfigurasi C++ untuk Bazel dengan mencari compiler C++ lokal, dan penanda yang didukung kompilator 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.