Aturan Repositori

Laporkan masalah Lihat sumber

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

Repositori eksternal adalah aturan yang hanya dapat digunakan dalam file WORKSPACE dan memungkinkan operasi non-hermetic pada fase pemuatan Bazel. Setiap aturan repositori eksternal membuat ruang kerja-nya sendiri, dengan file dan artefak BUILD-nya sendiri. Library ini dapat digunakan untuk bergantung pada library pihak ketiga (seperti library paket Maven), tetapi juga untuk menghasilkan file BUILD khusus untuk host yang dijalankan Bazel.

Pembuatan aturan repositori

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

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

Aturan dimuat saat Anda membuatnya secara eksplisit, atau jika aturan tersebut merupakan dependensi build. Dalam hal ini, Bazel akan menjalankan fungsi implementation-nya. Fungsi ini menjelaskan cara membuat repositori, kontennya, dan file BUILD.

Atribut

Atribut adalah argumen aturan yang diteruskan sebagai dikte ke argumen aturan attrs. Atribut dan jenisnya ditetapkan saat Anda menentukan 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 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 yang ditetapkan secara implisit (seperti aturan build). 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 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. Fungsi ini berisi logika aturan yang sebenarnya dan dieksekusi secara ketat dalam Fase Pemuatan.

Fungsi ini memiliki tepat satu parameter input, repository_ctx. Fungsi ini menampilkan None untuk menunjukkan bahwa aturan dapat direproduksi dengan parameter yang ditentukan, atau dikte dengan kumpulan parameter untuk aturan tersebut yang akan mengubah aturan tersebut menjadi aturan yang dapat direproduksi dan menghasilkan repositori 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-hermetic (menemukan biner, mengeksekusi biner, membuat file di repositori, atau mendownload file dari Internet). Lihat library untuk konteks lainnya. 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 dijalankan saat Bazel memerlukan target dari repositori tersebut, misalnya saat target lain (di repositori lain) bergantung padanya atau jika disebutkan pada command line. Fungsi implementasi selanjutnya diharapkan untuk membuat repositori dalam sistem file. Tindakan ini disebut "mengambil" repositori.

Berbeda dengan target reguler, repositori tidak perlu diambil ulang ketika ada perubahan yang akan menyebabkan repositori menjadi berbeda. Hal ini karena ada hal-hal yang perubahannya tidak dapat dideteksi oleh Bazel 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:

  • Parameter yang diteruskan ke deklarasi repositori dalam file WORKSPACE.
  • Kode Starlark yang terdiri dari implementasi repositori.
  • Nilai setiap variabel lingkungan yang dideklarasikan dengan atribut environ dari repository_rule. Nilai variabel lingkungan ini dapat di-hardcode pada command line dengan flag --action_env (tetapi flag ini akan membatalkan setiap tindakan build).
  • Konten dari setiap file yang diteruskan ke read(), execute(), dan metode serupa dari repository_ctx yang dirujuk dengan 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 tanda configure ditetapkan, repositori hanya diambil ulang pada bazel sync saat parameter --configure diteruskan ke properti tersebut (jika atribut tidak disetel, perintah ini tidak akan menyebabkan pengambilan ulang)
  • Jika flag local ditetapkan, selain kasus di atas, repositori juga diambil ulang saat server Bazel dimulai ulang atau saat file apa pun yang memengaruhi deklarasi repositori berubah (misalnya file WORKSPACE atau file yang dimuatnya), 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 dianggap dapat berkomunikasi dengan jaringan atau berbayar.

Memulai ulang fungsi implementasi

Fungsi penerapan dapat dimulai ulang saat repositori sedang diambil jika dependensi yang diminta tidak ada. Dalam hal ini, eksekusi fungsi implementasi akan berhenti, dependensi yang hilang 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 terlebih dahulu, asalkan semua argumen label dapat di-resolve ke file yang ada. Perhatikan bahwa penyelesaian jalur dari string atau label yang dibuat hanya selama eksekusi fungsi masih dapat menyebabkan mulai ulang.

Memaksa pengambilan kembali repositori eksternal

Terkadang, repositori eksternal dapat usang tanpa ada perubahan pada definisi atau dependensinya. Misalnya, sumber pengambilan repositori 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 sync.

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

Contoh

  • Toolchain yang dikonfigurasi secara otomatis C++: alat ini menggunakan aturan repositori untuk secara otomatis membuat file konfigurasi C++ untuk Bazel dengan mencari compiler C++ lokal, lingkungan, dan tanda yang didukung compiler C++.

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

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