Pendahuluan

Sasaran : Pengembang Gradle yang pernah mengalami perilaku build "magis" atau tidak terduga.

Dalam petualangan kami dalam pembuatan plugin`site-baker`, kami telah mengikuti pendekatan TDD yang ketat. Setiap fitur diuji, divalidasi, dan kami maju dengan kepercayaan. Dan kemudian, suatu hari, hal yang tidak terduga terjadi. Build mulai berperilaku dengan cara yang tidak teratur. Perubahan dalam logika plugin atau dalam file konfigurasi tampak diabaikan, dan tes fungsional kami yang sebelumnya dapat diandalkan gagal tanpa alasan yang jelas.

Masalah seperti ini bisa sangat memicu frustrasi. Ini menimbulkan pertanyaan tentang keandalan alat dan kevaliditas kode kita. Sesudah sesi debugging yang intensif, penyalah telah diidentifikasi:cache konfigurasi Gradle.

Gejala: Build Hantu

Masalah ini muncul dengan beberapa cara :

  1. Saya sedang memodifikasi sebuah rantai karakter dalam sebuah tugas`println`, tetapi string lama terus ditampilkan saat eksekusi.

  2. Saya sedang mengubah sebuah nilai dalam file saya`managed-jbake-context.yml`, tetapi plugin berperilaku seolah-olah file tersebut tidak telah dimodifikasi.

  3. Uji fungsional, yang membuat proyek uji secara langsung, gagal karena plugin tidak terlihat mendeteksi file konfigurasi yang baru dibuat.

Semua terasa seolah-olah Gradle menjalankan \"versi fantom\" dari build kita, mengabaikan perubahan terbaru kita.

Survei: Apa itu Cache Konfigurasi ?

Cache konfigurasi adalah fitur yang relatif modern dan sangat kuat dari Gradle, yang diaktifkan secara default di versi baru. Tujuannya adalah membuat build lebih cepat.

Prinsipnya sederhana :
  1. Selama pelaksanaan pertama, Gradle mengeksekusi fase dariKonfigurasi(membaca`build.gradle.kts`, pembuatan tugas, penyelesaian dependensi) dan membangun grafik tugas.

  2. Di akhir fase ini, GradleSerialisasikan graf tugas inidan menyimpannya dalam cache.

  3. Selama eksekusi berikutnya, jika tidak ada yang berubah (skrip build,gradle.properties, etc.), Gradlemelewati sepenuhnya fase konfigurasidan menggunakan kembali grafik tugas yang disimpan di cache.

Penghematan waktu ini spektakuler pada proyek-proyek besar. Namun, performa ini memiliki harga: ia menegakkan ketentuan yang ketat tentang bagaimana plugin harus ditulis.

siklus hidup cache konfigurasi
@startuml
start
:Première exécution;
:Phase de Configuration;
:Création du graphe de tâches;
:Mise en cache du graphe;
:Phase d'Exécution;
end

start
:Exécution suivante;
if (Cache valide ?) then (oui)
  :Restauration du graphe depuis le cache;
  note right
    La phase de configuration
    est sautée !
  end note
else (non)
  :Phase de Configuration;
  :Mise à jour du cache;
endif
:Phase d'Exécution;
stop
@enduml

Penyebab Masalah: Plugin Tidak Sesuai

Plugin kami`site-baker`melanggar, tanpa mengetahuinya, beberapa aturan cache konfigurasi. Agar grafik tugas dapat diserialkan, tugas tidak boleh mengandung referensi ke objek kompleks seperti objek`Project`atau membaca file secara sembarangan selama tahap eksekusi.

Kesalahan utama kami adalah membaca konten file YAML langsung di dalam logika eksekusi tugas, dengan menggunakan referensi ke jalur yang disimpan di ekstensi kami. Pendekatan ini tidak kompatibel dengan cache karena Gradle tidak dapat mengetahui apakah konten file telah berubah jika pembacaan ini tidak dimodelkan sebagai sebuahmasukan tugas(Task Input)

Solusi sementara: nonaktifkan cache

Untuk membebaskan kita dan mengembalikan perilaku build yang dapat diprediksi, solusi tercepat adalah menonaktifkan cache konfigurasi. Cukup menambahkan baris berikut ke dalam file`gradle.properties`proyek yang menggunakan plugin (atau dalam kasus kami, proyek uji)site-baker).

# site-baker/gradle.properties
org.gradle.configuration-cache=false

Segera, builds telah kembali berperilaku normal. Setiap eksekusi memulai kembali fase konfigurasi dan perubahan kami diperhitungkan.

Namun, ini adalah solusi sementara, bukan solusi permanen. Ia mengorbankan kinerja dan tidak menyelesaikan masalah inti plugin kami.

Solusi yang Benar : Membuat Plugin Kompatibel

Agar suatu plugin menjadi warga yang baik dalam ekosistem Gradle modern, ia harus kompatibel dengan cache konfigurasi. Hal ini membutuhkan pemikiran ulang tentang cara data mengalir ke tugas kita.

Kunci adalah untuk menggunakanAPI PenyediaGradle. Alih-alih meneruskan nilai langsung (seperti satu`String` ou un File) untuk tugas-tugas kita, kita harus menghabiskan beberapa`Property<T>`atau beberapa`Provider<T>`.

Ini rencana refactoring :
  1. Mendeklarasikan entri tugas:Tugas yang memparsing file YAML harus menyatakan file tersebut sebagai masukan. Untuk itu, kita menggunakan anotasi.@InputFile.

[source,kotlin] ---- @get:InputFile abstract val configFile: RegularFileProperty Halo dunia


Artikel terkait