Uvod

Ciljna publika : Gradle programeri koji su već susreli "magična" ili nepredvidljiva ponašanja gradle buildova.

У нашој авантури креирања плагина`site-baker`, smo sledili rigorozan TDD pristup. Svaka funkcionalnost je bila testirana, validirana, i napredovali smo sa pouzdanjem. I onda je jednog dana neočekivano stigli. Build-ovi su počeli da se ponašaju neravnomerno. Izmene u logici plugina ili u fajlovima konfiguracije su se čile da se ignorišu, i naši funkcioni testovi, koji su bili pouzdani, su počeli da neuspešaju bez razloga.

Posle intenzivne sesije debugovanja, krivac je identifikovan: lekeš konfiguracije Gradle.

Simptom: Neki Fantomski Builds

Problem se manifestovao na nekoliko načina :

  1. Ja sam menjao niz znakova u jednom zadatku`println`, ali stara niza je nastavila da se prikaže tokom izvršavanja.

  2. Menjao sam vrednost u svom fajlu`managed-jbake-context.yml`, ali je plugin postupao kao da fajl nije bio promenjen.

  3. Funkcionalni testovi, koji kreiraju test projekte na leto, pađali su jer plugin nije uspeo da otkrije nova kreirana konfiguraciona fajla.

Sve se odlagalo kao da Gradle izvršava "fantomsku verziju" našeg builda, ignorirajući naše najnovije izmene.

Istraživanje: Šta je keš konfiguracije ?

Keš konfiguracije je relativno moderna i ekstremno moćna funkcija Gradle-ova, aktiviran podrazumevano u novijim verzijama. Njegov cilj je da ubrzade gradnje.

Princip je jednostavan :
  1. При првом извршавању, Gradle извршава фазуКонфигурација(читање des`build.gradle.kts`, креирање задатака, решавање зависности) и конструише граф задатака.

  2. Na kraju ove faze, GradleСеријализује овај граф задатакаi kešira ga.

  3. Tokom sledećih izvršavanja, ako se ništa nije promenilo (skripte za izgradnju,gradle.properties, itd.), GradleПотпуно прескачу фазу конфигурацијеi ponovo koristi keširani graf zadataka.

Mnoštvo uštedjenog vremena je spektakularno na velikim projektima. međutim, ova performans ima svoju cenu: zahteva da se plugins pišu prema strožim pravilima.

Животни циклус кеша конфигурације
@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

Причина проблема: Непоглашајући плагин

Naš plugin`site-baker`kršio, ne znajući, više pravila keša konfiguracije. Da bi graf zadataka bio serijalizabilan, zadaci ne smeju da sadrže reference na složene objekte kao što je objekat`Project`ili čitati fajlove proizvoljno tokom faze izvršenja.

Naša glavna greška bila je da smo čitali sadržaj YAML fajla direktno u logiku izvršenja zadatka, koristeći referencu na putanju koja je bila smeštena u našoj ekstenziji. Ovaj pristup je nekompatibilan sa keširanjem jer Gradle ne može da zna da li se sadržaj fajla promenio ako se ovo čitanje ne modelira kaounos zadatka(Task Input).

Временно решење: Ономогући кеш

Da bi se otključali i vratili u ponašanje gradnje koje se može predvideti, najbrža rešenje je bilo da se isključi keš konfiguracije. Dovoljno je dodati sledeću liniju u fajl`gradle.properties`projekta koji koristi plugin (ili u našem slučaju, testni projekat)site-baker).

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

Odmah, builds su se vratili na svoje normalno ponašanje. Svako pokretanje je pokrenulo fazu konfiguracije i naše promene su bile uzeti u obzir.

Међутим, ово је обходно решење, не трајно решење. Оно жртвује перформансе и не решава основи проблем нашег плагина.

Истинско решение : Направити плагин совместим

Da bi plugin bio dobar građanin u modernom Gradle ekosistemu, mora biti kompatibilan sa keširanjem konfiguracije. To podrazumeva ponovo razmišljanje o tome kako podaci težu ka nasim zadacima.

Ključ je da se koristeAPI‑ji pružateljaod Gradle. Umesto prosleđivanja direktnih vrednosti (kao`String` ou un File) na naše zadatke, moramo provesti`Property<T>`или неке`Provider<T>`.

Ово је план рефакторинга :
  1. Пријавите унос задатака :Задатак који анализира YAML датотеку мора да декларише ову датотеку као улаз. За то се користи анотација`@InputFile`.

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


Повезани чланци