Lockfile Bazel

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

Fitur {i>lockfile<i} di Bazel memungkinkan perekaman versi atau dependensi pustaka atau paket perangkat lunak yang dibutuhkan oleh sebuah proyek. Ini mencapai hal ini dengan menyimpan hasil resolusi modul dan ekstensi evaluasi. Lockfile mendukung build yang dapat direproduksi, memastikan konsistensi lingkungan pengembangan lainnya. Selain itu, meningkatkan efisiensi build dengan Bazel untuk melewati bagian proses resolusi yang tidak terpengaruh oleh perubahan dalam dependensi proyek. Selanjutnya, {i>lockfile<i} meningkatkan stabilitas dengan mencegah pembaruan yang tidak diharapkan atau perubahan yang dapat menyebabkan gangguan dalam pustaka eksternal, sehingga mengurangi risiko masuknya {i>bug<i}.

Pembuatan Lockfile

Lockfile dibuat di bawah root ruang kerja dengan nama MODULE.bazel.lock. Instance dibuat atau diperbarui selama proses build, khususnya setelah resolusi modul dan evaluasi ekstensi. Yang penting, hanya menyertakan dependensi yang disertakan dalam pemanggilan buat.

Ketika terjadi perubahan dalam proyek yang mempengaruhi dependensinya, {i>lockfile<i} akan diperbarui secara otomatis untuk mencerminkan status baru. Hal ini memastikan bahwa {i>lockfile<i} tetap fokus pada serangkaian dependensi tertentu yang dibutuhkan oleh lingkungan dibangun, memberikan representasi akurat dari penyelesaian proyek dependensi.

Penggunaan Lockfile

{i>lockfile<i} dapat dikontrol oleh penanda --lockfile_mode ke menyesuaikan perilaku Bazel saat status project berbeda dari {i>lockfile<i}. Mode yang tersedia adalah:

  • update (Default): Gunakan informasi yang ada di file kunci untuk melewati download file registry yang diketahui dan menghindari evaluasi ulang ekstensi yang hasilnya masih terbaru. Jika informasinya tidak ada, maka akan ditambahkan ke {i>lockfile<i}. Dalam mode ini, Bazel juga akan menghindari pemuatan ulang informasi yang dapat berubah, seperti versi yang ditarik, untuk dependensi yang belum ubah.
  • refresh: Seperti update, tetapi informasi yang dapat berubah selalu diperbarui saat ketika beralih ke mode ini dan kira-kira setiap jam saat dalam mode ini.
  • error: Seperti update, tetapi jika ada informasi yang hilang atau tidak relevan, Bazel akan gagal dengan pesan error. Mode ini tidak pernah mengubah {i>lockfile<i} atau melakukan permintaan jaringan selama resolusi. Ekstensi modul yang ditandai sendiri sebagai reproducible mungkin masih menjalankan permintaan jaringan, tetapi diharapkan untuk selalu memberikan hasil yang sama.
  • off: Lockfile tidak diperiksa atau diperbarui.

Manfaat Lockfile

Lockfile ini menawarkan beberapa manfaat dan dapat digunakan dengan berbagai cara:

  • Build yang dapat direproduksi. Dengan merekam versi atau dependensi tertentu library perangkat lunak, {i>lockfile<i} memastikan bahwa build dapat direproduksi di berbagai lingkungan dan dari waktu ke waktu. Developer dapat mengandalkan hasil yang konsisten dan dapat diprediksi ketika membangun proyek mereka.

  • Resolusi inkremental yang cepat. {i>Lockfile<i} memungkinkan Bazel untuk menghindari mendownload file registry yang sudah digunakan pada build sebelumnya. Hal ini meningkatkan efisiensi build secara signifikan, terutama dalam skenario saat penyelesaian dapat memakan waktu.

  • Stabilitas dan pengurangan risiko. Lockfile membantu menjaga stabilitas dengan mencegah pembaruan yang tidak terduga atau perubahan yang dapat menyebabkan gangguan di pustaka eksternal. Menurut mengunci dependensi ke versi tertentu, risiko menimbulkan {i>bug<i} karena update yang tidak kompatibel atau tidak diuji berkurang.

Konten Lockfile

Lockfile berisi semua informasi yang dibutuhkan untuk menentukan apakah status project telah berubah. Hal ini juga mencakup hasil dari pembangunan proyek dengan kondisi saat ini. Lockfile terdiri dari dua bagian utama:

  1. Hash dari semua file jarak jauh yang merupakan input ke resolusi modul.
  2. Untuk setiap ekstensi modul, {i>lockfile<i} menyertakan input yang memengaruhinya, diwakili oleh bzlTransitiveDigest, usagesDigest, dan kolom lainnya, sebagai serta {i>output<i} dari menjalankan ekstensi tersebut, yang disebut sebagai generatedRepoSpecs

Berikut adalah contoh yang menunjukkan struktur {i>lockfile<i}, bersama dengan penjelasan untuk setiap bagian:

{
  "lockFileVersion": 10,
  "registryFileHashes": {
    "https://bcr.bazel.build/bazel_registry.json": "8a28e4af...5d5b3497",
    "https://bcr.bazel.build/modules/foo/1.0/MODULE.bazel": "7cd0312e...5c96ace2",
    "https://bcr.bazel.build/modules/foo/2.0/MODULE.bazel": "70390338... 9fc57589",
    "https://bcr.bazel.build/modules/foo/2.0/source.json": "7e3a9adf...170d94ad",
    "https://registry.mycorp.com/modules/foo/1.0/MODULE.bazel": "not found",
    ...
  },
  "selectedYankedVersions": {
    "foo@2.0": "Yanked for demo purposes"
  },
  "moduleExtensions": {
    "//:extension.bzl%lockfile_ext": {
      "general": {
        "bzlTransitiveDigest": "oWDzxG/aLnyY6Ubrfy....+Jp6maQvEPxn0pBM=",
        "usagesDigest": "aLmqbvowmHkkBPve05yyDNGN7oh7QE9kBADr3QIZTZs=",
        ...,
        "generatedRepoSpecs": {
          "hello": {
            "bzlFile": "@@//:extension.bzl",
            ...
          }
        }
      }
    },
    "//:extension.bzl%lockfile_ext2": {
      "os:macos": {
        "bzlTransitiveDigest": "oWDzxG/aLnyY6Ubrfy....+Jp6maQvEPxn0pBM=",
        "usagesDigest": "aLmqbvowmHkkBPve05y....yDNGN7oh7r3QIZTZs=",
        ...,
        "generatedRepoSpecs": {
          "hello": {
            "bzlFile": "@@//:extension.bzl",
            ...
          }
        }
      },
      "os:linux": {
        "bzlTransitiveDigest": "eWDzxG/aLsyY3Ubrto....+Jp4maQvEPxn0pLK=",
        "usagesDigest": "aLmqbvowmHkkBPve05y....yDNGN7oh7r3QIZTZs=",
        ...,
        "generatedRepoSpecs": {
          "hello": {
            "bzlFile": "@@//:extension.bzl",
            ...
          }
        }
      }
    }
  }
}

Hash File Registry

Bagian registryFileHashes berisi hash semua file dari registry jarak jauh yang diakses selama resolusi modul. Karena resolusi algoritma sepenuhnya determenistik ketika diberi input yang sama dan semua input di-hash, ini memastikan hasil resolusi yang dapat direproduksi sepenuhnya sekaligus menghindari duplikasi informasi jarak jauh yang berlebihan di {i>lockfile<i}. Perlu diketahui bahwa Hal ini juga memerlukan pencatatan saat {i> registry<i} tertentu tidak berisi , tetapi registry dengan prioritas lebih rendah melakukannya (lihat entri "tidak ditemukan" di contoh). Informasi yang secara inheren dapat berubah ini dapat diperbarui melalui bazel mod deps --lockfile_mode=refresh.

Bazel menggunakan {i>hash<i} dari {i>lockfile<i} untuk mencari file {i>registry<i} di cache repositori sebelum mengunduhnya, yang mempercepat resolusi.

Versi Yanked yang Dipilih

Bagian selectedYankedVersions berisi versi modul yang digabungkan yang dipilih berdasarkan resolusi modul. Karena hal ini biasanya menyebabkan {i>error<i} saat mencoba membangun, bagian ini hanya tidak kosong ketika versi yang ditarik secara eksplisit diizinkan melalui --allow_yanked_versions atau BZLMOD_ALLOW_YANKED_VERSIONS.

Bidang ini diperlukan karena, dibandingkan dengan file modul, informasi versi yang diambil pada dasarnya bisa berubah sehingga tidak dapat direferensikan oleh {i>hash<i}. Informasi ini dapat diperbarui melalui bazel mod deps --lockfile_mode=refresh.

Ekstensi Modul

Bagian moduleExtensions adalah peta yang hanya menyertakan ekstensi yang digunakan dalam pemanggilan saat ini atau yang sebelumnya dipanggil, sembari mengecualikan ekstensi yang tidak lagi digunakan. Dengan kata lain, jika ekstensi tidak digunakan di seluruh grafik dependensi, grafik tersebut akan dihapus dari moduleExtensions peta.

Jika ekstensi tidak tergantung pada sistem operasi atau jenis arsitektur, bagian ini hanya menampilkan satu "umum" entri. Jika tidak, beberapa entri disertakan, diberi nama sesuai OS, arsitektur, atau keduanya, dengan masing-masing sesuai dengan hasil evaluasi ekstensi berdasarkan spesifikasi tersebut.

Setiap entri di peta ekstensi sesuai dengan ekstensi yang digunakan dan diidentifikasi berdasarkan file dan nama yang dimuatnya. Nilai yang sesuai untuk setiap entri berisi informasi relevan yang terkait dengan ekstensi tersebut:

  1. bzlTransitiveDigest adalah ringkasan implementasi ekstensi dan file .bzl yang dimuat secara transitif.
  2. usagesDigest adalah ringkasan penggunaan ekstensi di grafik dependensi, yang mencakup semua tag.
  3. Kolom yang tidak ditentukan lebih lanjut yang melacak input lain ke ekstensi, seperti konten file atau direktori yang dibacanya atau lingkungan berbagai variabel yang digunakannya.
  4. generatedRepoSpecs mengenkode repositori yang dibuat oleh ekstensi dengan input saat ini.
  5. Kolom moduleExtensionMetadata opsional berisi metadata yang disediakan oleh ekstensi seperti apakah repositori tertentu yang dibuat harus diimpor melalui use_repo oleh modul root. Informasi ini mendukung Perintah bazel mod tidy.

Ekstensi modul dapat memilih untuk tidak disertakan dalam lockfile dengan menyetel menampilkan metadata dengan reproducible = True. Dengan demikian, mereka berjanji bahwa mereka akan selalu membuat repositori yang sama ketika diberi input yang sama.

Praktik Terbaik

Untuk memaksimalkan manfaat fitur lockfile, pertimbangkan hal-hal berikut praktik:

  • Perbarui kunci file secara teratur untuk mencerminkan perubahan dalam dependensi proyek atau konfigurasi Anda. Hal ini memastikan bahwa build berikutnya didasarkan pada terbaru dan akurat. Untuk mengunci semua ekstensi sekaligus, jalankan bazel mod deps --lockfile_mode=update.

  • Sertakan {i>lockfile<i} dalam kontrol versi untuk memfasilitasi kolaborasi dan memastikan bahwa semua anggota tim memiliki akses ke {i>lockfile<i} yang sama, yang konsisten di seluruh project.

  • Gunakan bazelisk untuk menjalankan Bazel, dan sertakan File .bazelversion dalam kontrol versi yang menentukan versi Bazel yang sesuai dengan {i>lockfile<i}. Karena Bazel sendiri adalah dependensi dari {i>build<i} Anda, {i>lockfile<i} itu khusus untuk versi Bazel, dan akan berubah bahkan antara kompatibel dengan versi lama Rilis Bazel. Penggunaan bazelisk memastikan bahwa semua developer menggunakan versi Bazel yang sesuai dengan {i>lockfile<i}.

Dengan mengikuti praktik terbaik ini, Anda dapat menggunakan {i>lockfile<i} secara efektif Bazel, yang mengarah ke pengalaman yang lebih efisien, andal, dan kolaboratif di alur kerja pengembangan perangkat lunak.

Konflik Penggabungan

Format {i>lockfile<i} dirancang untuk meminimalkan konflik penggabungan, tetapi mereka masih bisa terjadi.

Resolusi Otomatis

Bazel memberikan driver git merge untuk membantu menyelesaikan konflik ini secara otomatis.

Siapkan driver dengan menambahkan baris ini ke file .gitattributes di root repositori git Anda:

# A custom merge driver for the Bazel lockfile.
# https://bazel.build/external/lockfile#automatic-resolution
MODULE.bazel.lock merge=bazel-lockfile-merge

Kemudian setiap developer yang ingin menggunakan {i>driver<i} harus mendaftarkannya sekali dengan mengikuti langkah-langkah berikut:

  1. Instal jq (1.5 atau yang lebih tinggi).
  2. Jalankan perintah berikut:
jq_script=$(curl https://raw.githubusercontent.com/bazelbuild/bazel/master/scripts/bazel-lockfile-merge.jq)
printf '%s\n' "${jq_script}" | less # to optionally inspect the jq script
git config --global merge.bazel-lockfile-merge.name   "Merge driver for the Bazel lockfile (MODULE.bazel.lock)"
git config --global merge.bazel-lockfile-merge.driver "jq -s '${jq_script}' -- %O %A %B > %A.jq_tmp && mv %A.jq_tmp %A"

Resolusi Manual

Konflik penggabungan sederhana di registryFileHashes dan selectedYankedVersions isian dapat diselesaikan secara aman dengan menyimpan semua entri dari kedua sisi konflik.

Jenis konflik penggabungan lainnya tidak boleh diselesaikan secara manual. Sebagai gantinya:

  1. Memulihkan status lockfile sebelumnya melalui git reset MODULE.bazel.lock && git checkout MODULE.bazel.lock.
  2. Selesaikan konflik apa pun di file MODULE.bazel.
  3. Jalankan bazel mod deps untuk memperbarui file kunci.