This is a hands-on exercise to go along with the Incremental Builds and Build Caching training module. In this exercise you will go over the following:
- Recap of Incremental Builds
- Enable and use Local Cache
- Order of lookup for cached outputs
- Finished going through the relevant sections in the training course
- JDK 1.8+ and recent version of Gradle build tool installed
- Gradle Build Tool experience
- Knowledge of core concepts
- Authoring build files
- Kotlin experience a plus but not required
- Basic experience with Java software development
- Open the Gradle project in this repository in an editor of your choice
- Inspect the build and source files, there is only one subproject called
app
- Run tests on the project. Notice the task outcome labels indicate that most tasks' actions were executed.
$ ./gradlew :app:test
- Task :app:compileJava
# Task :app:processResources NO-SOURCE
- Task :app:classes
- Task :app:compileTestJava
# Task :app:processTestResources NO-SOURCE
- Task :app:testClasses
- Task :app:test
- Run the tests again. Notice that the outcome labels indicate that most
tasks' actions were not executed. The output from the previous execution
in the
build
directory was used.
$ ./gradlew :app:test
> Task :app:compileJava UP-TO-DATE
# Task :app:processResources NO-SOURCE
> Task :app:classes 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
- Make a change to the
app/src/main/java/com/gradle/lab/App.java
file, add 2 more exclamation marks to theHello World!
string:
public String getGreeting() {
return "Hello World!!!";
}
- Run the tests again. Notice that the actions of
compileJava
andtest
were executed since changes were made to the inputs for those tasks.
$ ./gradlew :app:test
- Task :app:compileJava
# Task :app:processResources NO-SOURCE
- Task :app:classes
> Task :app:compileTestJava UP-TO-DATE
# Task :app:processTestResources NO-SOURCE
> Task :app:testClasses UP-TO-DATE
- Task :app:test
- Revert the changes made to
app/src/main/java/com/gradle/lab/App.java
and run the tests again. Notice that the actions ofcompileJava
andtest
were executed since the most recent build had different inputs for those tasks.
$ ./gradlew :app:test
- Task :app:compileJava
# Task :app:processResources NO-SOURCE
- Task :app:classes
> Task :app:compileTestJava UP-TO-DATE
# Task :app:processTestResources NO-SOURCE
> Task :app:testClasses UP-TO-DATE
- Task :app:test
- Edit the
gradle.properties
file and addorg.gradle.caching=true
to it. The contents of the file now look like:
org.gradle.console=verbose
org.gradle.caching=true
- Run the clean task and then the tests, this will populate the cache.
$ ./gradlew :app:clean :app:test
# Task :app:clean
- Task :app:compileJava
# Task :app:processResources NO-SOURCE
- Task :app:classes
- Task :app:compileTestJava
# Task :app:processTestResources NO-SOURCE
- Task :app:testClasses
- Task :app:test
- Change the string in
app/src/main/java/com/gradle/lab/App.java
to have 2 extra exclamations again. Run the tests, notice that the task actions were executed. The inputs and outputs for these changes are not in the cache.
$ ./gradlew :app:test
- Task :app:compileJava
# Task :app:processResources NO-SOURCE
- Task :app:classes
> Task :app:compileTestJava UP-TO-DATE
# Task :app:processTestResources NO-SOURCE
> Task :app:testClasses UP-TO-DATE
- Task :app:test
- Revert the changes to
app/src/main/java/com/gradle/lab/App.java
and run the tests again. Notice that some task actions were skipped and the outputs from the cache were used. It is important to understand that the outputs from the cache are put into the build directory and that's how the outputs are available to the tasks.
$ ./gradlew :app:test
! Task :app:compileJava FROM-CACHE
# Task :app:processResources NO-SOURCE
> Task :app:classes UP-TO-DATE
> Task :app:compileTestJava UP-TO-DATE
# Task :app:processTestResources NO-SOURCE
> Task :app:testClasses UP-TO-DATE
! Task :app:test FROM-CACHE
- If you run the tests again, you will notice that the outcome label indicates
the output from the previous execution in the
build
directory was used. This shows the order in which Gradle will look for the cached outputs, first in the build directory, then in the cache.
$ ./gradlew :app:test
> Task :app:compileJava UP-TO-DATE
# Task :app:processResources NO-SOURCE
> Task :app:classes 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
- If you use the -i flag you can see the cache key used for each task input. Run a clean followed by the tests to see this.
$ ./gradlew :app:clean :app:test -i
...
...
...
> Task :app:test FROM-CACHE
Build cache key for task ':app:test' is 5eea5b00209094c7c5d641d592af0a2b
Task ':app:test' is not up-to-date because:
Output property 'binaryResultsDirectory' file /Users/adayal/trainings/dpeuni-gradle-incremental-and-caching-local/app/build/test-results/test/binary has been removed.
Output property 'binaryResultsDirectory' file /Users/adayal/trainings/dpeuni-gradle-incremental-and-caching-local/app/build/test-results/test/binary/output.bin has been removed.
Output property 'binaryResultsDirectory' file /Users/adayal/trainings/dpeuni-gradle-incremental-and-caching-local/app/build/test-results/test/binary/output.bin.idx has been removed.
Output property 'binaryResultsDirectory' file /Users/adayal/trainings/dpeuni-gradle-incremental-and-caching-local/app/build/test-results/test/binary/results.bin has been removed.
Output property 'reports.enabledReports.html.outputLocation' file /Users/adayal/trainings/dpeuni-gradle-incremental-and-caching-local/app/build/reports/tests/test has been removed.
Loaded cache entry for task ':app:test' with cache key 5eea5b00209094c7c5d641d592af0a2b
- You can also use the -Dorg.gradle.caching.debug=true flag to view more details.
$ ./gradlew :app:clean :app:test -Dorg.gradle.caching.debug=true
- You can see the cache entries by looking in the cache directory:
$ ls -ltr ~/.gradle/caches/build-cache-1/
- By default items will expire from the local cache after 7 days. Let's
modify the configuration to keep items for 30 days. Edit the
~/.gradle/init.gradle.kts
file and put the following configuration:
gradle.settingsEvaluated {
buildCache {
local {
removeUnusedEntriesAfterDays = 30
}
}
}
- Run a clean then the tests to make sure there was no mistake in the configuration:
$ ./gradlew :app:clean :app:test
# Task :app:clean
! Task :app:compileJava FROM-CACHE
# Task :app:processResources NO-SOURCE
> Task :app:classes UP-TO-DATE
! Task :app:compileTestJava FROM-CACHE
# Task :app:processTestResources NO-SOURCE
> Task :app:testClasses UP-TO-DATE
! Task :app:test FROM-CACHE
If you get stuck you can refer to the solution
branch of this repository.