Ö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.
TASKS (Görevler)
Önceki içeriklerde tanıttığımız örnek projeye geri dönelim. Bu sefer, task’ları çalıştırdığımız bir alt projeye örnek olarak “app” alt projesine odaklanacağız. Şu anda projenin build dosyası boş.
Boş Bir Projenin Görevleri Nelerdir? (Tasks of a plain/empty project)
Gradle’dan build’ları çalıştırmak için mevcut görevleri (tasks) bize göstermesini istersek, yalnızca birkaç help task’ının mevcut olduğunu görebiliriz.


Bunun nedeni, Gradle'ın çekirdeğinin yalnızca bu görevleri build'inizi analiz etmek için sağlamasıdır. Projenizi gerçekten oluşturmak için gereken diğer görevler(tasks) de pluginler tarafından eklenir.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
% gradle :app:tasks
> Task :app:tasks
------------------------------------------------------------
Tasks runnable from project ':app'
------------------------------------------------------------
Help tasks
----------
buildEnvironment - Displays all buildscript dependencies declared in project ':app'.
dependencies - Displays all dependencies declared in project ':app'.
dependencyInsight - Displays the insight into a specific dependency in project ':app'.
help - Displays a help message.
javaToolchains - Displays the detected java toolchains.
kotlinDslAccessorsReport - Prints the Kotlin code for accessing the currently available project extensions and conventions.
outgoingVariants - Displays the outgoing variants of project ':app'.
projects - Displays the sub-projects of project ':app'.
properties - Displays the properties of project ':app'.
resolvableConfigurations - Displays the configurations that can be resolved in project ':app'.
tasks - Displays the tasks runnable from project ':app'.
To see all tasks and more detail, run gradle tasks --all
To see more detail about a task, run gradle help --task <task>
Benim Notum : gradle tasks
komutunda olduğu gibi ./gradlew tasks
komutuyla da ilgili projenin görevlerini listeleyebilirsiniz. Aslında ./gradlew
komutunu kullanmak çoklu projelerde versiyon tutarlılığını sağlamak için daha iyidir.
Benim Notum: Register and configure tasks:

Bir görev (task), bir build’in gerçekleştirdiği bazı bağımsız iş birimlerini temsil eder. Görevler (Tasks), sınıfların derlenmesi, JAR oluşturma, Javadoc oluşturma, birim testlerinin (unit tests) çalıştırılması veya bir WAR dosyasının sıkıştırılması (zipping up a WAR file) gibi bazı temel işleri gerçekleştirir. Görevler genellikle pluginlerde tanımlanmış olsa da, görevleri build script’lerde kaydetmeniz (register) veya yapılandırmanız gerekebilir. Özetle görevler ya build script’lerden ya da pluginlerden gelir. 1 2
Bir kullanıcı komut satırında ./gradlew build
komutunu çalıştırdığında Gradle, build görevini, bağlı olduğu diğer görevlerle birlikte yürütür.
Bir görevin kaydedilmesi (registering), görevi projenize ekler.
TaskContainer.register(java.lang.String)
yöntemini kullanarak görevleri bir projeye kaydedebilirsiniz:
1
2
3
4
5
6
tasks.register<Zip>("zip-reports") {
from 'Reports/'
include '*'
archiveName 'Reports.zip'
destinationDir(file('/dir'))
}
Kaçınılması gereken TaskContainer.create(java.lang.String)
yönteminin kullanımını görmüş olabilirsiniz:
1
2
3
4
5
6
tasks.create<Zip>("zip-reports") {
from 'Reports/'
include '*'
archiveName 'Reports.zip'
destinationDir(file('/dir'))
}
Görev yapılandırmasından kaçınmayı sağlayan “register()
”, “create()
” yerine tercih edilir.
Yapılandırmak için bir görevin yerini “TaskCollection.named(java.lang.String)
” yöntemini kullanarak saptayabilirsiniz. İlgili görevi, oluşturulmasını veya yapılandırılmasını tetiklemeden ada (name) göre bulur; böyle bir nesne yoksa başarısız olur.
1
2
3
tasks.named<Test>("test") {
useJUnitPlatform()
}
Aşağıdaki örnek, Javadoc
görevini, Java kodundan otomatik olarak HTML belgeleri oluşturacak şekilde yapılandırır:
1
2
3
4
5
tasks.named("javadoc").configure {
exclude 'app/Internal*.java'
exclude 'app/internal/*'
exclude 'app/internal/*'
}
1
2
3
4
5
6
//build.gradle.kts
tasks.register("hello") {
doLast {
println("Hello world!")
}
}
Örnekte, build script, TaskContainer API’yi kullanarak “hello
” adlı tek bir görevi kaydeder (register) ve ona bir eylem (action) ekler. Aslında, TaskContainer, bir dizi Task örneğinin yönetilmesinden sorumludur. Bir TaskContainer örneğini Project.getTasks()
‘ı çağırarak veya build script‘inizde tasks
özelliğini (property) kullanarak elde edebilirsiniz. Bu link aracılığı ile tüm özellikleri (properties) görüntüleyebilirsiniz.
Projedeki görevler (tasks) listelenmişse, hello
görevi Gradle tarafından kullanılabilir:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ ./gradlew app:tasks --all
> Task :app:tasks
------------------------------------------------------------
Tasks runnable from project ':app'
------------------------------------------------------------
Other tasks
-----------
compileJava - Compiles main Java source.
compileTestJava - Compiles test Java source.
hello
processResources - Processes main resources.
processTestResources - Processes test resources.
startScripts - Creates OS-specific scripts to run the project as a JVM application.
build script’deki görevi ./gradlew hello
komutu ile yürütebilirsiniz:
1
2
$ ./gradlew hello
Hello world!
Gradle hello
görevini yürüttüğünde, sağlanan eylemi (action) yürütür. Bu örnekte, eylem (action) basit bir kod içeren bir bloktur: println("Hello world!")
.
Az önce ele alınan hello
görevi, bir açıklamayla (description) detaylandırılabilir ve aşağıdaki güncellemeyle bir gruba (group) atanabilir:
1
2
3
4
5
6
7
8
9
//build.gradle.kts
tasks.register("hello") {
group = "Custom"
description = "A lovely greeting task."
doLast {
println("Hello world!")
}
}
Görev bir gruba atandığında “./gradlew tasks
” tarafından listelenecektir.
1
2
3
4
5
6
7
$ ./gradlew tasks
> Task :tasks
Custom tasks
------------------
hello - A lovely greeting task.
Bir görevle ilgili bilgileri görüntülemek için “help --task <görev-adı>
” komutunu kullanın:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$./gradlew help --task hello
> Task :help
Detailed task information for hello
Path
:app:hello
Type
Task (org.gradle.api.Task)
Options
--rerun Causes the task to be re-run even if up-to-date.
Description
A lovely greeting task.
Group
Custom
Gördüğümüz gibi hello
görevi custom
grubuna aittir.
base Plugin kullanan bir projenin görevleri
Bazı merkezi yaşam döngüsü görevleri (central lifecycle tasks) ekleyen bir Gradle çekirdek (core) eklentisi olan ‘base
’ plugini ekleyerek bunu keşfetmeye başlayalım.
1
2
3
plugins {
id("base")
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
% gradle :app:tasks
Starting a Gradle Daemon (subsequent builds will be faster)
> Task :app:tasks
------------------------------------------------------------
Tasks runnable from project ':app'
------------------------------------------------------------
Build tasks
-----------
assemble - Assembles the outputs of this project.
build - Assembles and tests this project.
clean - Deletes the build directory.
Help tasks
----------
buildEnvironment - Displays all buildscript dependencies declared in project ':app'.
dependencies - Displays all dependencies declared in project ':app'.
dependencyInsight - Displays the insight into a specific dependency in project ':app'.
help - Displays a help message.
javaToolchains - Displays the detected java toolchains.
kotlinDslAccessorsReport - Prints the Kotlin code for accessing the currently available project extensions and conventions.
outgoingVariants - Displays the outgoing variants of project ':app'.
projects - Displays the sub-projects of project ':app'.
properties - Displays the properties of project ':app'.
resolvableConfigurations - Displays the configurations that can be resolved in project ':app'.
tasks - Displays the tasks runnable from project ':app'.
Verification tasks
------------------
check - Runs all checks.
Rules
-----
Pattern: clean<TaskName>: Cleans the output files of a task.
Pattern: build<ConfigurationName>: Assembles the artifacts of a configuration.
To see all tasks and more detail, run gradle tasks --all
To see more detail about a task, run gradle help --task <task>
Benim Notum:
Görüleceği üzere Help tasks‘lara ek olarak Build tasks, Verification tasks ve Rules‘un çıktıya eklendiğini görüyoruz. Bu ek görevler gradle core plugin olan “base
” plugin aracılıyla gelmektedir.
“Base Plugin”, çoğu “build” için ortak olan bazı görevleri ve “kuralları (conventions)” sağlar ve build’e bunların çalıştırılma şekli konusunda tutarlılığı destekleyen bir yapı (structure) ekler. En önemli katkısı, diğer eklentiler ve “build” yazarları tarafından sağlanan daha spesifik görevler için bir “şemsiye (umbrella)” görevi gören bir dizi “yaşam döngüsü görevleri”dir (lifecycle tasks).
Base plugin’in bir başka kullanımı da bu şekildedir.
1
2
3
4
5
6
7
8
// kotlin
plugins {
base
}
// groovy
plugins {
id 'base'
}
Tasks (Görevler)
- clean — Delete “build” dizinini ve içindeki her şeyi, yani “layout.buildDirectory” proje özelliği tarafından belirtilen yolu (path) siler.
- check — lifecycle task
Pluginler ve “build” yazarları, testleri çalıştıranlar gibi doğrulama görevlerini “
check.dependsOn(task)
” kullanarak bu yaşam döngüsü görevine eklemelidir. - assemble — lifecycle task
Pluginler ve “derleme” yazarları, bu “yaşam döngüsü (lifecycle)” görevine dağıtımlar (distributions) ve diğer tüketilebilir artifaktleri üreten görevleri eklemelidir. Örneğin, “
jar
”, Java kitaplıkları için tüketilebilir artifakt üretir. “assemble.dependsOn(task)
” komutunu kullanarak görevleri bu yaşam döngüsü (lifecycle) görevine ekleyin. - build — lifecycle task (
check
veassemble
görevlerine bağlıdır.) Tüm testlerin yürütülmesi, üretim artifaktlerinin (production artifacts) üretilmesi ve belgelerin (documentation) oluşturulması da dahil olmak üzere her şeyin build edilmesi amaçlanmaktadır. “assemble
” ve “check
” tipik olarak daha uygun olduğundan, muhtemelen somut görevleri doğrudan build’e nadiren ekleyeceksiniz. - buildConfiguration — task rule
İsimlendirilmiş konfigürasyona (named configuration) eklenen artifaktleri birleştirir. Örneğin, “
buildRuntimeElements
”, “runtimeElements
” yapılandırmasına eklenen herhangi bir artifakti oluşturmak için gereken her görevi yürütecektir. - cleanTask — task rule
Bir görevin tanımlanmış çıktılarını (defined outputs) kaldırır; ör. “
cleanJar
”, “Java Plugin”in “jar
” görevi tarafından üretilen “JAR” dosyasını silecektir.
BAĞIMLILIK YÖNETİMİ (Dependency management)
“Base Plugin” bağımlılıklar (dependencies) için hiçbir yapılandırma eklemez ancak aşağıdaki yapılandırmaları ekler:
- default
“Bağımlılık çözümlemesi (dependency resolution)” istek öznitelikleri (request attributes) olmadan gerçekleştirildiğinde kullanılan bir “geri dönüş (fallback)” yapılandırmasıdır. Yeni build’ler ve plugin’ler, “
default
” yapılandırmayı kullanmamalıdır! Yalnızca geriye dönük uyumluluk (backwards compatibility) için varlığını sürdürür. Bağımlılık çözümlemesi (dependency resolution) istek öznitelikleriyle (request attributes) gerçekleştirilmelidir. - archives
“
archives
” yapılandırmasında tanımlanan tüm artifaktler, “assemble
” görevi tarafından otomatik olarak oluşturulur (build edilir). Yeni “build’ler” ve “pluginler”, “archives
” yapılandırmasını kullanmamalıdır! Yalnızca geriye dönük uyumluluk (backwards compatibility) için varlığını sürdürür. Bunun yerine, görev bağımlılıkları (task dependencies) doğrudan “assemble
” görevinde bildirilmelidir.
KATKIDA BULUNAN UZANTILAR (Contributed extensions)
“Base Plugin”, projeye “base
” uzantısını ekler. Bu, tahsis edilmiş (dedicated) bir DSL bloğu içinde aşağıdaki özelliklerin (properties) yapılandırılmasına olanak tanır.
build.gradle.kts
1
2
3
4
5
base {
archivesName = "gradle"
distsDirectory = layout.buildDirectory.dir("custom-dist")
libsDirectory = layout.buildDirectory.dir("custom-libs")
}
- archivesName — default: $project.name
“archive” görevleri için varsayılan “
AbstractArchiveTask.getArchiveBaseName()
” değerini sağlar. - distsDirectory — default: layout.buildDirectory.dir(“distributions”) Dağıtım arşivlerinin (distribution archives), yani JAR olmayanların oluşturulduğu dizinin varsayılan adıdır.
- libsDirectory — default: layout.buildDirectory.dir(“libs”) Kütüphane arşivlerinin (library archives), yani JAR’ların oluşturulduğu dizinin varsayılan adıdır.
Plugin ayrıca “AbstractArchiveTask“ı genişleten herhangi bir görevde (task) aşağıdaki özellikler (properties) için varsayılan değerler sağlar:
- destinationDirectory
JAR olmayan arşivler (non-JAR archives) için varsayılan olarak “
distsDirectory
”, JAR’lar ve WAR’lar gibi JAR türevleri için “libsDirectory
“dir. - archiveVersion
Projenin sürümü (version) yoksa varsayılan olarak “
$project.version
” veya ‘belirtilmemiş (unspecified)’ olur. - archiveBaseName
Varsayılan olarak
$archivesBaseName
‘dir.

Artık ‘:assemble
’ ve ‘:build
’ görevlerinin mevcut olduğunu görebiliyoruz. “:” ile ayrılmış, alt proje adı ve görev (task) adı ile adreslediğimiz ‘:build
’ görevini çalıştırdığımızda pek bir şeyin gerçekleşmediğini görüyoruz.


Benim Notum : --console
hangi tür konsol çıktısının oluşturulacağını belirtir. Değerler ‘plain
’, ‘auto
’ (varsayılan), ‘rich
’ veya ‘verbose
‘dur.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
% gradle :app:build --console=plain
> Task :my-build-logic:java-plugins:checkKotlinGradlePluginConfigurationErrors
> Task :my-build-logic:java-plugins:generateExternalPluginSpecBuilders UP-TO-DATE
> Task :my-build-logic:java-plugins:extractPrecompiledScriptPluginPlugins UP-TO-DATE
> Task :my-build-logic:java-plugins:compilePluginsBlocks UP-TO-DATE
> Task :my-build-logic:java-plugins:generatePrecompiledScriptPluginAccessors UP-TO-DATE
> Task :my-build-logic:java-plugins:generateScriptPluginAdapters UP-TO-DATE
> Task :my-build-logic:java-plugins:compileKotlin UP-TO-DATE
> Task :my-build-logic:java-plugins:compileJava NO-SOURCE
> Task :my-build-logic:java-plugins:pluginDescriptors UP-TO-DATE
> Task :my-build-logic:java-plugins:processResources UP-TO-DATE
> Task :my-build-logic:java-plugins:classes UP-TO-DATE
> Task :my-build-logic:java-plugins:jar UP-TO-DATE
> Task :app:assemble UP-TO-DATE
> Task :app:check UP-TO-DATE
> Task :app:build UP-TO-DATE
Yaşam Döngüsü ve Eyleme Dönüştürülebilir Görevler (Lifecycle and Actionable Tasks)
Gradle’ın iki tür görev (task) arasında ayrım yaptığını bilmek önemlidir: (1) yaşam döngüsü görevleri (lifecycle tasks) ve (2) eyleme dönüştürülebilir görevler (actionable tasks). ‘base
’ pluginin eklediği şeyler yalnızca yaşam döngüsü görevleridir (lifecycle tasks).
Yaşam döngüsü görevleri (lifecycle tasks) çağırabileceğiniz (callable) hedefleri tanımlar. Gradle’a projenizi ‘:build
’ etmesini söylemek gibi. Ancak ‘base
’ plugin, yalnızca bu yaşam döngüsü görevlerini (lifecycle tasks) onlara herhangi bir “actionable” görev bağlamadan ekler.
java-library plugin ve Actionable task’lar
Bu tür “actionable” görevler, Java kaynak kodunu derlemek (compile) veya sınıfları bir “Jar” içinde paketlemek gibi şeyler için görevler sağlayan ‘java-library
’ eklentisi gibi eklentiler tarafından eklenir.


Benim Notum:
“Java Plugin”, görevlerinden bazılarını, Java Eklentisinin otomatik olarak uyguladığı “Base Plugin” tarafından tanımlanan “yaşam döngüsü (lifecycle)” görevlerine ekler ve ayrıca birkaç “yaşam döngüsü (lifecycle)” görevi daha ekler. 3 Benim anladığım üzere burada, tıpkı Java Library Plugin’in Java Plugin’i genişletmesi gibi bir durum var. Yani Java Plugin, Gradle Base Plugin’i genişletiyor.
Artık daha fazla görevin kullanılabilir hale geldiğini ve burada gösterilmeyen “lifecycle” görevlerine daha fazla “actionable” görevin bağlandığını görebiliyoruz.

Şimdi ‘:build
’ görevini tekrar çağırırsak, ‘:app:compileJava
’ görevi de dahil olmak üzere birçok görevin yürütüldüğünü görebiliriz.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
% gradle :app:build --console=plain
Starting a Gradle Daemon (subsequent builds will be faster)
> Task :my-build-logic:java-plugins:checkKotlinGradlePluginConfigurationErrors
> Task :my-build-logic:java-plugins:generateExternalPluginSpecBuilders
> Task :my-build-logic:java-plugins:extractPrecompiledScriptPluginPlugins
> Task :my-build-logic:java-plugins:compilePluginsBlocks
> Task :my-build-logic:java-plugins:generatePrecompiledScriptPluginAccessors
> Task :my-build-logic:java-plugins:generateScriptPluginAdapters
> Task :my-build-logic:java-plugins:pluginDescriptors
> Task :my-build-logic:java-plugins:processResources
> Task :my-build-logic:java-plugins:compileKotlin
> Task :my-build-logic:java-plugins:compileJava NO-SOURCE
> Task :my-build-logic:java-plugins:classes
> Task :my-build-logic:java-plugins:jar
> Task :app:compileJava NO-SOURCE
> Task :app:processResources NO-SOURCE
> Task :app:classes UP-TO-DATE
> Task :app:jar
> Task :app:assemble
> Task :app:compileTestJava NO-SOURCE
> Task :app:processTestResources NO-SOURCE
> Task :app:testClasses UP-TO-DATE
> Task :app:test NO-SOURCE
> Task :app:check UP-TO-DATE
> Task :app:build
Benim Notum : build
, check
ve assemble
dışındaki görevlerin “java-library” plugin ile geldiğini görüyorsunuz. Özetle java-library plugin’in, base
plugini genişlettiğini söyleyebiliriz.
Görevler Artımsaldır (Incremental)
Gradle görevlerinin önemli bir yönü artımlılıklarıdır (incrementality). Gradle önceki build’lerden elde edilen sonuçları yeniden kullanabilir (reuse). Dolayısıyla, projemizi zaten build ettiysek ve yalnızca küçük bir şeyi değiştirseydik,, ‘:build
’ komutunu tekrar çalıştırmak çok fazla işe neden olmayacaktır.
Benim Notum:
Önceki “build run” sonuçlarını yeniden kullanın
Örneğin, projemizde yalnızca test kodunu değiştirip, üretim (production) koduna dokunmazsak, build’ı çalıştırmak yalnızca test kodunu yeniden derleyecektir, ancak Gradle tarafından “UP-TO-DATE” (yani güncel) olarak işaretlenen production kodunu değiştirmeyecektir.
Şimdi sırasıyla production kodunda sonrasında da test kodunda bir sınıf oluşturup çıktıları aşama aşama inceleyelim.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
% gradle :app:build --console=plain
> Task :my-build-logic:java-plugins:checkKotlinGradlePluginConfigurationErrors
> Task :my-build-logic:java-plugins:generateExternalPluginSpecBuilders UP-TO-DATE
> Task :my-build-logic:java-plugins:extractPrecompiledScriptPluginPlugins UP-TO-DATE
> Task :my-build-logic:java-plugins:compilePluginsBlocks UP-TO-DATE
> Task :my-build-logic:java-plugins:generatePrecompiledScriptPluginAccessors UP-TO-DATE
> Task :my-build-logic:java-plugins:generateScriptPluginAdapters UP-TO-DATE
> Task :my-build-logic:java-plugins:compileKotlin UP-TO-DATE
> Task :my-build-logic:java-plugins:compileJava NO-SOURCE
> Task :my-build-logic:java-plugins:pluginDescriptors UP-TO-DATE
> Task :my-build-logic:java-plugins:processResources UP-TO-DATE
> Task :my-build-logic:java-plugins:classes UP-TO-DATE
> Task :my-build-logic:java-plugins:jar UP-TO-DATE
- > Task :app:compileJava
> Task :app:processResources NO-SOURCE
> Task :app:classes
> Task :app:jar
> Task :app:assemble
- > Task :app:compileTestJava NO-SOURCE
> Task :app:processTestResources NO-SOURCE
> Task :app:testClasses UP-TO-DATE
> Task :app:test NO-SOURCE
> Task :app:check UP-TO-DATE
> Task :app:build

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
% gradle :app:build --console=plain
> Task :my-build-logic:java-plugins:checkKotlinGradlePluginConfigurationErrors
> Task :my-build-logic:java-plugins:generateExternalPluginSpecBuilders UP-TO-DATE
> Task :my-build-logic:java-plugins:extractPrecompiledScriptPluginPlugins UP-TO-DATE
> Task :my-build-logic:java-plugins:compilePluginsBlocks UP-TO-DATE
> Task :my-build-logic:java-plugins:generatePrecompiledScriptPluginAccessors UP-TO-DATE
> Task :my-build-logic:java-plugins:generateScriptPluginAdapters UP-TO-DATE
> Task :my-build-logic:java-plugins:compileKotlin UP-TO-DATE
> Task :my-build-logic:java-plugins:compileJava NO-SOURCE
> Task :my-build-logic:java-plugins:pluginDescriptors UP-TO-DATE
> Task :my-build-logic:java-plugins:processResources UP-TO-DATE
> Task :my-build-logic:java-plugins:classes UP-TO-DATE
> Task :my-build-logic:java-plugins:jar UP-TO-DATE
- > Task :app:compileJava UP-TO-DATE
> Task :app:processResources NO-SOURCE
> Task :app:classes UP-TO-DATE
> Task :app:jar UP-TO-DATE
> Task :app:assemble UP-TO-DATE
- > Task :app:compileTestJava UP-TO-DATE
> Task :app:processTestResources NO-SOURCE
> Task :app:testClasses UP-TO-DATE
> Task :app:test UP-TO-DATE
> Task :app:check UP-TO-DATE
> Task :app:build UP-TO-DATE
Şekilde görüldüğü gibi sadece src/test/java/Test.java sınıfında bir değişiklik yapıyoruz.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
% gradle :app:build --console=plain
> Task :my-build-logic:java-plugins:checkKotlinGradlePluginConfigurationErrors
> Task :my-build-logic:java-plugins:generateExternalPluginSpecBuilders UP-TO-DATE
> Task :my-build-logic:java-plugins:extractPrecompiledScriptPluginPlugins UP-TO-DATE
> Task :my-build-logic:java-plugins:compilePluginsBlocks UP-TO-DATE
> Task :my-build-logic:java-plugins:generatePrecompiledScriptPluginAccessors UP-TO-DATE
> Task :my-build-logic:java-plugins:generateScriptPluginAdapters UP-TO-DATE
> Task :my-build-logic:java-plugins:compileKotlin UP-TO-DATE
> Task :my-build-logic:java-plugins:compileJava NO-SOURCE
> Task :my-build-logic:java-plugins:pluginDescriptors UP-TO-DATE
> Task :my-build-logic:java-plugins:processResources UP-TO-DATE
> Task :my-build-logic:java-plugins:classes UP-TO-DATE
> Task :my-build-logic:java-plugins:jar UP-TO-DATE
- > Task :app:compileJava UP-TO-DATE
> Task :app:processResources NO-SOURCE
> Task :app:classes UP-TO-DATE
> Task :app:jar UP-TO-DATE
> Task :app:assemble UP-TO-DATE
- > Task :app:compileTestJava
> Task :app:processTestResources NO-SOURCE
> Task :app:testClasses
> Task :app:test
> Task :app:check
> Task :app:build
Değişiklik yapmadığım src/main/java/Test.java sınıfını derlemek için kullanılan task, compileJava
UP-TO-DATE olarak etiketli kalırken, src/test/java/Test.java sınıfını derlemek için kullanılan compileTestJava
görevi etiketsiz kalmaktadır. Bu, ilgili görevin yeniden çalıştırıldığının bir işaretidir.
Build Cache Sonuçları Yeniden Kullanma
Gradle ayrıca geçmişteki sonuçları da yeniden kullanabilir. Bunun için “Build Cache”‘i etkinleştirmeniz gerekir. Bunu “--build-cache
” komut satırı parametresi aracılığıyla veya “gradle.properties
” dosyasında bir özellik (property) ayarlayarak yapabilirsiniz. Bu, build’lerinizi büyük ölçüde hızlandırabilir.


Örneğin, branch’ler arasında düzenli olarak geçiş yapıyorsanız, “build cache” uzak bir sunucuda (remote server) da bulunabilir ve birden fazla makine arasında da paylaşılabilir. Bu kurulumla CI sunucusu “build cache”‘i doldurabilir ve birden fazla geliştirici sonuçları yeniden kullanabilir.
Görevler arasında bağımlılıklar (dependencies) vardır
Gradle’ın tüm görevler (tasks) arasındaki bağımlılıkları (dependencies) bildiğini anlamak önemlidir. Bu sayede hangi görevi hedef alırsanız alın, diğer hangi görevlerin yürütülmesi gerektiğini bilirsiniz.
“app” alt projemize bir bağımlılık ekleyelim.

“app” projesi artık diğer iki alt projemize bağlıdır: doğrudan “business-logic” projesine ve dolaylı olarak “data-model” projesine bağımlıdır. Şimdi ‘:build’i tekrar çalıştırırsak bu projelerin Java kodlarının nasıl derlendiğini de görmüş oluruz.

Benim Notum:
Diğer görevlere bağlı olan görevleri bildirebilirsiniz:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
//build.gradle.kts
tasks.register("hello") {
doLast {
println("Hello world!")
}
}
tasks.register("intro") {
dependsOn("hello")
doLast {
println("I'm Gradle")
}
}
1
2
3
$ gradle -q intro
Hello world!
I'm Gradle
taskX
‘in taskY
‘ye bağımlılığı, taskY
tanımlanmadan önce bildirilebilir:
1
2
3
4
5
6
7
8
9
10
11
12
13
//build.gradle.kts
tasks.register("taskX") {
dependsOn("taskY")
doLast {
println("taskX")
}
}
tasks.register("taskY") {
doLast {
println("taskY")
}
}
1
2
3
$ gradle -q taskX
taskY
taskX
Önceki örnekteki hello
görevi bir bağımlılık içerecek şekilde güncellendi:
1
2
3
4
5
6
7
8
9
10
//build.gradle.kts
tasks.register("hello") {
group = "Custom"
description = "A lovely greeting task."
doLast {
println("Hello world!")
}
dependsOn(tasks.assemble)
}
hello
görevi artık assemble
görevine bağlıdır; bu, Gradle’ın hello
görevini yürütmeden önce assemble
görevini yürütmesi gerektiği anlamına gelir:
1
2
3
4
5
6
7
8
9
10
11
12
13
$ ./gradlew :app:hello
> Task :app:compileJava UP-TO-DATE
> Task :app:processResources NO-SOURCE
> Task :app:classes UP-TO-DATE
> Task :app:jar UP-TO-DATE
> Task :app:startScripts UP-TO-DATE
> Task :app:distTar UP-TO-DATE
> Task :app:distZip UP-TO-DATE
> Task :app:assemble UP-TO-DATE
> Task :app:hello
Hello world!
Referanslar:
- Example on GitHub
- Example on GitHub - alternative implementation options:
- 01 – The Settings File
- 02 The Build Files
- 08 Declaring Dependencies:
- onepiece.Software
- Modern Gradle Fundamentals
- Jendrik’s mastodon account
- Jendrik’s github
- Jendrik Johannes’s youtube channel
- Logo
- Writing Build Scripts
- Update to work the new way
Daha Fazla Okuma:
- Applying plugins (Plugins DSL):
- Plugin Basics
- Local/Custom plugins (Convention Plugins)
- The Gradle Plugin Portal
- Defining Convention Plugins
- Structuring Projects with Gradle
- Sharing convention plugins with build logic build Sample
- The ‘java’ Extension
- Declaring Dependencies (other Subprojects)
- Declaring Dependencies (Components)
- 07 Implementing Tasks and Extensions
- Groovy dsl version
- Example on GitHub
- Using Plugins
- Explore the build script
- Ignore scripts in source roots by default. This script is not supposed to be inside source root. Since Kotlin 1.9 it is ignored during the module compilation.
Syncing and reloading The Gradle Tool Window Use “Load Gradle Changes” The Right Way in IntelliJ IDEA