Giriş

Hedef Kitle : Gradle geliştiricileri zaten sihrî gibi görünen veya beklenmedik derleme davranışlarıyla karşılaştı.

Eklenti oluşturma maceramızda`site-baker`, Her özellik test edilip onaylanıyordu ve biz güvenselle ileri gidiyorduk. Ve bir gün, beklenmedik bir durum ortaya çıktı. Derlemeler tutarsız davranmaya başladı. Plug‑in mantığı veya yapılandırma dosyalarındaki değişiklikler görmezden geliniyordu, işlevsel testlerimiz, daha önce güvenilir olanlar, belirgin bir neden olmadan başarısız oluyordu.

Bu tip bir sorun inanılmaz derecede ürkütücü olabilir. Araç güvenilirliğini ve kodun geçerliliğini sorgular. Yoğun bir hata ayıklama oturumundan sonra suçlu tespit edildi:Gradle yapılandırma önbelleği.

Belirti: Hayalet Buildler

Problemin birden fazla şekilde ortaya çıkıyordu:

  1. Bir görevde bir karakter dizisini değiştiriyordum.println, ama eski dize çalışma zamanında görüntülenmeye devam ediyordu.

  2. Dosyamda bir değeri değiştiriyordum.managed-jbake-context.yml, fakat eklenti dosyanın değiştirilmemiş gibi davranıyordu.

  3. Fonksiyonel testler, anlık test projeleri oluştururken başarısız oluyordu çünkü eklenti yeni oluşturulan yapılandırma dosyalarını algılamadığı görünüyordu.

Her şey, Gradle’nin derlememizin bir 'fantom sürümü' çalıştırıyordu ve en son yaptığımız değişiklikleri görmezden geliyordu.

İnceleme: Yapılandırma önbelleği nedir ?

Yapılandırma önbelleği, Gradle’in nispeten modern ve çok güçlü bir özelliğidir; yeni sürümlerde varsayılan olarak etkindir ve hedefi derlemeleri daha hızlı yapmaktır.

Prensip basittir:
  1. İlk çalıştırma sırasında, Gradle fazını yürütürKonfigürasyon(okuma des`build.gradle.kts`, görev oluşturma, bağımlılık çözümü) ve bir görev grafiği oluşturur.

  2. Bu aşamanın sonunda, Gradlebu görev grafiğini serileştirirve onu önbelleğe alır.

  3. Sonraki yürütmeler sırasında, hiçbir şey değişmediyse (derleme betikleri`gradle.properties`, etc.), GradleYapılandırma aşamasını tamamen atlarve önbelleğe alınmış görev grafiğini yeniden kullanır

Büyük projelerde zaman tasarrufu spektaküler. Ancak bu performans bir maliyet getirir: eklentilerin nasıl yazılması gerektiğine dair sıkı kurallar getirir.

  1. Yapılandırma önbelleğinin yaşam döngüsü

@startuml
start
:İlk çalıştırma;
:Yapılandırma Aşaması;
:Görev grafiği oluşturma;
:Graf önbelleği;
:Yürütme Aşaması;
end

start
:Sonraki yürütme;
if (Cache valide ?) then (oui)
  :Önbellekten grafik geri yükleniyor;
  note right
Konfigürasyon aşaması
atlandı!
  end note
else (non)
  :Yapılandırma Aşaması;
  :Cache güncellemesi;
endif
:Yürütme Aşaması;
stop
@enduml

Problemin Nedeni : Uygun Olmayan Bir Eklenti

Eklentimiz`site-baker`Bilmeden yapılandırma önbelleğinin çeşitli kurallarını ihlal ediyordu. Bir görev grafiği serileştirilebilmesi için, görevler karmaşık nesnelere referans içermemelidir, gibi bir obje.`Project`veya dosyaları istediği gibi okuyabilir yürütme aşaması sırasında.

Ana hatamız, görev yürütme mantığı içinde YAML dosyasının içeriğini doğrudan okumaktı, uzantımızda saklanan yol referansını kullanarak. Bu yaklaşım, okuma bir modelleme yapılmadıkça Gradle’nin dosya içeriğinin değişip değişmediğini bilememesi nedeniyle önbellek ile uyumsuzdur.görev girişi (Task Input).

Geçici Çözüm : Önbelleği Devre Dışı Bırak

Bizden takılan yolu açmak ve tahmin edilebilir bir yapı davranışına geri dönmek için en hızlı çözüm, yapılandırma önbelleğini devre dışı bırakmaktı. Yapmamız gereken, dosyaya aşağıdaki satırı eklemektir.gradle.properties`eklenti kullanan proje (veya bizim durumumuzda, test projesi)`site-baker). "

Between triple backticks they had nothing else; outside they typed: ").". I’m leaning they want to translate "")." which translates to "")." since punctuation remains.

Thus output: ")." </think> ")

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

Anında, derlemeler normal davranışını kazandı. Her çalıştırma yapılandırma aşamasını yeniden başlatıyordu ve değişikliklerimiz dikkate alınıyordu.

Ancak, bu bir geçici çözüm, kalıcı bir çözüm değildir. Performansı sakatlar ve eklentimizin kök sorununu çözmez.

Gerçek Çözüm : Eklentiyi uyumlu hâle getirmek

Bir eklenti modern Gradle ekosisteminde iyi bir vatandaş olmak istiyorsa, yapılandırma önbelleğiyle uyumlu olmalıdır. Bu, görevlerimize veri akışı şeklini yeniden düşündürmeyi gerektirir.

Anahtar onları kullanmaktırSağlayıcı API’leriGradle’nin. Doğrudan değerleri geçirmek yerine (bir gibi`String` ou un File) görevlerimiz için, geçirmemiz gereken`Property<T>`veya bazı`Provider<T>`.

İşte yeniden yapılandırma planı :
  1. Görev girişlerini bildirme :YAML dosyasını çözen görev, bu dosyayı bir giriş olarak bildirmelidir. Bunun için anotasyon kullanılır.@InputFile.

[source,kotlin] ---- @get:InputFile soyut değeri configFile: RegularFileProperty ----

  1. Property` ve `Provider’yi kullanın :değeri`configFile`özelliğe bağlanacak`configPath`DSL uzantımızda. Gradle bu şekilde verinin kökenini izleyebilir.

[source,kotlin] ---- // Plugin içinde tasks.register<MyTask>("myTask") { configFile.set(extension.configPath.flatMap { project.layout.projectDirectory.file(it) }) } ----

  1. İçeriği doğru zamanda okuyun:Dosyanın okunması görevin eylemi içinde yapılmalıdır (@TaskAction), kullanarak`Provider`girişın.

[source,kotlin] ---- @TaskAction fonksiyon execute() { val content = configFile.get().asFile.readText() içeriği parse etmek } ----

Bu modele izleyerek, Gradle içerik olduğunda`configFile`değişiklik, yapılandırma önbelleği geçersiz ve yapılandırma aşaması yeniden çalıştırılmalıdır. Ayrıca, görev çıktısının bu dosyanın içeriğine bağlı olduğunu bilir, bu da yürütme önbelleğini optimize etmemizi de sağlar.UP-TO-DATE)".

Sonuç

Bu hata ayıklama macerası değerli bir ders oldu. Yapılandırma önbelleğinin "büyülü" davranışı, Gradle yaşam döngüsünü ve bildirimçi ve gecikmeli programlama (lazy).

Konfigürasyon önbelleğini devre dışı bırakmak, faydalı bir tanı aracıdır, ancak gerçek çözüm sağlam ve modern eklentiler geliştirmektir. Görevlerimizin girişlerini ve çıkışlarını API’leriyle doğru şekilde modelleyerek`Provider`, biz sadece bir hatayı düzeltmiyoruz, eklentimizin performansını, güvenilirliğini ve sürdürülebilirliğini iyileştiriyoruz.

Bir sonraki makalede bu refaktör işlemini uygulayarak YAML ayrıştırma görevimizi yapılandırma önbelleğiyle tamamen uyumlu hale getireceğiz.

İlgili Makaleler