Uvod

Ciljna grupa: Razvojni inženjeri Gradle koji se suočavaju sa upravljanjem zavisnostima u projektima sa više build-ova.

U našoj potrazi za kreiranjem plugina`site-baker`, smo se trudili da održamo čistu i centralizovanu bazu koda. Jedna od najboljih praksi u modernom Gradle ekosustavu je korištenjekatalog verzija(libs.versions.toml) за управљање зависностима. Но шта се дешава када ваш пројекат постаје сложенији, као једанIzgradi kompozitГде независни билд (наш плагин) треба да буде укључен у друг ?

Tu je naša avantura došla do nezvaničanog obreta. Hteli smo da naš plugin`site-baker`, koji je sam po sebi Gradle projekat, koristi isti katalog verzija kao i naš glavni projekat. Ovaj članak, peti u našoj seriji, opisuje kako smo rešili ovaj izazov.

Katalog verzija (libs.versions.toml) : Jedno podsjetanje

Datoteka`gradle/libs.versions.toml`је функционалност Gradle-а која омогућава централизацију верзија и координата зависиености вашег пројекта. Обично је структуриран у четири секcije :

  • [versions]: Definiše alias za brojeve verzija (npr:`kotlin = "1.9.20"`).

  • [libraries]: Дефинише алиаси за потпуне зависносце, коришћењем верзија дефиницисаних изнад (на пример:`kotlin-stdlib = { module = "org.jetbrains.kotlin:kotlin-stdlib", version.ref = "kotlin" }`)

  • [bundles]`Skupiti više biblioteka pod jednim pseudinomom (primer:`jackson = ["jackson-core", "jackson-databind"]).

  • [plugins]: Definiše alias za Gradle pluginove.

Jednom definisano, Gradle automatski generiše tipizovane pristupnike, što čini vaše`build.gradle.kts`mnogo čitljivije:

dependencies {
    // Au lieu de : implementation("org.jetbrains.kotlin:kotlin-stdlib:1.9.20")
    implementation(libs.kotlin.stdlib)
}
Tok podataka iz kataloga verzija
@startuml
!theme plain
file "gradle/libs.versions.toml" as Toml
node "Gradle" as G
file "build.gradle.kts" as BuildScript

Toml --> G : "je čitan od"
G --> BuildScript : "generiše akcesor `libs"
BuildScript -> G : "Koristi `libs` za deklarisanje zavisnosti"
@enduml

2. Problem : Jedan Build Kompozitni i dva odvojena sveta

Наша структура пројекта је једанIzgradi kompozit. Главни пројект (thymeleaf.cheroliv.com) uključuje projekat plugina (site-baker) komandom`includeBuild("site-baker")у фајлу`settings.gradle.kts.

Struktura kompozitnog građenja
@startuml
!theme plain
package "Glavni projekt" {
  file "settings.gradle.kts" as MainSettings
  folder "gradle" {
    file "libs.versions.toml" as MainToml
  }
}

package "Plugin `site-baker` (Build Uključen)" {
  file "settings.gradle.kts" as PluginSettings
  file "build.gradle.kts" as PluginBuild
}

MainSettings -> PluginSettings : `includeBuild("site-pekar")`
PluginBuild ..> MainToml : **Voulait accéder à...**
note right on link: ...mais ne pouvait pas !
@enduml

Problem je što je, po defaultu, uključen build jedanodvojen svet. On ima svoju konfiguraciju, svoj životni ciklus, i on ne vidi datoteku`libs.versions.toml`glavnog builda. Naš`plugin/build.gradle.kts`pokušavao je da koristi`libs.plugins.kotlin.jvm`, ali objekat`libs`Nije generisan iz ispravne TOML datoteke, što je izazvalo greške u gradnji.

3. Решение: Делити решење зависности

Posle nekoliko istraživanja, rešenje se ukazalo kao funkcionalnost Gradle dizajnirana baš za ovaj slučaj :`dependencyResolutionManagement`.

У фајлу`settings.gradle.kts` du build uključen(site-baker/settings.gradle.kts), možemo da Gradle-u kažemo gde da pronađe katalog verzija koje treba da koristimo.

Ovo je konfiguracija koju smo dodali`site-baker/settings.gradle.kts`:

// site-baker/settings.gradle.kts

dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        gradlePluginPortal()
        mavenCentral()
    }
    versionCatalogs {
        create("libs") {
            from(files("../gradle/libs.versions.toml"))
        }
    }
}

rootProject.name = "site-baker"
include("plugin")

Анализирамо критичан део:

versionCatalogs {
    create("libs") { // Crée un catalogue nommé 'libs'
        from(files("../gradle/libs.versions.toml")) // En utilisant ce fichier
    }
}
  • create("libs"): Декларишем каталог верзија који ће бити доступан преко алиаса`libs`.

  • from(files("../gradle/libs.versions.toml"))`Ovo je magija. Govorimo Gradle-u da je izvor ovog kataloga datoteka TOML koja se nalazi u direktorijumu.`gradle du roditeljski projekat(../).

С овим подешавањем, саграда`site-baker`Сада зна да мора да користи каталог верзија главног пројекта. Објекат`libs`је правилно генерисан, и зависимости су решены као што је планирано.

4. Zaključak : Moć dobro upravljenih kompozitnih gradnje

Ovo iskustvo je bilo bogato lekcijama. Katalog verzija je fantastičan alat za održavanje, ali ponašanje u scenarijima složenih građenja nije uvek intuitivno.

Ključ je da se sećamo da je uključen build i dalje nezavisni build. Da bi se delile konfiguracije, kao što je katalog verzija, potrebno je koristiti eksplicitne mehanizme koje pruža Gradle, kao što je blok`dependencyResolutionManagement`у`settings.gradle.kts`.

Rešavanjem ovog problema, nismo samo napravili naš build čistiji, već smo takođe jačili konsistenciju našeg projekta osiguravajući da plugin i glavni projekat dele jedinstveni izvor istine za njihove zavisnosti.

У следећем чланку, nastavit ćemo da poboljšamo naš plugin dodavanjem složenijih zadataka, sada kada je naše upravljanje zavisnostima čvrsto i centralizovano.

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