// 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.

[[part2_build_lifecycle]]
= Part 2: The Build Lifecycle

Learn about the Gradle build lifecycle and what each phase represents.

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

- Understand the Build Lifecycle
- Register and configure two tasks
- Run the task to view the phases in action
****

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

1. You initialized your Java app in <<part1_gradle_init_project.adoc#part1_begin,part 1>>.

== Step 1. Understanding the Build Lifecycle

A Gradle build has three distinct phases:

Phase 1 - Initialization  :: During the initialization phase, Gradle determines which projects will take part in the build, and creates a `Project` instance for each project.

Phase 2 - Configuration  :: During the configuration phase, the `Project` objects are configured using the build scripts of all projects in the build. Gradle determines the set of tasks to be executed.

Phase 3 - Execution  :: During the execution phase, Gradle executes each of the selected tasks.

When Gradle is invoked to execute a task, the lifecycle begins.
Let's see it in action.

image::gradle-build-lifecycle.png[]

== Step 2. Update the Settings File

Add the following line to the top of the Settings file:

[.multi-language-sample]
=====
.settings.gradle.kts
[source, kotlin]
----
println("SETTINGS FILE: This is executed during the initialization phase")
----
=====
[.multi-language-sample]
=====
.settings.gradle
[source, groovy]
----
println('SETTINGS FILE: This is executed during the initialization phase')
----
=====

== Step 3. Update the Build Script

Add the following lines to the bottom of the Build script:

[.multi-language-sample]
=====
.app/build.gradle.kts
[source, kotlin]
----
println("BUILD SCRIPT: This is executed during the configuration phase")

tasks.register("task1"){
    println("REGISTER TASK1: This is executed during the configuration phase")
}

tasks.register("task2"){
    println("REGISTER TASK2: This is executed during the configuration phase")
}

tasks.named("task1"){
    println("NAMED TASK1: This is executed during the configuration phase")
    doFirst {
        println("NAMED TASK1 - doFirst: This is executed during the execution phase")
    }
    doLast {
        println("NAMED TASK1 - doLast: This is executed during the execution phase")
    }
}

tasks.named("task2"){
    println("NAMED TASK2: This is executed during the configuration phase")
    doFirst {
        println("NAMED TASK2 - doFirst: This is executed during the execution phase")
    }
    doLast {
        println("NAMED TASK2 - doLast: This is executed during the execution phase")
    }
}
----
=====
[.multi-language-sample]
=====
[source, groovy]
----
println("BUILD SCRIPT: This is executed during the configuration phase")

tasks.register("task1") {
    println("REGISTER TASK1: This is executed during the configuration phase")
}

tasks.register("task2") {
    println("REGISTER TASK2: This is executed during the configuration phase")
}

tasks.named("task1") {
    println("NAMED TASK1: This is executed during the configuration phase")
    doFirst {
        println("NAMED TASK1 - doFirst: This is executed during the execution phase")
    }
    doLast {
        println("NAMED TASK1 - doLast: This is executed during the execution phase")
    }
}

tasks.named("task2") {
    println("NAMED TASK2: This is executed during the configuration phase")
    doFirst {
        println("NAMED TASK2 - doFirst: This is executed during the execution phase")
    }
    doLast {
        println("NAMED TASK2 - doLast: This is executed during the execution phase")
    }
}
----
=====

== Step 4. Run a Gradle Task

Run the `task1` task that you registered and configured in Step 3:

[source,text]
----
$ ./gradlew task1

SETTINGS FILE: This is executed during the initialization phase     //<1>

> Configure project :app
BUILD SCRIPT: This is executed during the configuration phase       //<2>
REGISTER TASK1: This is executed during the configuration phase     //<2>
NAMED TASK1: This is executed during the configuration phase        //<2>

> Task :app:task1
NAMED TASK1 - doFirst: This is executed during the execution phase  //<3>
NAMED TASK1 - doLast: This is executed during the execution phase   //<3>

BUILD SUCCESSFUL in 25s
5 actionable tasks: 3 executed, 2 up-to-date
----
<1> *Initialization*: Gradle executes `settings.gradle(.kts)` to determine the projects to be built and creates a `Project` object for each one.
<2> *Configuration*: Gradle configures each project by executing the `build.gradle(.kts)` files. It resolves dependencies and creates a dependency graph of all the available tasks.
<3> *Execution*: Gradle executes the tasks passed on the command line and any prerequisite tasks.

It is important to note that while `task1` was configured and executed, `task2` was not.
This is called _task configuration avoidance_ and prevents unnecessary work.

Task configuration avoidance is when Gradle avoids configuring `task2` when `task1` was called and `task1` does NOT depend. on `task2`.

[.text-right]
**Next Step:** <<part3_multi_project_builds#part3_multi_project_builds,Multi-Project Builds>> >>
