ÖNEMLİ : Kendim için aldığım notlar. Umarım size de bir faydası olur. Bu yazı Jendrik Johannes’in Gradle’ı Anlamak İsimli Youtube içeriklerinin bir çevirisidir ve yazarın izni alınarak paylaşılmaktadır. Amacım hem aldığım notları sizinle paylaşmak hem de bilmeyenler için Jendrik’i size tanıtmaktır. Jendrik’in Gradle ile ilgili çok değerli içeriklere sahip olduğunu düşünüyorum. Türkçe kaynağa destek olmak için bu çevirileri sizinle paylaşmak istedim. Aşağıdaki yazı Jendrik’in kendi cümleleri olup, sadece turuncu blok içerisinde öne çıkardığım notlar bana aittir. Referanslara ise sayfa sonundan ulaşabilirsiniz.

Serinin Diğer İçerikleri:


Diğer içerikleri görüntülemek için linke tıklayın.

PLUGINS

Bu yazıda Gradle’da çok önemli olan “eklentiler (plugins)“ kavramından bahsedeceğiz. Gradle bir dizi güçlü çekirdek (core) sistemle birlikte gelir. Ancak üstteki her şey bir eklentidir(plugin).

Benim Notum : Plugin’ler Gradle’ı genişletmek için kullanılır. Ayrıca proje konfigürasyonlarını modülerleştirmek (modularize) ve yeniden kullanmak (reuse) için de kullanılırlar.

Farklı plugin dağıtım (distribution) türleri


Kabaca üç farklı eklenti (plugin) dağıtım türünü ayırt edebiliriz. 1

gradle'ı anlamak (understanding gradle) Different kinds of plugin distribution


  1. Birinci, Gradle ile birlikte verilen ve önceki videoda kullandığımız “java-library” eklentisi gibi basit bir kimlikle uygulanabilen çekirdek eklentiler (core plugins).
  2. İkincisi, genellikle Gradle Eklenti Portalında bulunan topluluk eklentileri (community plugins). Bunlar, nitelikli bir kimlik ve bu videoda kullanacağımız Kotlin eklentisi gibi bir sürüm kullanılarak uygulanır.
  3. Üçüncüsü, yerel (local) olarak kendi yazdığınız konvansiyon eklentileri (convention plugins). Ayrıca bu videomuzda bunlardan daha detaylı bahsedeceğiz.
1
2
3
4
5
plugins{
    id("java-library") // Gradle Core Plugin
    id("org.jetbrains.kotlin.jvm") version "1.5.21" // Community Plugin with own version
    id("my-java-library") // locally defined Plugin (e.g. your own Convention Plugin)
}

O halde bir önceki bölümde oluşturmaya başladığımız projeye bir göz atalım.

Benim Notum: Gradle Plugin Türleri Nelerdir?


3 farklı plugin dağıtım türü var demiştik. Bununla beraber Gradle’da iki genel plugin türü vardır: binary plugins ve script plugins. 2

  • “Binary plugins”, Plugin arayüzü uygulanarak (implementing the Plugin interface) programlı olarak veya Groovy veya Kotlin DSL’deki deklarasyonlar aracılığıyla yazılır. Bir “build script”‘de, proje hiyerarşisi içinde veya harici olarak bir plugin jar’da bulunabilirler.

  • “Script plugins”, build’i ayrıca yapılandıran ve genellikle build’i manipüle etmek için deklaratif bir yaklaşım uygulayan ek “build scripts”‘lerdir. Genellikle bir build içinde kullanılırlar ancak harici hale getirilebilir ve uzaktan erişilebilirler.

Bir plugin genellikle bir script plugin olarak başlar (çünkü yazılması kolaydır). Daha sonra, kod daha değerli hale geldikçe, kolayca test edilebilecek ve birden fazla proje veya kuruluş arasında paylaşılabilecek bir binary plugin’e taşınır.

EKLENTİ (PLUGIN) KULLANMA

Üç alt projeye sahip bir proje tanımlamıştık: biri data-model için, biri business-logic için ve biri de app için. Business-logic alt projemizin build dosyasına bakalım. Daha önce “java-library” eklentisini uygulamıştık. Şayet Kotlin desteği istiyorsak bunun üzerine “org.jetbrains.kotlin.jvm” eklentisini ekleyebiliriz. Burada bir sürümü (version) nasıl tanımlamamız gerektiğini görebilirsiniz çünkü bu, Gradle’ın kendisinden bağımsız olarak sürümlendirilmiş bir topluluk eklentisidir (community plugin). Gradle, bu eklentiyi (plugin) Gradle Plugin Portalı‘ndan alabileceğini biliyor çünkü bunu settings dosyamızda tanımlamıştık.

Benim Notum: settings.gradle


Görüldüğü üzere Gradle Plugin Portal burada tanımlanıyor.

1
2
3
4
5
6
7
pluginManagement{
    repositories {
        gradlePluginPortal() // Artifact Repository
        ...
    }
    ....
}

Başka bir Not: Bir “Settings” script’i, hem Groovy hem de Kotlin dillerinde özel bir kısayol olan “{ …​ }” ifadesini sıklıkla kullanan, Gradle API’sine yapılan bir dizi yöntem çağrısıdır. “{ }” bloğuna Kotlin’de lambda veya Groovy’de closure adı verilir.

Basitçe söylemek gerekirse, “plugins{ }” bloğu, bir Kotlin lambda nesnesinin veya Groovy closure nesnesinin argüman olarak iletildiği bir yöntem çağrısıdır. “plugins{ }” bloğu, bunun kısa şeklidir: 3

1
2
3
plugins(function() {
    id("plugin")
})

Bloklar Gradle API yöntemleriyle haritalanır. Fonksiyonun içindeki kod, Kotlin lambda’da “receiver”, Groovy closure’da da “delegate” olarak adlandırılan “this” nesnesine karşı yürütülür. Gradle doğru “this” nesnesini belirler ve karşılık gelen doğru yöntemi çağırır. Yöntem çağrısı id("plugin")‘nin this nesnesi “PluginDependegencySpec” türündedir.

Settings dosyası, DSL’lerin üzerine inşa edilmiş Gradle API çağrılarından oluşur. Gradle, script’i yukarıdan aşağıya satır satır yürütür.

gradle'ı anlamak (understanding gradle) Using plugins in the example



1
2
3
4
5
6
7
8
9
10
11
12
13
plugins{
    id("java-library") // Gradle Core Plugin
    id("org.jetbrains.kotlin.jvm") version "1.5.21" // Community Plugin with own version
}

java {
    toolchain.languageVersion.set(JavaLanguageVersion.of(11))
}

dependencies {
    implementation(project(":data-model"))
    implementation("org.apache.commons:commons-lang3:3.9")
}
gradle'ı anlamak (understanding gradle) kotlin support


Ancak burada gördüğünüz gibi build dosyamız büyümeye başlıyor. Ne kadar çok plugin uygularsak ve ne kadar çok plugin yapılandırırsak, projemiz o kadar büyür. Ayrıca alt projelerimizin çoklu build dosyalarında (multiple build files) çok fazla tekrar var. Tüm alt projelerimiz aynı Java sürümüne göre oluşturulacaksa ve hepsinde Kotlin desteği varsa, tüm bu yapılandırmayı her build dosyamızda tekrarlamamız gerekir. Bunun önüne geçmek için kendi tanımladığımız “konvansiyon eklentilerinden (convention plugins)“ faydalanabiliriz. Bir sonraki bölüm bu plugin’lerden bahsedeceğiz.

Benim Notum:


1
2
3
4
5
kotlin { //this: KotlinJvmProjectExtension

}


  • kotlin {} yapılandırma bloğu, Kotlin community plugin uygulandığında yüklenen çok yararlı bir uzantı (extension) işlevidir.

  • Bir task, sınıfları derlemek veya javadoc oluşturmak gibi bir build için tek bir atomik çalışma parçasını temsil eder.

  • useJUnitPlatform() : JUnit Platform tabanlı testleri keşfedip ve uygular. 4


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
plugins{
    id("java-library") // Gradle Core Plugin
    id("org.jetbrains.kotlin.jvm") version "1.5.21" // Community Plugin with own version
}

java {
    toolchain.languageVersion.set(JavaLanguageVersion.of(11))
}

tasks.test {
    useJUnitPlatform()
}


kotlin {

}

dependencies {
    implementation(project(":data-model"))
    implementation("org.apache.commons:commons-lang3:3.9")
}

Benim Notum: bir hata mesajı


Could not create task ‘:business-logic:compileTestKotlin’. Cannot use @TaskAction annotation on method AbstractKotlinCompile.execute() because interface org.gradle.api.tasks.incremental.IncrementalTaskInputs is not a valid parameter to an action method.

Try: Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights. Get more help at https://help.gradle.org.

Deprecated Gradle features were used in this build, making it incompatible with Gradle 9.0. You can use ‘--warning-mode all’ to show the individual deprecation warnings and determine if they come from your own scripts or plugins. For more on this, please refer to this in the Gradle documentation. BUILD FAILED in 580ms ——

kotlin community plugin’in sürümünden ötürü yukarıdaki gibi bir hata alabilirsiniz. Şayet bu sürümü,

1
id("org.jetbrains.kotlin.jvm") version "1.5.21"

bu şekilde

1
id("org.jetbrains.kotlin.jvm") version "1.9.0"

değiştirirsek sorun çözülür.

Şimdi benzer işlemleri diğer build dosyalarında da uyguluyoruz. Yani data-model ve app‘i kastediyorum.

gradle'ı anlamak (understanding gradle) kotlin support


Benim Notum: Plugin'leri kullanma


Bir eklentide kapsüllenmiş (encapsulated) yapı mantığını (build logic) kullanmak için Gradle’ın iki adım gerçekleştirmesi gerekir. Önce eklentiyi çözmesi (resolve the plugin), ardından eklentiyi hedefe, genellikle bir Projeye uygulaması (apply the plugin) gerekir.

Bir eklentiyi çözmek (yani, resolve the plugin), belirli bir eklentiyi içeren jar’ın doğru sürümünü bulmak ve onu script sınıf yoluna (script classpath) eklemek anlamına gelir. Bir eklenti çözüldüğünde, API’si bir build script’te kullanılabilir. Hatırlayacağınız üzere 2 tür plugin vardı. Bunlardan biri script plugin, diğeri ise binary plugin’di. Script plugin’ler, uygulanırken (apply) sağlanan belirli dosya yolu (specific file path) veya URL’den çözümlenmeleri (resolved) bakımından “kendi kendine çözümlenir (yani self-resolving‘dir)”. Bununla beraber Gradle dağıtımının bir parçası olarak sağlanan core binary plugin’ler otomatik olarak çözülür.

Bir eklenti uygulamak (applying a plugin), eklenti ile geliştirmek istediğiniz Projede eklentinin Plugin.apply(T) öğesini yürütmek anlamına gelir.

Eklentileri tek bir adımda çözmek ve uygulamak için DSL eklentileri (plugins DSL) önerilir.

Convention eklentileri (plugin) aracılığıyla build konfigürasyonlarını yeniden kullanın

Bu eklentilerde, isteğe bağlı “build” konfigürasyonunu, hatta custom “build” mantığını kapsülleyebiliriz.

Ayrı bir build logic yapısı oluşturun


Bu tür “konvansiyon eklentilerini (convention plugins)“ tanımlamak için ayrı bir Gradle “build’ine” ihtiyacımız var. Bunu tamamen ayrı bir Gradle yapısını (build) temsil eden yeni bir klasör oluşturarak yapıyoruz - buna “my-build-logic” diyelim -

gradle'ı anlamak (understanding gradle) Create a separate build logic build


main build’imizde, bu build’i Gradle’ın diğer eklentileri arayabileceği bir yer olarak bilinir hale getirmemiz gerekiyor. Bu konuyla ilgili içerikten hatırlayacağınız gibi bunu settings dosyamızda yapıyoruz.

Benim Notum:


Önceden derlenmiş komut dosyası eklentisi (precompiled script plugin) adlarının iki önemli sınırlaması vardır:

  • org.gradle ile başlayamazlar.
  • Yerleşik bir plugin kimliğiyle aynı isme sahip olamazlar. Bu, precompiled script plugin’lerin sessizce göz ardı edilmemesini sağlar. 5
gradle'ı anlamak (understanding gradle) Create a separate build logic build


Şimdi “my-build-logic” Gradle build’imize bakalım. Build’in bağımlılıklarının nerede bulunduğunu tanımlamak için bu build’in kendi settings dosyası vardır. Örneğimizde “topluluk eklentilerine (community plugins)“ erişim sahibi olmak istiyoruz, bu nedenle depo (repository) olarak “Gradle Plugin Portalı”nı ekliyoruz.

gradle'ı anlamak (understanding gradle) Create a separate build logic build


Ayrıca “konvansiyon eklentilerimizi (convention plugin)” tanımlamak için kullanacağımız bir alt proje (subproject) de tanımlıyoruz.

gradle'ı anlamak (understanding gradle) Create a separate build logic build


1
2
3
4
5
6
7
dependencyResolutionManagement {
    repositories {
        gradlePluginPortal()
    }
}

include("java-plugins")

Kotlin-dsl plugin kullanma


Alt projede elbette bir build dosyası oluşturuyoruz. Build dosyasında artık “kotlin-dsl” eklentisini uyguluyoruz. Bu, özellikle Kotlin DSL’de eklentiler yazmak için kullanılan bir Gradle çekirdek eklentisidir (core plugin). Groovy DSL’i burada gösterildiği gibi kullanmak istiyorsanız bir eşdeğeri var.

gradle'ı anlamak (understanding gradle) kotlin-dsl plugin


Bir topluluk eklentisi (community plugin) kullanmak için bir bağımlılık (dependency) deklare edin


Kotlin eklentisini kullanmak istediğimiz için burada, “build” dosyasında bir bağımlılık (dependency) tanımlamamız gerekiyor. "Konvansiyon eklentileri" için, diğer eklentileri bulmak amacıyla normal bağımlılık yönetimi (dependency management) kullanılır. Bu şu anda gradle dökümantasyonunda iyi bir şekilde belgelenmemiştir, dolayısıyla bağımlılıkların doğru koordinatlarını bulmak biraz zordur. Bunu Gradle Eklenti Portalında ararsanız, bu örnek resimde gösterildiği gibi koordinatları en altta bulabilirsiniz.

gradle'ı anlamak (understanding gradle) Declare a dependency to use a community plugin


Kotlin DSL’de convention plugin yazma


gradle'ı anlamak (understanding gradle) kotlin source set, kotlin source tree


Artık “kotlin-dsl” eklentisi uygulandığına göre, şekilde görüldüğü üzere src/main/kotlin klasörü oluşturup, daha sonra bu klasör içerisine Gradle scriptlerini yazabiliriz.

Benim Notum: Dile özgü kaynak dosyalarını ayırma (Separate language-specific source files)


Bağımsız projeler (standalone projects) olarak yazılan pluginlere ek olarak Gradle, Groovy veya Kotlin DSL’lerinde önceden derlenmiş komut dosyası eklentileri (precompiled script plugins) olarak yazılmış build logic sağlamanıza da olanak tanır. Bunları “src/main/groovy” dizinine *.gradle dosyaları veya “src/main/kotlin” dizinine *.gradle.kts dosyaları olarak yazıyorsunuz.

Gradle’ın dil eklentileri (language plugins), kaynak (source) kodunu keşfetmeye ve derlemeye yönelik kurallar oluşturur. Örneğin, Java eklentisini (java plugin) uygulayan bir proje, kodu otomatik olarak src/main/java dizininde derleyecektir. Diğer dil eklentileri de aynı modeli izler. Dizin yolunun son kısmı genellikle kaynak dosyaların beklenen dilini gösterir.

Aşağıdaki kaynak ağacı (source tree) Java ve Kotlin kaynak dosyalarını içerir. Java kaynak dosyaları src/main/java‘da yaşarken, Kotlin kaynak dosyaları src/main/kotlin‘de yaşar. 6

1
2
3
4
5
6
7
8
.
├── build.gradle.kts
└── src
    └── main
        ├── java
           └── HelloWorld.java
        └── kotlin
            └── Utils.kt
gradle'ı anlamak (understanding gradle) Write convention plugin in Kotlin DSL


my-java-library.gradle.kts” adında bir script ekliyoruz. Gördüğünüz gibi build dosyaları için kullandığımız uzantıların (extension) aynısını kullanıyoruz. Ve aslında bir build dosyasına yazabileceğimiz her şeyi bu plugin’e yazabiliriz. Şimdi daha önce build dosyamızda tanımladığımız tüm plugin uygulamasını ve yapılandırmasını bu “konvansiyon eklentisine (convention plugin)“ yerleştirdik.

Benim Notum:




my-java-library.gradle.kts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
plugins {
    id("java-library")
    id("org.jetbrains.kotlin.jvm")
}

java {
    toolchain.languageVersion.set(JavaLanguageVersion.of(11))
}

tasks.test {
    useJUnitPlatform()
}
kotlin {
    // ...
}

Benim Notum:


Bu durumla ilgili Jendrik’e, neden kotlin dizini altında, my-java-library.gradle.kts script’i içindeki kotlin plugin deklarasyonunu version numarası belirtmeden gerçekleştirdik, şeklinde bir soru yönelttim.

O da, gradle’ın bu durumu henüz iyi bir şekilde belgelendirmediğini ifade etti. Aslında yukarıdaki şekilde bu durumu izah etmeye çalıştığını da belirtti.

“convention” eklentilerinizde, tıpkı core Gradle eklentilerini kullandığınız gibi, “Gradle Plugin Portalı”ndaki “community” eklentileri gibi diğer kaynaklardan gelen harici eklentileri kullanabilirsiniz. (Core Gradle eklentileri, ‘java-library’ veya ‘application’ gibi Gradle ile birlikte verilen eklentilerdir. Sırf bu yüzden versiyon numarası belirtilmesine gerek yoktur.)

Ayrı bir “build logic“‘e sahip olduğunuzda (build/project), diğer Gradle projelerinde olduğu gibi Gradle’ın bağımlılık yönetimi (dependency management) mekanizmalarını kullanırsınız. Harici eklentiler (external plugins) veya daha iyisi eklentileri içeren jar’lar, daha sonra build logic projesinin build.gradle.kts dosyasında tanımladığınız projenin bağımlılıkları (dependencies) haline gelir. Bu örnekte, build.gradle.kts dosyası içinde elimizde:

1
2
3
dependencies {
    implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.21")
}

var.

Makalenin başında gösterdiğimiz “kısa notasyon (short notation) yani id("org.jetbrains.kotlin.jvm") version "1.5.21", “harici eklentileri (external plugins)” doğrudan projenizin “build.gradle.kts” dosyasında bir “build Logic” projesi olmadan kullanmak için kullanılabilir. Ama buradaki gibi ayrı bir build logic mantığı kullandığımızda, “java-plugins/src/main/kotlin/*.gradle.kts” dosyalarının içinde id("org.jetbrains.kotlin.jvm") şeklinde, sürüm numarası olmadan kullanılması gerekir. Sürüm yerine java-plugins/build.gradle.kts dosyasında, eklentiyi içeren jar’a bağımlılık (dependency) tanımlarsınız. Bu durumda az önce belirttiğimiz kod bloğu bu sorunu çözecektir. Yani;

1
2
3
dependencies {
    implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.21")
}

Dikkat ederseniz, bu eklenti (kotlin-gradle-plugin) Gradle çekirdeğinde (core) doğrudan bulunmadığından, Gradle’a eklentiyi içeren jar’ı build time’da kullanılabilir hale getirmesini söylemek için “my-build-logic/java-plugins” projenizin “build” dosyasına bir bağımlılık (dependency) eklemeniz gerekir.

Benim Notum:


Peki, oluşturmak istediğimiz convention plugin içinde kullanmak istediğimiz plugini version numarası belirterek kullanmak istersek ne olur? Yani yukarıda oluşturduğumuz script’i şu şekilde değiştirdiğimizi hayal edelim;

my-java-library.gradle.kts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
plugins {
  id("java-library")
  id("org.jetbrains.kotlin.jvm") version "1.9.0"
}

java {
  toolchain.languageVersion.set(JavaLanguageVersion.of(11))
}

tasks.test {
  useJUnitPlatform()
}
kotlin {
  // ...
}
1
2
3
4
5
Invalid plugin request [id: 'org.jetbrains.kotlin.jvm', version: '1.9.0'].
Plugin requests from precompiled scripts must not include a version number.
Please remove the version from the offending request and make sure the module
containing the requested plugin 'org.jetbrains.kotlin.jvm' is an implementation
dependency of project ':my-build-logic:java-plugins'.

Arkadaşlar bu şekilde bir hata alırız. Bunun nedeni, önceden derlenmiş komut dosyalarından gelen eklenti istekleri sürüm numarası içermemelidir.

Şayet versiyon numarasını kaldırırsam da şu şekilde bir hata alırım.

1
2
3
4
5
6
7
8
9
10
FAILURE: Build failed with an exception.

* Where:
Precompiled script plugin '/Users/.../.../my-build-logic/java-plugins/src/main/kotlin/my-java-library.gradle.kts' line: 1

* What went wrong:
Plugin [id: 'org.jetbrains.kotlin.jvm'] was not found in any of the following sources:

- Gradle Core Plugins (plugin is not in 'org.gradle' namespace)
- Plugin Repositories (plugin dependency must include a version number for this source)

Doğru kullanım ilgili plugini versiyon numarası olmadan deklare edip, bağımlılığını ise build dosyası içindeki dependency bloğu içinde bildirmekle olur.

Tüm alt projelerde convention plugin’i kullanma

Dosyanın adı artık tüm alt projelerimizde kullanabileceğimiz bir plugin ID’si olacaktır. Kendi oluşturduğumuz “my-java-library” eklentimizi uygulamak için tüm alt projelerimizin build dosyalarını şu şekilde değiştirebiliriz.

business-logic içindeki build.gradle.kts (yapılan değişiklikler + ve - ile gösterilmektedir)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
plugins{
-    id("java-library") // Gradle Core Plugin
-    id("org.jetbrains.kotlin.jvm") version "1.9.0" // Community Plugin with own version
+    id("my-java-library")
}

- java {
-    toolchain.languageVersion.set(JavaLanguageVersion.of(11))
- }

- tasks.test {
-     useJUnitPlatform()
- }

- kotlin {
- }

dependencies {
    implementation(project(":data-model"))
    implementation("org.apache.commons:commons-lang3:3.9")
}

business-logic içindeki build.gradle.kts (son hali)

1
2
3
4
5
6
7
8
plugins{
    id("my-java-library") // kendi yaptığımız convention plugin
}

dependencies {
    implementation(project(":data-model"))
    implementation("org.apache.commons:commons-lang3:3.9")
}

Benzer değişikliği data-model içindeki build.gradle.kts‘de de yapıyoruz.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
plugins{
-    id("java-library") // Gradle Core Plugin
-    id("org.jetbrains.kotlin.jvm") version "1.9.0" // Community Plugin with own version
+    id("my-java-library")
}

- java {
-    toolchain.languageVersion.set(JavaLanguageVersion.of(11))
- }

- tasks.test {
-     useJUnitPlatform()
- }

- kotlin {
- }

data-model içindeki build.gradle.kts (son hali)

1
2
3
plugins{
    id("my-java-library") // kendi yaptığımız convention plugin
}

app alt projesinin hem içi boş olduğu için hem de bir sonraki içerikte kullanacağımızdan onun üzerinde bir işlem yapmadık. Ama benzer işlemleri ona da uygulayabilirdik.

Özetle tekrar eden kısımları kendi yaptığımız convention plugin olan my-java-library içinde, yani tek bir yerde topladık diyebiliriz.

Artık tüm ortak konfigürasyonları build dosyalarımızda otomatik olarak paylaşıyoruz ve tek noktadan değiştirebiliyoruz. Build dosyalarında olduğu gibi, convention eklentinizi (plugin) yazmak için burada Kotlin dilinin tüm gücüne sahibiz.

gradle'ı anlamak (understanding gradle) Write convention plugin in Kotlin DSL


Burada Kotlin kaynak klasörüne sahip olduğumuz için, kodu ayrı dosyalara, hatta ayrı sınıflara çıkarabiliriz. Convention plugin yazmanın en basit hali bu şekildedir. Bu, build dosyalarınızı bozmadan build konfigürasyonlarını yapılandırılmış (structured) ve bakımı kolay (maintainable) tutmanıza olanak tanır.

Benim Notum: Plugin Dağıtım Türleri Hakkında


Jendrik, plugin dağıtım türlerinin sınıflandırılması ile ilgili şunlara da değinmektedir.

Kategorik olarak plugin dağıtım türlerini 3 bölüme ayırmak yeni başlayanlar için bilinmesi yeterlidir. Ama bunu detaylandırmak da mümkündür. Daha derine inersek, sınıflandırmak için kullanabileceğiniz birkaç boyut vardır. 7

  1. İlk olarak, bir eklentiyi nasıl uyguladığınızın teknik boyutu var. Burada zaten birkaç seçeneğiniz var:
    1. (a) Eklentiyi, Plugin<Project> implement eden bir sınıf olarak uygulayın ve sonrasında onu build dosyasına kaydedin - burada tüm JVM dillerini seçebilirsiniz - yani, Java, Kotlin, Groovy, Scala’da uygulayabilirsiniz.
    2. (b) Eklentiyi, daha az gürültülü olan ve size daha fazla kolaylık sağlayan “önceden derlenmiş komut dosyası eklentileri (pre-compiled script plugins)” olarak uygulayın (kısacası bu içerikte anlatılan convention eklentiler gibi). Yani Eklentiyi .gradle veya .gradle.kts script olarak yazarsınız - bu daha sonra Kod’a “derlenir”, böylece çalışma zamanında Gradle, (a) ve (b) seçenekleri arasında hiçbir fark görmez.
  2. İkincisi, plugini nereye koyduğunuzun ve build’inizde nereden “tükettiğinizin (consume)” boyutu vardır. Bunu söyleyeceğimiz birçok kategoriye ayırabilirsiniz. Ancak sonuçta en büyük fark versiyonlamadır. İçerikteki 3 kategoriye geri dönülen yer de burasıdır:
    1. Gradle çekirdeğinden (gradle core) eklenti tüketin (consume) (sürüm gerekmez, ancak eklenti binary’dir ve değiştirilemez).
    2. Eklentiyi bir repodan (repository) (portaldan veya private bir repodan veya MavenCentral gibi başka bir genel repodan) tüketin (consume), burada eklentinin sürümünü (version) belirlemeniz gerekir ve plugin’i tüketirken, ilgili sürümü, tüketen build’in herhangi bir yerinde tanımlamanız gerekir.
    3. Eklentiyi başka bir yerel(local) build’den tüketin (bu içerikteki my-build-logic). Burada bir sürüme (version) ihtiyacınız yok çünkü Gradle her zaman en son durumu (state’i) kullanır. Ancak burada, build üzerinde çalışırken eklentiyi istediğiniz gibi değiştirebilirsiniz.
  3. Üçüncüsü, “Konvansiyon Eklentisi (Convention Plugin)” (yani, yalnızca bir takım şeyleri yapılandıran eklenti) ile “Build Logic Ekleyen Eklenti” (yani Kotlin, Android veya Spring Boot Eklentileri vb. gibi bir eklenti.) arasında kavramsal bir ayrım vardır. Ama burada da ayrım akışkandır. Şunu söyleyebilirsiniz: Yeni Task’lar (Transform’lar veyahut Action’lar) uygulamadığınız sürece bu bir convention’dır. Ya da şöyle diyebilirsiniz: “Yerel (local)” tuttuğum bir şey olduğu sürece bu bir convention’dır, çünkü zaten var olan şeylerin etrafında “küçük şeyler” inşa ediyorum. Bu yüzden, tüm bunları 3 kategoriye indirgeme düşüncem; Bir projeye başladığınızda çoğunlukla standart yapıyı takip etmeniz ve alışılagelmiş eklentileri kullanmanız yönündeydi, yani;
    1. core plugin’leri kullanın
    2. Portaldaki topluluk eklentilerini (community plugins) kullanın ve bunların sürümlerinin (versions) olduğunun farkında olmanız gerekir.
    3. build yapılandırmanızı düzenlemek için kendi küçük eklentilerinizi yazın - ve bunun için “önceden derlenmiş komut dosyası eklentileri (yani pre-compiled script plugins)” kullanımı en iyi/en kolay olanlardır.

Gradle’ın bir parçası oldukları için ‘çekirdek eklentiler (core plugins)’ yazamazsınız. Diğer tüm eklentiler kavramsal olarak aynıdır. Yani, bir “Topluluk eklentisi (community plugin)”, yayınlanan (published) ve bir sürümü (version) olan bir eklentidir. Bu tanımla, bu örnekte yazdığımız tipteki eklentiler (yani convention/local/custom olanlar), şayet onları yayınlarsanız (yani bir platformda publish ederseniz) “topluluk eklentileri (community plugins)” haline gelir (belki de onlara “yayınlanmış eklentiler (‘published plugins)” demek daha iyi bir seçim olurdu).

Referanslar:

Daha Fazla Okuma: