// Copyright (C) 2024 Gradle, Inc.
//
// Licensed under the Creative Commons Attribution-Noncommercial-ShareAlike 4.0 International License.;
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://creativecommons.org/licenses/by-nc-sa/4.0/
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

[[part5_gradle_inc_builds]]
= Part 5: Exploring Incremental Builds

++++
<div class="badge-wrapper">
    <a class="badge" href="https://dpeuniversity.gradle.com/app/courses/ec69d0b8-9171-4969-ac3e-82dea16f87b0/" target="_blank">
        <span class="badge-type button--blue">LEARN</span>
        <span class="badge-text">Incremental Builds and Build Caching with Gradle&nbsp;&nbsp;&nbsp;&gt;</span>
    </a>
</div>
++++

Learn the basics of Gradle's incremental builds.

****
**In this section you will:**

- Use Gradle properties
- Understand incremental builds
- Explore task outcome labels
****

[[part5_begin]]
== Step 0. Before you Begin

1. You initialized your Java app in <<part1_gradle_init.adoc#part1_begin,part 1>>.
2. You ran several tasks in <<part2_gradle_tasks#part2_begin,part 2>>.
3. You learned about dependency management in <<part3_gradle_dep_man#part3_begin,part 3>>.
4. You applied a plugin to your app in <<part4_gradle_plugins#part4_begin,part 4>>.

== Step 1. Understanding Incremental Builds

It's important to know that Gradle optimizes your build in a variety of ways.
One such optimization is called _incremental builds_.

An _incremental build_ is a build that avoids running tasks whose inputs did not change since the previous build, making the execution of such tasks unnecessary.

For incremental builds to work, tasks must define their inputs and outputs. At build time, Gradle will determine whether the input or outputs have changed. If they have changed, Gradle will execute the task. Otherwise, it will skip execution.

== Step 2. Updating Gradle Properties

To better see incremental builds in action, we are going to switch the console output to verbose.

In the top-level folder of your app (`tutorial`), create a `gradle.properties` file:

[source,bash]
----
$ touch gradle.properties
----

Add `org.gradle.console=verbose` so the contents of the file look like this:

.gradle.properties
[source,properties]
----
org.gradle.console=verbose
----

== Step 3. Analyzing Incremental Builds

Run the clean task and then the build task using the `./gradlew :app:clean :app:build` command:

[source,text]
----
$ ./gradlew :app:clean :app:build

> Task :app:clean
> Task :app:compileJava
> Task :app:processResources NO-SOURCE
> Task :app:classes
> Task :app:jar
> Task :app:startScripts
> Task :app:distTar
> Task :app:distZip
> Task :app:assemble
> Task :app:compileTestJava
> Task :app:processTestResources NO-SOURCE
> Task :app:testClasses
> Task :app:test
> Task :app:check
> Task :app:build

BUILD SUCCESSFUL in 1s
8 actionable tasks: 8 executed
----

No surprise here, Gradle invoked all the tasks needed to build the app.
This was done successfully.

Run the build again to view the _incremental build_ optimization in action:

[source,text]
----
$ ./gradlew :app:build

> 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: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

BUILD SUCCESSFUL in 409ms
7 actionable tasks: 7 up-to-date
----

Most tasks now have the `UP-TO-DATE` label.
This is how Gradle lets us know that inputs and outputs have not changed and therefore some tasks did not re-run.

== Step 4. Understanding Outcome Labels

There are four labels that developers can use to view task outcomes when verbose mode is turned on:

|===
|Outcome Label |Description

|UP-TO-DATE
|Task that has been already executed and hasn't changed (incremental build feature)

|SKIPPED
|Task was explicitly prevented from running

|FROM-CACHE
|Task output has been copied to local directory from previous builds in the build cache (caching feature)

|NO-SOURCE
|Task was not executed because its required inputs were not available
|===

If there is no label, the task was newly executed by Gradle (locally).

We will look at the `FROM-CACHE` label in the next section.

[.text-right]
**Next Step:** <<part6_gradle_caching#part6_begin,Enabling the Build Cache>> >>
