From b6cfefed2026cc58e2cf4b021aa8087812501922 Mon Sep 17 00:00:00 2001 From: nate contino Date: Wed, 19 Oct 2022 15:31:48 -0400 Subject: [PATCH 01/24] Rewrite Build Lifecycle documentation in a consistent docs voice (cherry picked from commit c08c821b0305912be7e2fd611b17a92ed220b3ee) Signed-off-by: Julia Boes --- .../authoring-builds/build_lifecycle.adoc | 171 +++++++++++------- .../organizing_gradle_projects.adoc | 6 +- 2 files changed, 108 insertions(+), 69 deletions(-) diff --git a/subprojects/docs/src/docs/userguide/authoring-builds/build_lifecycle.adoc b/subprojects/docs/src/docs/userguide/authoring-builds/build_lifecycle.adoc index e6d3c723e5f8..54a114bb4fac 100644 --- a/subprojects/docs/src/docs/userguide/authoring-builds/build_lifecycle.adoc +++ b/subprojects/docs/src/docs/userguide/authoring-builds/build_lifecycle.adoc @@ -15,37 +15,53 @@ [[build_lifecycle]] = Build Lifecycle -We said earlier that the core of Gradle is a language for dependency based programming. In Gradle terms this means that you can define tasks and dependencies between tasks. Gradle guarantees that these tasks are executed in the order of their dependencies, and that each task is executed only once. These tasks form a http://en.wikipedia.org/wiki/Directed_acyclic_graph[Directed Acyclic Graph]. There are build tools that build up such a dependency graph as they execute their tasks. Gradle builds the complete dependency graph _before_ any task is executed. This lies at the heart of Gradle and makes many things possible which would not be possible otherwise. +Gradle is an example of *dependency based programming*: you define tasks and dependencies between tasks. +Gradle guarantees that these tasks execute in the order of their dependencies. +Your build scripts configure this dependency graph. +This page discusses the phases of the lifecycle Gradle passes through as it interprets those scripts. +Additionally, this page explains how you can react to events of the lifecycle using notifications. -Your build scripts configure this dependency graph. Therefore they are strictly speaking _build configuration scripts_. +== Task Graphs + +Some build tools assemble a task graph lazily, as they execute tasks. +Gradle builds the complete task graph eagerly, before executing any task. + +Within each project, tasks form a http://en.wikipedia.org/wiki/Directed_acyclic_graph[Directed Acyclic Graph] (DAG). + +This diagram shows two example task graphs: one abstract and the other concrete. +The diagram represents dependencies between tasks as arrows: + +.Two examples of Gradle task graphs +image::task-dag-examples.png[Example task graphs] + +Both plugins and your own build scripts contribute to the task graph via the <>. [[sec:build_phases]] -== Build phases +== Build Phases A Gradle build has three distinct phases. +Gradle runs these phases in order: first initialization, then configuration, and finally execution. Initialization:: -Gradle supports single and multi-project builds. During the initialization phase, Gradle determines which projects are going to take part in the build, and creates a link:{groovyDslPath}/org.gradle.api.Project.html[Project] instance for each of these projects. +- Detects the settings file. +- Evaluates the <> to determine which projects participate in the build. +- Creates a link:{groovyDslPath}/org.gradle.api.Project.html[`Project`] instance for every project. Configuration:: -During this phase the project objects are configured. The build scripts of _all_ projects which are part of the build are executed. +- Evaluates the build scripts of every project participating in the build. +- Creates a task graph for all projects. Execution:: -Gradle determines the subset of the tasks, created and configured during the configuration phase, to be executed. The subset is determined by the task name arguments passed to the `gradle` command and the current directory. Gradle then executes each of the selected tasks. - - -[[sec:settings_file]] -== Settings file +- Calculates tasks to run based on the passed task name arguments. +- Executes each of the selected tasks in the order of their dependencies. -Beside the build script files, Gradle defines a settings file. The settings file is determined by Gradle via a naming convention. The default name for this file is `settings.gradle`. Later in this chapter we explain how Gradle looks for a settings file. +=== Example -The settings file is executed during the initialization phase. A multi-project build must have a `settings.gradle` file in the root project of the multi-project hierarchy. It is required because the settings file defines which projects are taking part in the multi-project build (see <>). For a single-project build, a settings file is optional. Besides defining the included projects, you might need it to add libraries to your build script classpath (see <>). Let's first do some introspection with a single project build: +The following example shows which parts of settings and build files correspond to various build phases: -.Single project build ==== include::sample[dir="snippets/buildlifecycle/basic/groovy",files="settings.gradle[];build.gradle[]"] include::sample[dir="snippets/buildlifecycle/basic/kotlin",files="settings.gradle.kts[];build.gradle.kts[]"] ==== -=== Output of **`gradle test testBoth`** [source.multi-language-sample,groovy] ---- > gradle test testBoth @@ -57,76 +73,81 @@ include::{snippetsPath}/buildlifecycle/basic/tests/buildlifecycle.out[] include::{snippetsPath}/buildlifecycle/basic/tests/buildlifecycle.out[] ---- -For a build script, the property access and method calls are delegated to a project object. Similarly property access and method calls within the settings file is delegated to a settings object. Look at the link:{groovyDslPath}/org.gradle.api.initialization.Settings.html[Settings] class in the API documentation for more information. - - [[sec:initialization]] == Initialization -How does Gradle know whether to do a single or multi-project build? -If you trigger a multi-project build from a directory with a `settings.gradle` file, Gradle uses it to configure the build. -Gradle also allows you to execute the build from within any subproject taking part in the build.footnote:[Gradle supports partial multi-project builds (see <>).] -If you execute Gradle from within a project with no `settings.gradle` file, Gradle looks for a `settings.gradle` file in the following way: +In the initialization phase, Gradle detects the set of projects participating in the build. +Then, Gradle evaluates the settings file. Finally, Gradle instantiates `Project` instances for each project. -* It looks for `settings.gradle` in parent directories. -* If not found, the build is executed as a single project build. -* If a `settings.gradle` file is found, Gradle checks if the current project is part of the multi-project hierarchy defined in the found `settings.gradle` file. -If not, the build is executed as a single project build. Otherwise a multi-project build is executed. +=== Detect Settings File -What is the purpose of this behavior? Gradle needs to determine whether the project you are in is a subproject of a multi-project build or not. -Of course, if it is a subproject, only the subproject and its dependent projects are built, but Gradle needs to create the build configuration for the whole multi-project build (see <>). -If the current project contains a `settings.gradle` file, the build is always executed as: +When you run Gradle in a directory that contains a `settings.gradle` file, Gradle uses that `settings.gradle` file to initialize the build. +You can run Gradle within any subproject of the build.footnote:[Gradle supports partial multi-project builds (see <>).] +When you run Gradle in a directory that contains *no* `settings.gradle` file: -* a single project build, if the `settings.gradle` file does not define a multi-project hierarchy -* a multi-project build, if the `settings.gradle` file does define a multi-project hierarchy. +. Gradle looks for a `settings.gradle` file in parent directories. +. If Gradle finds a `settings.gradle` file, Gradle checks if the current project is part of the multi-project build. If so, Gradle builds as a multi-project. +. If Gradle does not find a `settings.gradle` file, Gradle builds as a single project. -The automatic search for a `settings.gradle` file only works for multi-project builds with a default project layout where project paths match the physical subproject layout on disk. -Gradle supports arbitrary physical layouts for a multi-project build, but for such arbitrary layouts you need to execute the build from the directory where the settings file is located. -For information on how to run partial builds from the root, see <>. +In the standard Gradle project layout, project paths match the physical subproject layout on disk. +The automatic search for a `settings.gradle` file only works for multi-project builds with a standard project layout. +To build projects that use a nonstandard layout, execute the build from the directory that contains `settings.gradle`. -Gradle creates a Project object for every project taking part in the build. For a multi-project build these are the projects specified in the Settings object (plus the root project). Each project object has by default a name equal to the name of its top level directory, and every project except the root project has a parent project. Any project may have child projects. +=== Evaluate Settings File -[[sec:configuration_and_execution_of_a_single_project_build]] -== Configuration and execution of a single project build +During settings file evaluation, Gradle: -For a single project build, the workflow of the _after initialization_ phases are pretty simple. The build script is executed against the project object that was created during the initialization phase. Then Gradle looks for tasks with names equal to those passed as command line arguments. If these task names exist, they are executed as a separate build in the order you have passed them. The configuration and execution for multi-project builds is discussed in <>. +- Adds libraries to your build script classpath. +- Defines which projects participate in a multi-project build. -[[build_lifecycle_events]] -== Responding to the lifecycle in the build script +Gradle creates a `Project` for every project in the build. +By default, each `Project` has a name equal to the name of its top level directory. +Every project except the root project has a parent project. +Any project may have child projects. -Your build script can receive notifications as the build progresses through its lifecycle. These notifications generally take two forms: You can either implement a particular listener interface, or you can provide a closure to execute when the notification is fired. The examples below use closures. For details on how to use the listener interfaces, refer to the API documentation. +== Configuration +In the configuration phase, Gradle adds tasks and other properties to the projects generated by the initialization phase. +By the end of the configuration phase, Gradle has a complete task execution graph for each project. [[sec:project_evaluation]] -=== Project evaluation +=== Project Evaluation + +During project evaluation, Gradle evaluates build scripts to build a task hierarchy within a `Project`. +This hierarchy includes inputs, actions, and outputs for all tasks. -You can receive a notification immediately before and after a project is evaluated. This can be used to do things like performing additional configuration once all the definitions in a build script have been applied, or for some custom logging or profiling. +==== React to Project Evaluation -Below is an example which adds a `test` task to each project which has a `hasTests` property value of true. +You can receive a notification immediately before and immediately after a project evaluates. +These notifications work even when project evaluation fails. +You can configure project evaluation notifications for all projects or a specific project. +For example, you could use these notifications for: + +- additional configuration after applying all definitions in a build script +- custom logging +- custom profiling + +The following example adds a `test` task to each project where the `hasTests` property value is `true`: -.Adding of test task to each project which has certain property set ==== include::sample[dir="snippets/buildlifecycle/projectEvaluateEvents/groovy",files="build.gradle[tags=after-evaluate];project-a.gradle[]"] include::sample[dir="snippets/buildlifecycle/projectEvaluateEvents/kotlin",files="build.gradle.kts[tags=after-evaluate];project-a.gradle.kts[]"] ==== -.Output of `gradle -q test` ---- > gradle -q test include::{snippetsPath}/buildlifecycle/projectEvaluateEvents/tests/projectEvaluateEvents.out[] ---- -This example uses method `Project.afterEvaluate()` to add a closure which is executed after the project is evaluated (ie. the end of the configuration phase). - -It is also possible to receive notifications when any project is evaluated. This example performs some custom logging of project evaluation. Notice that the `afterProject` notification is received regardless of whether the project evaluates successfully or fails with an exception. +The following example uses `Project.afterEvaluate()` to run logic when a project finishes evaluation: -.Notifications ==== include::sample[dir="snippets/buildlifecycle/buildProjectEvaluateEvents/groovy",files="build.gradle[tags=evaluate-events]"] include::sample[dir="snippets/buildlifecycle/buildProjectEvaluateEvents/kotlin",files="build.gradle.kts[tags=evaluate-events]"] ==== -==== Output of **`gradle -q test`** +The following example runs logic when *any* project finishes evaluation: + [source.multi-language-sample,groovy] ---- > gradle -q test @@ -138,50 +159,64 @@ include::{snippetsPath}/buildlifecycle/buildProjectEvaluateEvents/tests-groovy/b include::{snippetsPath}/buildlifecycle/buildProjectEvaluateEvents/tests-kotlin/buildProjectEvaluateEvents.kotlin.out[] ---- -You can also add a link:{javadocPath}/org/gradle/api/ProjectEvaluationListener.html[ProjectEvaluationListener] to the link:{groovyDslPath}/org.gradle.api.invocation.Gradle.html[Gradle] to receive these events. +To receive these events via a listener instead of a closure, add a link:{javadocPath}/org/gradle/api/ProjectEvaluationListener.html[ProjectEvaluationListener] to a build's link:{groovyDslPath}/org.gradle.api.invocation.Gradle.html[Gradle] instance. + +=== Task Execution Graph Assembly + +During project evaluation, Gradle assembles the *task execution graph*: a http://en.wikipedia.org/wiki/Directed_acyclic_graph[DAG] representing the dependency relationships between tasks. + +[[sec:task_execution_graph_ready]] +=== React to Task Execution Graph Assembly + +You can receive a notification immediately after Gradle finishes populating a project's task execution graph. + +To receive these events, add a link:{javadocPath}/org/gradle/api/execution/TaskExecutionGraphListener.html[TaskExecutionGraphListener] to a project's link:{javadocPath}/org/gradle/api/execution/TaskExecutionGraph.html[TaskExecutionGraph]. + +=== Task Creation + +During project evaluation, Gradle creates tasks and configures inputs, outputs, and actions for those tasks. [[sec:task_creation]] -=== Task creation +==== React to Task Creation -You can receive a notification immediately after a task is added to a project. This can be used to set some default values or add behaviour before the task is made available in the build file. +You can receive a notification immediately after Gradle adds a task to a project. +For example, you could use these notifications to set some default values or methods. -The following example sets the `srcDir` property of each task as it is created. +The following example sets a `srcDir` value on each task in a project: -.Setting of certain property to all tasks ==== include::sample[dir="snippets/buildlifecycle/taskCreationEvents/groovy",files="build.gradle[]"] include::sample[dir="snippets/buildlifecycle/taskCreationEvents/kotlin",files="build.gradle.kts[]"] ==== -.Output of **`gradle -q a`** ---- > gradle -q a include::{snippetsPath}/buildlifecycle/taskCreationEvents/tests/taskCreationEvents.out[] ---- -You can also add an link:{javadocPath}/org/gradle/api/Action.html[Action] to a link:{javadocPath}/org/gradle/api/tasks/TaskContainer.html[TaskContainer] to receive these events. +To receive these events via a listener instead of a closure, add an link:{javadocPath}/org/gradle/api/Action.html[Action] to a link:{javadocPath}/org/gradle/api/tasks/TaskContainer.html[TaskContainer]. -[[sec:task_execution_graph_ready]] -=== Task execution graph ready - -You can receive a notification immediately after the task execution graph has been populated. +== Execution -You can also add a link:{javadocPath}/org/gradle/api/execution/TaskExecutionGraphListener.html[TaskExecutionGraphListener] to the link:{javadocPath}/org/gradle/api/execution/TaskExecutionGraph.html[TaskExecutionGraph] to receive these events. +In the execution phase, Gradle runs tasks. +Gradle uses the task execution graphs generated by the configuration phase to determine which tasks to execute. [[sec:task_execution]] -=== Task execution +=== Task Execution + +Task execution includes most of the work you normally associate with a build: downloading libraries, compiling code, reading inputs, and writing outputs. -You can receive a notification immediately before and after any task is executed. +==== React to Task Execution Notifications -The following example logs the start and end of each task execution. Notice that the `afterTask` notification is received regardless of whether the task completes successfully or fails with an exception. +You can receive a notification immediately before and after Gradle executes any task. +These notifications work even when task execution fails. +The following example logs the start and end of each task execution: -.Logging of start and end of each task execution ==== include::sample[dir="snippets/buildlifecycle/taskExecutionEvents/groovy",files="build.gradle[]"] include::sample[dir="snippets/buildlifecycle/taskExecutionEvents/kotlin",files="build.gradle.kts[]"] ==== -==== Output of **`gradle -q broken`** [source.multi-language-sample,groovy] ---- > gradle -q broken @@ -193,4 +228,4 @@ include::{snippetsPath}/buildlifecycle/taskExecutionEvents/tests-groovy/taskExec include::{snippetsPath}/buildlifecycle/taskExecutionEvents/tests-kotlin/taskExecutionEvents.kotlin.out[] ---- -You can also use a link:{javadocPath}/org/gradle/api/execution/TaskExecutionListener.html[TaskExecutionListener] to the link:{javadocPath}/org/gradle/api/execution/TaskExecutionGraph.html[TaskExecutionGraph] to receive these events. +To receive these events via a listener instead of a closure, add a link:{javadocPath}/org/gradle/api/execution/TaskExecutionListener.html[TaskExecutionListener] to a project's link:{javadocPath}/org/gradle/api/execution/TaskExecutionGraph.html[TaskExecutionGraph]. diff --git a/subprojects/docs/src/docs/userguide/authoring-builds/organizing_gradle_projects.adoc b/subprojects/docs/src/docs/userguide/authoring-builds/organizing_gradle_projects.adoc index 916abcfe0dfd..988148395c3c 100644 --- a/subprojects/docs/src/docs/userguide/authoring-builds/organizing_gradle_projects.adoc +++ b/subprojects/docs/src/docs/userguide/authoring-builds/organizing_gradle_projects.adoc @@ -95,8 +95,12 @@ Gradle tries to locate a `settings.gradle` (Groovy DSL) or a `settings.gradle.kt For that purpose, the runtime walks the hierarchy of the directory tree up to the root directory. The algorithm stops searching as soon as it finds the settings file. +A multi-project build must have a `settings.gradle` file in the root project of the multi-project hierarchy. +It is required because the settings file defines which projects are taking part in a <>. +For a single-project build, the settings file is optional. +Besides defining included projects, you might need it to <>. + Always add a `settings.gradle` to the root directory of your build to avoid the initial performance impact. -This recommendation applies to single project builds as well as multi-project builds. The file can either be empty or define the desired name of the project. A typical Gradle project with a settings file look as such: From d7abd5cc0dd6dde7884eff2f603c323f91a2d558 Mon Sep 17 00:00:00 2001 From: nate contino Date: Sat, 22 Oct 2022 01:00:44 +0200 Subject: [PATCH 02/24] Fix links broken during refactor (cherry picked from commit bfbb6c4353215ff9bb45386e6810cbeb5991164d) Signed-off-by: Julia Boes --- subprojects/docs/src/docs/userguide/api/kotlin_dsl.adoc | 2 +- .../src/docs/userguide/authoring-builds/build_lifecycle.adoc | 1 + .../userguide/authoring-builds/organizing_gradle_projects.adoc | 1 + .../docs/userguide/authoring-builds/writing_build_scripts.adoc | 2 +- .../migration/migrating_from_groovy_to_kotlin_dsl.adoc | 2 +- .../docs/src/docs/userguide/migration/upgrading_version_6.adoc | 2 +- .../docs/src/docs/userguide/reference/directory_layout.adoc | 2 +- 7 files changed, 7 insertions(+), 5 deletions(-) diff --git a/subprojects/docs/src/docs/userguide/api/kotlin_dsl.adoc b/subprojects/docs/src/docs/userguide/api/kotlin_dsl.adoc index 7dae8a1feb75..d6197269a01f 100644 --- a/subprojects/docs/src/docs/userguide/api/kotlin_dsl.adoc +++ b/subprojects/docs/src/docs/userguide/api/kotlin_dsl.adoc @@ -158,7 +158,7 @@ Groovy DSL script files use the `.gradle` file name extension. Kotlin DSL script files use the `.gradle.kts` file name extension. ==== -To activate the Kotlin DSL, simply use the `.gradle.kts` extension for your build scripts in place of `.gradle`. That also applies to the <> — for example `settings.gradle.kts` — and <>. +To activate the Kotlin DSL, simply use the `.gradle.kts` extension for your build scripts in place of `.gradle`. That also applies to the <> — for example `settings.gradle.kts` — and <>. Note that you can mix Groovy DSL build scripts with Kotlin DSL ones, i.e. a Kotlin DSL build script can apply a Groovy DSL one and each project in a multi-project build can use either one. diff --git a/subprojects/docs/src/docs/userguide/authoring-builds/build_lifecycle.adoc b/subprojects/docs/src/docs/userguide/authoring-builds/build_lifecycle.adoc index 54a114bb4fac..39800634b79d 100644 --- a/subprojects/docs/src/docs/userguide/authoring-builds/build_lifecycle.adoc +++ b/subprojects/docs/src/docs/userguide/authoring-builds/build_lifecycle.adoc @@ -36,6 +36,7 @@ image::task-dag-examples.png[Example task graphs] Both plugins and your own build scripts contribute to the task graph via the <>. +[[build_lifecycle_events]] [[sec:build_phases]] == Build Phases diff --git a/subprojects/docs/src/docs/userguide/authoring-builds/organizing_gradle_projects.adoc b/subprojects/docs/src/docs/userguide/authoring-builds/organizing_gradle_projects.adoc index 988148395c3c..f190790a14ae 100644 --- a/subprojects/docs/src/docs/userguide/authoring-builds/organizing_gradle_projects.adoc +++ b/subprojects/docs/src/docs/userguide/authoring-builds/organizing_gradle_projects.adoc @@ -89,6 +89,7 @@ While those conventions can be reconfigured, it makes it harder to build script Try to stick to the default conventions as much as possible except if you need to adapt to the layout of a legacy project. Refer to the reference page of the relevant plugin to learn about its default conventions. +[[sec:settings_file]] == Always define a settings file Gradle tries to locate a `settings.gradle` (Groovy DSL) or a `settings.gradle.kts` (Kotlin DSL) file with every invocation of the build. diff --git a/subprojects/docs/src/docs/userguide/authoring-builds/writing_build_scripts.adoc b/subprojects/docs/src/docs/userguide/authoring-builds/writing_build_scripts.adoc index 2aee6d97faf8..907e75734fbc 100644 --- a/subprojects/docs/src/docs/userguide/authoring-builds/writing_build_scripts.adoc +++ b/subprojects/docs/src/docs/userguide/authoring-builds/writing_build_scripts.adoc @@ -96,7 +96,7 @@ The `Project` object provides some standard properties, which are available in y .Script with other targets ==== The _build scripts_ described here target `Project` objects. -There are also <> and <> that respectively target link:{groovyDslPath}/org.gradle.api.initialization.Settings.html[Settings] and link:{groovyDslPath}/org.gradle.api.invocation.Gradle.html[Gradle] objects. +There are also <> and <> that respectively target link:{groovyDslPath}/org.gradle.api.initialization.Settings.html[Settings] and link:{groovyDslPath}/org.gradle.api.invocation.Gradle.html[Gradle] objects. ==== [[sec:the_script_api]] diff --git a/subprojects/docs/src/docs/userguide/migration/migrating_from_groovy_to_kotlin_dsl.adoc b/subprojects/docs/src/docs/userguide/migration/migrating_from_groovy_to_kotlin_dsl.adoc index 1fa67ab1a953..d7f23a7dbd40 100644 --- a/subprojects/docs/src/docs/userguide/migration/migrating_from_groovy_to_kotlin_dsl.adoc +++ b/subprojects/docs/src/docs/userguide/migration/migrating_from_groovy_to_kotlin_dsl.adoc @@ -143,7 +143,7 @@ Kotlin DSL script files use the `.gradle.kts` file name extension. To use the Kotlin DSL, simply name your files `build.gradle.kts` instead of `build.gradle`. -The <>, `settings.gradle`, can also be renamed `settings.gradle.kts`. +The <>, `settings.gradle`, can also be renamed `settings.gradle.kts`. In a multi-project build, you can have some modules using the Groovy DSL (with `build.gradle`) and others using the Kotlin DSL (with `build.gradle.kts`). diff --git a/subprojects/docs/src/docs/userguide/migration/upgrading_version_6.adoc b/subprojects/docs/src/docs/userguide/migration/upgrading_version_6.adoc index 92dee6492d5d..5cf91748c685 100644 --- a/subprojects/docs/src/docs/userguide/migration/upgrading_version_6.adoc +++ b/subprojects/docs/src/docs/userguide/migration/upgrading_version_6.adoc @@ -297,7 +297,7 @@ The `layout` method taking a configuration block has been removed and is replace A Gradle build is defined by its `settings.gradle(.kts)` file found in the current or parent directory. Without a settings file, a Gradle build is undefined and Gradle produces an error when attempting to execute tasks. -To fix this error, <> for the build. +To fix this error, <> for the build. Exceptions to this are invoking Gradle with the `init` task or using diagnostic command line flags, such as `--version`. diff --git a/subprojects/docs/src/docs/userguide/reference/directory_layout.adoc b/subprojects/docs/src/docs/userguide/reference/directory_layout.adoc index 20a4b3bdbb92..3938c4e054e4 100644 --- a/subprojects/docs/src/docs/userguide/reference/directory_layout.adoc +++ b/subprojects/docs/src/docs/userguide/reference/directory_layout.adoc @@ -107,7 +107,7 @@ Overall, the anatomy of a typical project root directory looks roughly as follow <4> Contains the JAR file and configuration of the <> <5> Project-specific <> <6> Scripts for executing builds using the <> -<7> The project's <> where the list of subprojects is defined +<7> The project's <> where the list of subprojects is defined <8> Usually a project is organized into one or multiple subprojects <9> Each subproject has its own Gradle build script From 7f59776dc39b245308b1e9a0f8b59fe7d1d2b123 Mon Sep 17 00:00:00 2001 From: nate contino Date: Thu, 20 Oct 2022 08:19:28 -0400 Subject: [PATCH 03/24] Clarify that plugins also configure the dependency graph. Co-authored-by: Paul Merlin (cherry picked from commit d38d4583baa3a466b0b2cce9927812331d995d5a) Signed-off-by: Julia Boes --- .../src/docs/userguide/authoring-builds/build_lifecycle.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subprojects/docs/src/docs/userguide/authoring-builds/build_lifecycle.adoc b/subprojects/docs/src/docs/userguide/authoring-builds/build_lifecycle.adoc index 39800634b79d..ade05daa7824 100644 --- a/subprojects/docs/src/docs/userguide/authoring-builds/build_lifecycle.adoc +++ b/subprojects/docs/src/docs/userguide/authoring-builds/build_lifecycle.adoc @@ -17,7 +17,7 @@ Gradle is an example of *dependency based programming*: you define tasks and dependencies between tasks. Gradle guarantees that these tasks execute in the order of their dependencies. -Your build scripts configure this dependency graph. +Your build scripts and plugins configure this dependency graph. This page discusses the phases of the lifecycle Gradle passes through as it interprets those scripts. Additionally, this page explains how you can react to events of the lifecycle using notifications. From 039e5e68e26d4a3c2e43f691e401cb0168eab84e Mon Sep 17 00:00:00 2001 From: nate contino Date: Thu, 20 Oct 2022 08:20:16 -0400 Subject: [PATCH 04/24] Tighten up description of execution phase Co-authored-by: Paul Merlin (cherry picked from commit e27e94610e02d378fcb16a390f236de1c99a466a) Signed-off-by: Julia Boes --- .../src/docs/userguide/authoring-builds/build_lifecycle.adoc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/subprojects/docs/src/docs/userguide/authoring-builds/build_lifecycle.adoc b/subprojects/docs/src/docs/userguide/authoring-builds/build_lifecycle.adoc index ade05daa7824..87bb1fc19e3f 100644 --- a/subprojects/docs/src/docs/userguide/authoring-builds/build_lifecycle.adoc +++ b/subprojects/docs/src/docs/userguide/authoring-builds/build_lifecycle.adoc @@ -51,8 +51,7 @@ Configuration:: - Evaluates the build scripts of every project participating in the build. - Creates a task graph for all projects. Execution:: -- Calculates tasks to run based on the passed task name arguments. -- Executes each of the selected tasks in the order of their dependencies. +- Schedules and executes each of the selected tasks in the order of their dependencies. === Example From e13524e9c693d9d2c9f56fd09705c1e840df9b41 Mon Sep 17 00:00:00 2001 From: nate contino Date: Thu, 20 Oct 2022 08:22:35 -0400 Subject: [PATCH 05/24] Add included builds mention to build lifecycle explanation Co-authored-by: Paul Merlin (cherry picked from commit 137184fa0a582c22b861e3653173de25c3c37fae) Signed-off-by: Julia Boes --- .../src/docs/userguide/authoring-builds/build_lifecycle.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subprojects/docs/src/docs/userguide/authoring-builds/build_lifecycle.adoc b/subprojects/docs/src/docs/userguide/authoring-builds/build_lifecycle.adoc index 87bb1fc19e3f..e49d7743b096 100644 --- a/subprojects/docs/src/docs/userguide/authoring-builds/build_lifecycle.adoc +++ b/subprojects/docs/src/docs/userguide/authoring-builds/build_lifecycle.adoc @@ -45,7 +45,7 @@ Gradle runs these phases in order: first initialization, then configuration, and Initialization:: - Detects the settings file. -- Evaluates the <> to determine which projects participate in the build. +- Evaluates the <> to determine which projects and included builds participate in the build. - Creates a link:{groovyDslPath}/org.gradle.api.Project.html[`Project`] instance for every project. Configuration:: - Evaluates the build scripts of every project participating in the build. From 80542c366b6757353311bde81d86cba353d09ef0 Mon Sep 17 00:00:00 2001 From: nate contino Date: Thu, 20 Oct 2022 08:22:59 -0400 Subject: [PATCH 06/24] Add included builds to another section of the build lifecycle doc Co-authored-by: Paul Merlin (cherry picked from commit ba2d99cd2d8b469fb34a90278d7412217c928bca) Signed-off-by: Julia Boes --- .../src/docs/userguide/authoring-builds/build_lifecycle.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subprojects/docs/src/docs/userguide/authoring-builds/build_lifecycle.adoc b/subprojects/docs/src/docs/userguide/authoring-builds/build_lifecycle.adoc index e49d7743b096..35392f7ef82c 100644 --- a/subprojects/docs/src/docs/userguide/authoring-builds/build_lifecycle.adoc +++ b/subprojects/docs/src/docs/userguide/authoring-builds/build_lifecycle.adoc @@ -76,7 +76,7 @@ include::{snippetsPath}/buildlifecycle/basic/tests/buildlifecycle.out[] [[sec:initialization]] == Initialization -In the initialization phase, Gradle detects the set of projects participating in the build. +In the initialization phase, Gradle detects the set of projects and included builds participating in the build. Then, Gradle evaluates the settings file. Finally, Gradle instantiates `Project` instances for each project. === Detect Settings File From b1b79bbdf1b115acd72a8c5dd4deb68ea9fcae13 Mon Sep 17 00:00:00 2001 From: nate contino Date: Thu, 20 Oct 2022 08:24:08 -0400 Subject: [PATCH 07/24] Add composite builds mention in lifecycle docs Co-authored-by: Paul Merlin (cherry picked from commit b99a3aff2b095ddeb55e94d9167005a8d201fe4c) Signed-off-by: Julia Boes --- .../src/docs/userguide/authoring-builds/build_lifecycle.adoc | 1 + 1 file changed, 1 insertion(+) diff --git a/subprojects/docs/src/docs/userguide/authoring-builds/build_lifecycle.adoc b/subprojects/docs/src/docs/userguide/authoring-builds/build_lifecycle.adoc index 35392f7ef82c..002b64b28900 100644 --- a/subprojects/docs/src/docs/userguide/authoring-builds/build_lifecycle.adoc +++ b/subprojects/docs/src/docs/userguide/authoring-builds/build_lifecycle.adoc @@ -98,6 +98,7 @@ To build projects that use a nonstandard layout, execute the build from the dire During settings file evaluation, Gradle: - Adds libraries to your build script classpath. +- Defines which included builds participate in a composite build. - Defines which projects participate in a multi-project build. Gradle creates a `Project` for every project in the build. From 8ef60578b97cfc63cb5b6a1b98928f774e2a7d4f Mon Sep 17 00:00:00 2001 From: nate contino Date: Thu, 20 Oct 2022 08:52:40 -0400 Subject: [PATCH 08/24] Change create to register, clarify configuration actions Co-authored-by: Paul Merlin (cherry picked from commit ffe2a3cd1f261d5bf2e978d47bb372002e36826a) Signed-off-by: Julia Boes --- .../src/docs/userguide/authoring-builds/build_lifecycle.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subprojects/docs/src/docs/userguide/authoring-builds/build_lifecycle.adoc b/subprojects/docs/src/docs/userguide/authoring-builds/build_lifecycle.adoc index 002b64b28900..082a64eae198 100644 --- a/subprojects/docs/src/docs/userguide/authoring-builds/build_lifecycle.adoc +++ b/subprojects/docs/src/docs/userguide/authoring-builds/build_lifecycle.adoc @@ -175,7 +175,7 @@ To receive these events, add a link:{javadocPath}/org/gradle/api/execution/TaskE === Task Creation -During project evaluation, Gradle creates tasks and configures inputs, outputs, and actions for those tasks. +During project evaluation, Gradle registers tasks and their configuration actions. The configuration actions define inputs, outputs, and actions for those tasks. They are evaluated if the task is part of the task graph for the requested tasks. [[sec:task_creation]] ==== React to Task Creation From a769dfe09838f5d9b36fe8c4a37abaff27adcf62 Mon Sep 17 00:00:00 2001 From: nate contino Date: Thu, 20 Oct 2022 09:08:12 -0400 Subject: [PATCH 09/24] Replace Project.afterEvaluate with gradle.afterProject (cherry picked from commit 7530fc7b669a065220216db5dabb8521ee7a1247) Signed-off-by: Julia Boes --- .../src/docs/userguide/authoring-builds/build_lifecycle.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subprojects/docs/src/docs/userguide/authoring-builds/build_lifecycle.adoc b/subprojects/docs/src/docs/userguide/authoring-builds/build_lifecycle.adoc index 082a64eae198..e52fec184e57 100644 --- a/subprojects/docs/src/docs/userguide/authoring-builds/build_lifecycle.adoc +++ b/subprojects/docs/src/docs/userguide/authoring-builds/build_lifecycle.adoc @@ -140,7 +140,7 @@ include::sample[dir="snippets/buildlifecycle/projectEvaluateEvents/kotlin",files include::{snippetsPath}/buildlifecycle/projectEvaluateEvents/tests/projectEvaluateEvents.out[] ---- -The following example uses `Project.afterEvaluate()` to run logic when a project finishes evaluation: +The following example uses `gradle.afterProject()` to run logic when a project finishes evaluation: ==== include::sample[dir="snippets/buildlifecycle/buildProjectEvaluateEvents/groovy",files="build.gradle[tags=evaluate-events]"] From ac93d0d0307b166a37c0d5b6a9b0ce8e58115070 Mon Sep 17 00:00:00 2001 From: nate contino Date: Fri, 21 Oct 2022 10:27:07 -0400 Subject: [PATCH 10/24] Make it clearer that you should always define a settings file (cherry picked from commit 842006dab49c487940600a3380c868debf3f4401) Signed-off-by: Julia Boes --- .../authoring-builds/organizing_gradle_projects.adoc | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/subprojects/docs/src/docs/userguide/authoring-builds/organizing_gradle_projects.adoc b/subprojects/docs/src/docs/userguide/authoring-builds/organizing_gradle_projects.adoc index f190790a14ae..d1a44aff73b9 100644 --- a/subprojects/docs/src/docs/userguide/authoring-builds/organizing_gradle_projects.adoc +++ b/subprojects/docs/src/docs/userguide/authoring-builds/organizing_gradle_projects.adoc @@ -96,15 +96,14 @@ Gradle tries to locate a `settings.gradle` (Groovy DSL) or a `settings.gradle.kt For that purpose, the runtime walks the hierarchy of the directory tree up to the root directory. The algorithm stops searching as soon as it finds the settings file. +Always add a `settings.gradle` to the root directory of your build to avoid the initial performance impact. +The file can either be empty or define the desired name of the project. + A multi-project build must have a `settings.gradle` file in the root project of the multi-project hierarchy. It is required because the settings file defines which projects are taking part in a <>. -For a single-project build, the settings file is optional. Besides defining included projects, you might need it to <>. -Always add a `settings.gradle` to the root directory of your build to avoid the initial performance impact. -The file can either be empty or define the desired name of the project. - -A typical Gradle project with a settings file look as such: +The following example shows a standard Gradle project layout: ==== [.multi-language-sample] From 3eb95d655ddcfdf7f64256b3db49bf7ec087c691 Mon Sep 17 00:00:00 2001 From: nate contino Date: Fri, 21 Oct 2022 10:29:38 -0400 Subject: [PATCH 11/24] Clarify settings file evaluation order (cherry picked from commit dc2618da740f7c8aeee6f11116d3c6ab74acd280) Signed-off-by: Julia Boes --- .../src/docs/userguide/authoring-builds/build_lifecycle.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subprojects/docs/src/docs/userguide/authoring-builds/build_lifecycle.adoc b/subprojects/docs/src/docs/userguide/authoring-builds/build_lifecycle.adoc index e52fec184e57..04219cac8db4 100644 --- a/subprojects/docs/src/docs/userguide/authoring-builds/build_lifecycle.adoc +++ b/subprojects/docs/src/docs/userguide/authoring-builds/build_lifecycle.adoc @@ -77,7 +77,7 @@ include::{snippetsPath}/buildlifecycle/basic/tests/buildlifecycle.out[] == Initialization In the initialization phase, Gradle detects the set of projects and included builds participating in the build. -Then, Gradle evaluates the settings file. Finally, Gradle instantiates `Project` instances for each project. +Gradle first evaluates the settings file. Then, Gradle instantiates `Project` instances for each project. === Detect Settings File From b4b6c184284d2974c2ef2ff2a1dae1af6482b8a6 Mon Sep 17 00:00:00 2001 From: nate contino Date: Fri, 21 Oct 2022 10:30:20 -0400 Subject: [PATCH 12/24] Included Kotlin and Groovy DSL settings file variants (cherry picked from commit dc6131b89489165d7633d989ed424fd0492bcba4) Signed-off-by: Julia Boes --- .../userguide/authoring-builds/organizing_gradle_projects.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subprojects/docs/src/docs/userguide/authoring-builds/organizing_gradle_projects.adoc b/subprojects/docs/src/docs/userguide/authoring-builds/organizing_gradle_projects.adoc index d1a44aff73b9..7681408cf4f3 100644 --- a/subprojects/docs/src/docs/userguide/authoring-builds/organizing_gradle_projects.adoc +++ b/subprojects/docs/src/docs/userguide/authoring-builds/organizing_gradle_projects.adoc @@ -99,7 +99,7 @@ The algorithm stops searching as soon as it finds the settings file. Always add a `settings.gradle` to the root directory of your build to avoid the initial performance impact. The file can either be empty or define the desired name of the project. -A multi-project build must have a `settings.gradle` file in the root project of the multi-project hierarchy. +A multi-project build must have a `settings.gradle(.kts)` file in the root project of the multi-project hierarchy. It is required because the settings file defines which projects are taking part in a <>. Besides defining included projects, you might need it to <>. From 31daeade5ddc5a48cf9e11b60a4db905460db8ca Mon Sep 17 00:00:00 2001 From: nate contino Date: Fri, 21 Oct 2022 10:33:25 -0400 Subject: [PATCH 13/24] Link to settings file documentation on first occurrence (cherry picked from commit 0229876c635f15e5edc01ff49c39024f8850793e) Signed-off-by: Julia Boes --- .../src/docs/userguide/authoring-builds/build_lifecycle.adoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/subprojects/docs/src/docs/userguide/authoring-builds/build_lifecycle.adoc b/subprojects/docs/src/docs/userguide/authoring-builds/build_lifecycle.adoc index 04219cac8db4..e95e4c3c22c0 100644 --- a/subprojects/docs/src/docs/userguide/authoring-builds/build_lifecycle.adoc +++ b/subprojects/docs/src/docs/userguide/authoring-builds/build_lifecycle.adoc @@ -44,8 +44,8 @@ A Gradle build has three distinct phases. Gradle runs these phases in order: first initialization, then configuration, and finally execution. Initialization:: -- Detects the settings file. -- Evaluates the <> to determine which projects and included builds participate in the build. +- Detects the <>. +- Evaluates the settings file to determine which projects and included builds participate in the build. - Creates a link:{groovyDslPath}/org.gradle.api.Project.html[`Project`] instance for every project. Configuration:: - Evaluates the build scripts of every project participating in the build. From d568062c7045c192d4ebcaa8292be513ea8b4763 Mon Sep 17 00:00:00 2001 From: nate contino Date: Fri, 21 Oct 2022 10:34:06 -0400 Subject: [PATCH 14/24] Clarify that task graph applies to requested tasks only Co-authored-by: Paul Merlin (cherry picked from commit ed3421671a69a1586039602401395d8d8fcb9168) Signed-off-by: Julia Boes --- .../src/docs/userguide/authoring-builds/build_lifecycle.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subprojects/docs/src/docs/userguide/authoring-builds/build_lifecycle.adoc b/subprojects/docs/src/docs/userguide/authoring-builds/build_lifecycle.adoc index e95e4c3c22c0..de5526401ac9 100644 --- a/subprojects/docs/src/docs/userguide/authoring-builds/build_lifecycle.adoc +++ b/subprojects/docs/src/docs/userguide/authoring-builds/build_lifecycle.adoc @@ -49,7 +49,7 @@ Initialization:: - Creates a link:{groovyDslPath}/org.gradle.api.Project.html[`Project`] instance for every project. Configuration:: - Evaluates the build scripts of every project participating in the build. -- Creates a task graph for all projects. +- Creates a task graph for requested tasks. Execution:: - Schedules and executes each of the selected tasks in the order of their dependencies. From 1caab0d54248ceb15e3b71a645a623b92a150bbf Mon Sep 17 00:00:00 2001 From: nate contino Date: Fri, 21 Oct 2022 10:41:04 -0400 Subject: [PATCH 15/24] Inclusivity for Kotlin AND Groovy DSLs (cherry picked from commit 87f2015714e97d51c5bfabcb46bbc5e8f0395494) Signed-off-by: Julia Boes --- .../docs/userguide/authoring-builds/build_lifecycle.adoc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/subprojects/docs/src/docs/userguide/authoring-builds/build_lifecycle.adoc b/subprojects/docs/src/docs/userguide/authoring-builds/build_lifecycle.adoc index de5526401ac9..3a255792fdd2 100644 --- a/subprojects/docs/src/docs/userguide/authoring-builds/build_lifecycle.adoc +++ b/subprojects/docs/src/docs/userguide/authoring-builds/build_lifecycle.adoc @@ -85,9 +85,9 @@ When you run Gradle in a directory that contains a `settings.gradle` file, Gradl You can run Gradle within any subproject of the build.footnote:[Gradle supports partial multi-project builds (see <>).] When you run Gradle in a directory that contains *no* `settings.gradle` file: -. Gradle looks for a `settings.gradle` file in parent directories. -. If Gradle finds a `settings.gradle` file, Gradle checks if the current project is part of the multi-project build. If so, Gradle builds as a multi-project. -. If Gradle does not find a `settings.gradle` file, Gradle builds as a single project. +. Gradle looks for a `settings.gradle(.kts)` file in parent directories. +. If Gradle finds a `settings.gradle(.kts)` file, Gradle checks if the current project is part of the multi-project build. If so, Gradle builds as a multi-project. +. If Gradle does not find a `settings.gradle(.kts)` file, Gradle builds as a single project. In the standard Gradle project layout, project paths match the physical subproject layout on disk. The automatic search for a `settings.gradle` file only works for multi-project builds with a standard project layout. From 2a393c91f4a7a73f311262ba0f57a11a4f8c8742 Mon Sep 17 00:00:00 2001 From: nate contino Date: Fri, 21 Oct 2022 10:41:54 -0400 Subject: [PATCH 16/24] Include Kotlin and Groovy DSL (cherry picked from commit c224b27002ba3e60fa6cecf70c1e757db9df8666) Signed-off-by: Julia Boes --- .../src/docs/userguide/authoring-builds/build_lifecycle.adoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/subprojects/docs/src/docs/userguide/authoring-builds/build_lifecycle.adoc b/subprojects/docs/src/docs/userguide/authoring-builds/build_lifecycle.adoc index 3a255792fdd2..bbc4bca05b49 100644 --- a/subprojects/docs/src/docs/userguide/authoring-builds/build_lifecycle.adoc +++ b/subprojects/docs/src/docs/userguide/authoring-builds/build_lifecycle.adoc @@ -90,8 +90,8 @@ When you run Gradle in a directory that contains *no* `settings.gradle` file: . If Gradle does not find a `settings.gradle(.kts)` file, Gradle builds as a single project. In the standard Gradle project layout, project paths match the physical subproject layout on disk. -The automatic search for a `settings.gradle` file only works for multi-project builds with a standard project layout. -To build projects that use a nonstandard layout, execute the build from the directory that contains `settings.gradle`. +The automatic search for a settings file only works for multi-project builds with a standard project layout. +To build projects that use a nonstandard layout, execute the build from the directory that contains `settings.gradle(.kts)`. === Evaluate Settings File From e77611d3efee069232da72b7402c1b842a11f2d2 Mon Sep 17 00:00:00 2001 From: nate contino Date: Fri, 21 Oct 2022 10:42:26 -0400 Subject: [PATCH 17/24] Clarify that task execution graph only includes requested tasks Co-authored-by: Paul Merlin (cherry picked from commit e8e6eca7d8bd0826965ede23fa95757ee53e9a6a) Signed-off-by: Julia Boes --- .../src/docs/userguide/authoring-builds/build_lifecycle.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subprojects/docs/src/docs/userguide/authoring-builds/build_lifecycle.adoc b/subprojects/docs/src/docs/userguide/authoring-builds/build_lifecycle.adoc index bbc4bca05b49..312d5573f9e9 100644 --- a/subprojects/docs/src/docs/userguide/authoring-builds/build_lifecycle.adoc +++ b/subprojects/docs/src/docs/userguide/authoring-builds/build_lifecycle.adoc @@ -109,7 +109,7 @@ Any project may have child projects. == Configuration In the configuration phase, Gradle adds tasks and other properties to the projects generated by the initialization phase. -By the end of the configuration phase, Gradle has a complete task execution graph for each project. +By the end of the configuration phase, Gradle has a complete task execution graph for the requested tasks. [[sec:project_evaluation]] === Project Evaluation From fb06945d24c70b6d75aa56fcfb231e50ccf833df Mon Sep 17 00:00:00 2001 From: nate contino Date: Sat, 22 Oct 2022 00:48:38 +0200 Subject: [PATCH 18/24] Remove allproject antipattern and eliminate now-redundant afterProject example (cherry picked from commit 29a47583bc22f5b538349aaed4f2395ad8a47c91) Signed-off-by: Julia Boes --- .../authoring-builds/build_lifecycle.adoc | 23 ++----------------- .../groovy/build.gradle | 11 --------- .../groovy/project-b.gradle | 1 - .../groovy/settings.gradle | 5 ---- .../kotlin/build.gradle.kts | 11 --------- .../kotlin/project-b.gradle.kts | 1 - .../kotlin/settings.gradle.kts | 5 ---- ...ojectEvaluateEventsSanityCheck.sample.conf | 3 --- .../buildProjectEvaluateEvents.groovy.out | 21 ----------------- ...ldProjectEvaluateEvents.groovy.sample.conf | 6 ----- .../buildProjectEvaluateEvents.kotlin.out | 20 ---------------- ...ldProjectEvaluateEvents.kotlin.sample.conf | 6 ----- .../projectEvaluateEvents/groovy/build.gradle | 23 +++++++++---------- .../kotlin/build.gradle.kts | 17 +++++++------- 14 files changed, 22 insertions(+), 131 deletions(-) delete mode 100644 subprojects/docs/src/snippets/buildlifecycle/buildProjectEvaluateEvents/groovy/build.gradle delete mode 100644 subprojects/docs/src/snippets/buildlifecycle/buildProjectEvaluateEvents/groovy/project-b.gradle delete mode 100644 subprojects/docs/src/snippets/buildlifecycle/buildProjectEvaluateEvents/groovy/settings.gradle delete mode 100644 subprojects/docs/src/snippets/buildlifecycle/buildProjectEvaluateEvents/kotlin/build.gradle.kts delete mode 100644 subprojects/docs/src/snippets/buildlifecycle/buildProjectEvaluateEvents/kotlin/project-b.gradle.kts delete mode 100644 subprojects/docs/src/snippets/buildlifecycle/buildProjectEvaluateEvents/kotlin/settings.gradle.kts delete mode 100644 subprojects/docs/src/snippets/buildlifecycle/buildProjectEvaluateEvents/tests-common/buildProjectEvaluateEventsSanityCheck.sample.conf delete mode 100644 subprojects/docs/src/snippets/buildlifecycle/buildProjectEvaluateEvents/tests-groovy/buildProjectEvaluateEvents.groovy.out delete mode 100644 subprojects/docs/src/snippets/buildlifecycle/buildProjectEvaluateEvents/tests-groovy/buildProjectEvaluateEvents.groovy.sample.conf delete mode 100644 subprojects/docs/src/snippets/buildlifecycle/buildProjectEvaluateEvents/tests-kotlin/buildProjectEvaluateEvents.kotlin.out delete mode 100644 subprojects/docs/src/snippets/buildlifecycle/buildProjectEvaluateEvents/tests-kotlin/buildProjectEvaluateEvents.kotlin.sample.conf diff --git a/subprojects/docs/src/docs/userguide/authoring-builds/build_lifecycle.adoc b/subprojects/docs/src/docs/userguide/authoring-builds/build_lifecycle.adoc index 312d5573f9e9..ea9c91564698 100644 --- a/subprojects/docs/src/docs/userguide/authoring-builds/build_lifecycle.adoc +++ b/subprojects/docs/src/docs/userguide/authoring-builds/build_lifecycle.adoc @@ -128,7 +128,8 @@ For example, you could use these notifications for: - custom logging - custom profiling -The following example adds a `test` task to each project where the `hasTests` property value is `true`: +The following example uses `gradle.beforeProject()` to add `hasTests` property to certain tests. +Later, the example uses `gradle.afterProject()` to add a `test` task to each project where the `hasTests` property value is `true`: ==== include::sample[dir="snippets/buildlifecycle/projectEvaluateEvents/groovy",files="build.gradle[tags=after-evaluate];project-a.gradle[]"] @@ -140,26 +141,6 @@ include::sample[dir="snippets/buildlifecycle/projectEvaluateEvents/kotlin",files include::{snippetsPath}/buildlifecycle/projectEvaluateEvents/tests/projectEvaluateEvents.out[] ---- -The following example uses `gradle.afterProject()` to run logic when a project finishes evaluation: - -==== -include::sample[dir="snippets/buildlifecycle/buildProjectEvaluateEvents/groovy",files="build.gradle[tags=evaluate-events]"] -include::sample[dir="snippets/buildlifecycle/buildProjectEvaluateEvents/kotlin",files="build.gradle.kts[tags=evaluate-events]"] -==== - -The following example runs logic when *any* project finishes evaluation: - -[source.multi-language-sample,groovy] ----- -> gradle -q test -include::{snippetsPath}/buildlifecycle/buildProjectEvaluateEvents/tests-groovy/buildProjectEvaluateEvents.groovy.out[] ----- -[source.multi-language-sample,kotlin] ----- -> gradle -q test -include::{snippetsPath}/buildlifecycle/buildProjectEvaluateEvents/tests-kotlin/buildProjectEvaluateEvents.kotlin.out[] ----- - To receive these events via a listener instead of a closure, add a link:{javadocPath}/org/gradle/api/ProjectEvaluationListener.html[ProjectEvaluationListener] to a build's link:{groovyDslPath}/org.gradle.api.invocation.Gradle.html[Gradle] instance. === Task Execution Graph Assembly diff --git a/subprojects/docs/src/snippets/buildlifecycle/buildProjectEvaluateEvents/groovy/build.gradle b/subprojects/docs/src/snippets/buildlifecycle/buildProjectEvaluateEvents/groovy/build.gradle deleted file mode 100644 index d7db714280b0..000000000000 --- a/subprojects/docs/src/snippets/buildlifecycle/buildProjectEvaluateEvents/groovy/build.gradle +++ /dev/null @@ -1,11 +0,0 @@ -// tag::evaluate-events[] -gradle.afterProject { project -> - if (project.state.failure) { - println "Evaluation of $project FAILED" - } else { - println "Evaluation of $project succeeded" - } -} -// end::evaluate-events[] - -tasks.register('test') diff --git a/subprojects/docs/src/snippets/buildlifecycle/buildProjectEvaluateEvents/groovy/project-b.gradle b/subprojects/docs/src/snippets/buildlifecycle/buildProjectEvaluateEvents/groovy/project-b.gradle deleted file mode 100644 index e009d10d47a6..000000000000 --- a/subprojects/docs/src/snippets/buildlifecycle/buildProjectEvaluateEvents/groovy/project-b.gradle +++ /dev/null @@ -1 +0,0 @@ -throw new RuntimeException('broken') \ No newline at end of file diff --git a/subprojects/docs/src/snippets/buildlifecycle/buildProjectEvaluateEvents/groovy/settings.gradle b/subprojects/docs/src/snippets/buildlifecycle/buildProjectEvaluateEvents/groovy/settings.gradle deleted file mode 100644 index 0eb9cd57f0b4..000000000000 --- a/subprojects/docs/src/snippets/buildlifecycle/buildProjectEvaluateEvents/groovy/settings.gradle +++ /dev/null @@ -1,5 +0,0 @@ -rootProject.name = 'build-project-evaluate-events' - -include 'project-a', 'project-b' - -project(':project-b').buildFileName = '../project-b.gradle' diff --git a/subprojects/docs/src/snippets/buildlifecycle/buildProjectEvaluateEvents/kotlin/build.gradle.kts b/subprojects/docs/src/snippets/buildlifecycle/buildProjectEvaluateEvents/kotlin/build.gradle.kts deleted file mode 100644 index aa9a8c17cfb8..000000000000 --- a/subprojects/docs/src/snippets/buildlifecycle/buildProjectEvaluateEvents/kotlin/build.gradle.kts +++ /dev/null @@ -1,11 +0,0 @@ -// tag::evaluate-events[] -gradle.afterProject { - if (state.failure != null) { - println("Evaluation of $project FAILED") - } else { - println("Evaluation of $project succeeded") - } -} -// end::evaluate-events[] - -tasks.register("test") diff --git a/subprojects/docs/src/snippets/buildlifecycle/buildProjectEvaluateEvents/kotlin/project-b.gradle.kts b/subprojects/docs/src/snippets/buildlifecycle/buildProjectEvaluateEvents/kotlin/project-b.gradle.kts deleted file mode 100644 index 2cf738167500..000000000000 --- a/subprojects/docs/src/snippets/buildlifecycle/buildProjectEvaluateEvents/kotlin/project-b.gradle.kts +++ /dev/null @@ -1 +0,0 @@ -throw RuntimeException("broken") diff --git a/subprojects/docs/src/snippets/buildlifecycle/buildProjectEvaluateEvents/kotlin/settings.gradle.kts b/subprojects/docs/src/snippets/buildlifecycle/buildProjectEvaluateEvents/kotlin/settings.gradle.kts deleted file mode 100644 index a261d023724e..000000000000 --- a/subprojects/docs/src/snippets/buildlifecycle/buildProjectEvaluateEvents/kotlin/settings.gradle.kts +++ /dev/null @@ -1,5 +0,0 @@ -rootProject.name = "build-project-evaluate-events" - -include("project-a", "project-b") - -project(":project-b").buildFileName = "../project-b.gradle.kts" diff --git a/subprojects/docs/src/snippets/buildlifecycle/buildProjectEvaluateEvents/tests-common/buildProjectEvaluateEventsSanityCheck.sample.conf b/subprojects/docs/src/snippets/buildlifecycle/buildProjectEvaluateEvents/tests-common/buildProjectEvaluateEventsSanityCheck.sample.conf deleted file mode 100644 index 377bc1793607..000000000000 --- a/subprojects/docs/src/snippets/buildlifecycle/buildProjectEvaluateEvents/tests-common/buildProjectEvaluateEventsSanityCheck.sample.conf +++ /dev/null @@ -1,3 +0,0 @@ -executable: gradle -args: help -expect-failure: true diff --git a/subprojects/docs/src/snippets/buildlifecycle/buildProjectEvaluateEvents/tests-groovy/buildProjectEvaluateEvents.groovy.out b/subprojects/docs/src/snippets/buildlifecycle/buildProjectEvaluateEvents/tests-groovy/buildProjectEvaluateEvents.groovy.out deleted file mode 100644 index 73ccb8476fce..000000000000 --- a/subprojects/docs/src/snippets/buildlifecycle/buildProjectEvaluateEvents/tests-groovy/buildProjectEvaluateEvents.groovy.out +++ /dev/null @@ -1,21 +0,0 @@ -Evaluation of root project 'build-project-evaluate-events' succeeded -Evaluation of project ':project-a' succeeded -Evaluation of project ':project-b' FAILED - -FAILURE: Build failed with an exception. - -* Where: -Build file '/home/user/gradle/samples/project-b.gradle' line: 1 - -* What went wrong: -A problem occurred evaluating project ':project-b'. -> broken - -* 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 - -BUILD FAILED in 0s diff --git a/subprojects/docs/src/snippets/buildlifecycle/buildProjectEvaluateEvents/tests-groovy/buildProjectEvaluateEvents.groovy.sample.conf b/subprojects/docs/src/snippets/buildlifecycle/buildProjectEvaluateEvents/tests-groovy/buildProjectEvaluateEvents.groovy.sample.conf deleted file mode 100644 index cfd3bc9b0277..000000000000 --- a/subprojects/docs/src/snippets/buildlifecycle/buildProjectEvaluateEvents/tests-groovy/buildProjectEvaluateEvents.groovy.sample.conf +++ /dev/null @@ -1,6 +0,0 @@ -executable: gradle -args: test -flags: --quiet -expect-failure: true -expected-output-file: buildProjectEvaluateEvents.groovy.out -allow-additional-output: true diff --git a/subprojects/docs/src/snippets/buildlifecycle/buildProjectEvaluateEvents/tests-kotlin/buildProjectEvaluateEvents.kotlin.out b/subprojects/docs/src/snippets/buildlifecycle/buildProjectEvaluateEvents/tests-kotlin/buildProjectEvaluateEvents.kotlin.out deleted file mode 100644 index a1f719b766a0..000000000000 --- a/subprojects/docs/src/snippets/buildlifecycle/buildProjectEvaluateEvents/tests-kotlin/buildProjectEvaluateEvents.kotlin.out +++ /dev/null @@ -1,20 +0,0 @@ -Evaluation of root project 'build-project-evaluate-events' succeeded -Evaluation of project ':project-a' succeeded -Evaluation of project ':project-b' FAILED - -FAILURE: Build failed with an exception. - -* Where: -Build file '/home/user/gradle/samples/project-b.gradle.kts' line: 1 - -* What went wrong: -broken - -* 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 - -BUILD FAILED in 0s diff --git a/subprojects/docs/src/snippets/buildlifecycle/buildProjectEvaluateEvents/tests-kotlin/buildProjectEvaluateEvents.kotlin.sample.conf b/subprojects/docs/src/snippets/buildlifecycle/buildProjectEvaluateEvents/tests-kotlin/buildProjectEvaluateEvents.kotlin.sample.conf deleted file mode 100644 index 3f84b02cbe70..000000000000 --- a/subprojects/docs/src/snippets/buildlifecycle/buildProjectEvaluateEvents/tests-kotlin/buildProjectEvaluateEvents.kotlin.sample.conf +++ /dev/null @@ -1,6 +0,0 @@ -executable: gradle -args: test -flags: --quiet -expect-failure: true -expected-output-file: buildProjectEvaluateEvents.kotlin.out -allow-additional-output: true diff --git a/subprojects/docs/src/snippets/buildlifecycle/projectEvaluateEvents/groovy/build.gradle b/subprojects/docs/src/snippets/buildlifecycle/projectEvaluateEvents/groovy/build.gradle index 9f0982b793ef..1b72f1281582 100644 --- a/subprojects/docs/src/snippets/buildlifecycle/projectEvaluateEvents/groovy/build.gradle +++ b/subprojects/docs/src/snippets/buildlifecycle/projectEvaluateEvents/groovy/build.gradle @@ -1,18 +1,17 @@ // tag::after-evaluate[] -allprojects { - afterEvaluate { project -> - if (project.hasTests) { - println "Adding test task to $project" - project.task('test') { - doLast { - println "Running tests for $project" - } +gradle.beforeProject { + ext.hasTests = false +} + +gradle.afterProject { + if (project.hasTests) { + def projectString = project.toString() + println "Adding test task to $projectString" + project.task('test') { + doLast { + println "Running tests for $projectString" } } } } // end::after-evaluate[] - -allprojects { - ext.hasTests = false -} diff --git a/subprojects/docs/src/snippets/buildlifecycle/projectEvaluateEvents/kotlin/build.gradle.kts b/subprojects/docs/src/snippets/buildlifecycle/projectEvaluateEvents/kotlin/build.gradle.kts index e4625bf4a22d..1637f1361260 100644 --- a/subprojects/docs/src/snippets/buildlifecycle/projectEvaluateEvents/kotlin/build.gradle.kts +++ b/subprojects/docs/src/snippets/buildlifecycle/projectEvaluateEvents/kotlin/build.gradle.kts @@ -1,15 +1,16 @@ // tag::after-evaluate[] -allprojects { +gradle.beforeProject { // Set a default value extra["hasTests"] = false +} - afterEvaluate { - if (extra["hasTests"] as Boolean) { - println("Adding test task to $project") - tasks.register("test") { - doLast { - println("Running tests for $project") - } +gradle.afterProject { + if (extra["hasTests"] as Boolean) { + val projectString = project.toString() + println("Adding test task to $projectString") + tasks.register("test") { + doLast { + println("Running tests for $projectString") } } } From 4e3fe3f79cd291c590bb37a3c6531310f3f46832 Mon Sep 17 00:00:00 2001 From: nate contino Date: Mon, 24 Oct 2022 09:43:49 -0400 Subject: [PATCH 19/24] Update subprojects/docs/src/docs/userguide/authoring-builds/build_lifecycle.adoc (cherry picked from commit 55af8eda8a979ab68d728e7674958336222bc6ee) Signed-off-by: Julia Boes --- .../src/docs/userguide/authoring-builds/build_lifecycle.adoc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/subprojects/docs/src/docs/userguide/authoring-builds/build_lifecycle.adoc b/subprojects/docs/src/docs/userguide/authoring-builds/build_lifecycle.adoc index ea9c91564698..0ca4e58b3244 100644 --- a/subprojects/docs/src/docs/userguide/authoring-builds/build_lifecycle.adoc +++ b/subprojects/docs/src/docs/userguide/authoring-builds/build_lifecycle.adoc @@ -23,8 +23,9 @@ Additionally, this page explains how you can react to events of the lifecycle us == Task Graphs -Some build tools assemble a task graph lazily, as they execute tasks. -Gradle builds the complete task graph eagerly, before executing any task. +Some build tools assemble a task graph as they execute tasks. +Gradle builds the task graph before executing any task. +With configuration avoidance, Gradle skips configuration for tasks that aren't part of the current build. Within each project, tasks form a http://en.wikipedia.org/wiki/Directed_acyclic_graph[Directed Acyclic Graph] (DAG). From 1a661efa59ca9383ad0becaf709c153cb32cd68a Mon Sep 17 00:00:00 2001 From: nate contino Date: Mon, 24 Oct 2022 22:24:02 -0400 Subject: [PATCH 20/24] Switch example to ExtraProperties (cherry picked from commit e21a89a3b409aa23ec8825675ef1c2f7afbff670) Signed-off-by: Julia Boes --- .../buildlifecycle/projectEvaluateEvents/groovy/build.gradle | 4 ++-- .../projectEvaluateEvents/kotlin/build.gradle.kts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/subprojects/docs/src/snippets/buildlifecycle/projectEvaluateEvents/groovy/build.gradle b/subprojects/docs/src/snippets/buildlifecycle/projectEvaluateEvents/groovy/build.gradle index 1b72f1281582..205079b89f32 100644 --- a/subprojects/docs/src/snippets/buildlifecycle/projectEvaluateEvents/groovy/build.gradle +++ b/subprojects/docs/src/snippets/buildlifecycle/projectEvaluateEvents/groovy/build.gradle @@ -1,10 +1,10 @@ // tag::after-evaluate[] gradle.beforeProject { - ext.hasTests = false + project.ext.set("hasTests", false) } gradle.afterProject { - if (project.hasTests) { + if (project.ext.has("hasTests") && project.ext.get("hasTests")) { def projectString = project.toString() println "Adding test task to $projectString" project.task('test') { diff --git a/subprojects/docs/src/snippets/buildlifecycle/projectEvaluateEvents/kotlin/build.gradle.kts b/subprojects/docs/src/snippets/buildlifecycle/projectEvaluateEvents/kotlin/build.gradle.kts index 1637f1361260..6eb0a83dc3a5 100644 --- a/subprojects/docs/src/snippets/buildlifecycle/projectEvaluateEvents/kotlin/build.gradle.kts +++ b/subprojects/docs/src/snippets/buildlifecycle/projectEvaluateEvents/kotlin/build.gradle.kts @@ -1,11 +1,11 @@ // tag::after-evaluate[] gradle.beforeProject { // Set a default value - extra["hasTests"] = false + project.ext.set("hasTests", false) } gradle.afterProject { - if (extra["hasTests"] as Boolean) { + if (project.ext.has("hasTests") && project.ext.get("hasTests")) { val projectString = project.toString() println("Adding test task to $projectString") tasks.register("test") { From 99e3bf970262c204218219ddc7d26b193b7ed5bc Mon Sep 17 00:00:00 2001 From: nate contino Date: Wed, 26 Oct 2022 12:54:18 -0400 Subject: [PATCH 21/24] Make project closure arg explicit (cherry picked from commit 2c24e033bc1668adaba72a1fa9b0d550a31756a0) Signed-off-by: Julia Boes --- .../buildlifecycle/projectEvaluateEvents/groovy/build.gradle | 4 ++-- .../projectEvaluateEvents/kotlin/build.gradle.kts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/subprojects/docs/src/snippets/buildlifecycle/projectEvaluateEvents/groovy/build.gradle b/subprojects/docs/src/snippets/buildlifecycle/projectEvaluateEvents/groovy/build.gradle index 205079b89f32..dfb61f8fc8eb 100644 --- a/subprojects/docs/src/snippets/buildlifecycle/projectEvaluateEvents/groovy/build.gradle +++ b/subprojects/docs/src/snippets/buildlifecycle/projectEvaluateEvents/groovy/build.gradle @@ -1,9 +1,9 @@ // tag::after-evaluate[] -gradle.beforeProject { +gradle.beforeProject { project -> project.ext.set("hasTests", false) } -gradle.afterProject { +gradle.afterProject { project -> if (project.ext.has("hasTests") && project.ext.get("hasTests")) { def projectString = project.toString() println "Adding test task to $projectString" diff --git a/subprojects/docs/src/snippets/buildlifecycle/projectEvaluateEvents/kotlin/build.gradle.kts b/subprojects/docs/src/snippets/buildlifecycle/projectEvaluateEvents/kotlin/build.gradle.kts index 6eb0a83dc3a5..1d16b4f716c5 100644 --- a/subprojects/docs/src/snippets/buildlifecycle/projectEvaluateEvents/kotlin/build.gradle.kts +++ b/subprojects/docs/src/snippets/buildlifecycle/projectEvaluateEvents/kotlin/build.gradle.kts @@ -1,10 +1,10 @@ // tag::after-evaluate[] -gradle.beforeProject { +gradle.beforeProject { project -> // Set a default value project.ext.set("hasTests", false) } -gradle.afterProject { +gradle.afterProject { project -> if (project.ext.has("hasTests") && project.ext.get("hasTests")) { val projectString = project.toString() println("Adding test task to $projectString") From e562276587ec2b31b08e32108a2dfc292d3292d2 Mon Sep 17 00:00:00 2001 From: nate contino Date: Wed, 26 Oct 2022 14:27:09 -0400 Subject: [PATCH 22/24] Remove explicit project arg from kotlin (cherry picked from commit 9b79e546c5c46008e78d954e3747c039cc0550bb) Signed-off-by: Julia Boes --- .../projectEvaluateEvents/kotlin/build.gradle.kts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/subprojects/docs/src/snippets/buildlifecycle/projectEvaluateEvents/kotlin/build.gradle.kts b/subprojects/docs/src/snippets/buildlifecycle/projectEvaluateEvents/kotlin/build.gradle.kts index 1d16b4f716c5..6eb0a83dc3a5 100644 --- a/subprojects/docs/src/snippets/buildlifecycle/projectEvaluateEvents/kotlin/build.gradle.kts +++ b/subprojects/docs/src/snippets/buildlifecycle/projectEvaluateEvents/kotlin/build.gradle.kts @@ -1,10 +1,10 @@ // tag::after-evaluate[] -gradle.beforeProject { project -> +gradle.beforeProject { // Set a default value project.ext.set("hasTests", false) } -gradle.afterProject { project -> +gradle.afterProject { if (project.ext.has("hasTests") && project.ext.get("hasTests")) { val projectString = project.toString() println("Adding test task to $projectString") From 9404ac1bbb92f592147d050c149639d2b946c714 Mon Sep 17 00:00:00 2001 From: nate contino Date: Wed, 26 Oct 2022 16:09:23 -0400 Subject: [PATCH 23/24] Fix type inference failure (cherry picked from commit cf0b0d4c11c8293bd619806e7d0f5b1375045d76) Signed-off-by: Julia Boes --- .../buildlifecycle/projectEvaluateEvents/groovy/build.gradle | 2 +- .../projectEvaluateEvents/kotlin/build.gradle.kts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/subprojects/docs/src/snippets/buildlifecycle/projectEvaluateEvents/groovy/build.gradle b/subprojects/docs/src/snippets/buildlifecycle/projectEvaluateEvents/groovy/build.gradle index dfb61f8fc8eb..a7492360fa18 100644 --- a/subprojects/docs/src/snippets/buildlifecycle/projectEvaluateEvents/groovy/build.gradle +++ b/subprojects/docs/src/snippets/buildlifecycle/projectEvaluateEvents/groovy/build.gradle @@ -4,7 +4,7 @@ gradle.beforeProject { project -> } gradle.afterProject { project -> - if (project.ext.has("hasTests") && project.ext.get("hasTests")) { + if (project.ext.has("hasTests") && project.ext.get("hasTests") as Boolean) { def projectString = project.toString() println "Adding test task to $projectString" project.task('test') { diff --git a/subprojects/docs/src/snippets/buildlifecycle/projectEvaluateEvents/kotlin/build.gradle.kts b/subprojects/docs/src/snippets/buildlifecycle/projectEvaluateEvents/kotlin/build.gradle.kts index 6eb0a83dc3a5..7881016404c9 100644 --- a/subprojects/docs/src/snippets/buildlifecycle/projectEvaluateEvents/kotlin/build.gradle.kts +++ b/subprojects/docs/src/snippets/buildlifecycle/projectEvaluateEvents/kotlin/build.gradle.kts @@ -5,7 +5,7 @@ gradle.beforeProject { } gradle.afterProject { - if (project.ext.has("hasTests") && project.ext.get("hasTests")) { + if (project.ext.has("hasTests") && project.ext.get("hasTests") as Boolean) { val projectString = project.toString() println("Adding test task to $projectString") tasks.register("test") { From 1e69399740784dc58452b5f6791e76e6f1a8bf8b Mon Sep 17 00:00:00 2001 From: nate contino Date: Mon, 24 Oct 2022 09:43:20 -0400 Subject: [PATCH 24/24] Update subprojects/docs/src/docs/userguide/authoring-builds/build_lifecycle.adoc (cherry picked from commit 0c7c1a50735d334ca7aaab8fda429f967aa0dc9b) Signed-off-by: Julia Boes --- .../src/docs/userguide/authoring-builds/build_lifecycle.adoc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/subprojects/docs/src/docs/userguide/authoring-builds/build_lifecycle.adoc b/subprojects/docs/src/docs/userguide/authoring-builds/build_lifecycle.adoc index 0ca4e58b3244..7c1fa55974a4 100644 --- a/subprojects/docs/src/docs/userguide/authoring-builds/build_lifecycle.adoc +++ b/subprojects/docs/src/docs/userguide/authoring-builds/build_lifecycle.adoc @@ -63,6 +63,9 @@ include::sample[dir="snippets/buildlifecycle/basic/groovy",files="settings.gradl include::sample[dir="snippets/buildlifecycle/basic/kotlin",files="settings.gradle.kts[];build.gradle.kts[]"] ==== +The following command configures and executes the `test` and `testBoth` tasks specified above. +Because Gradle only configures requested tasks and their dependencies, the `configured` task never configures. + [source.multi-language-sample,groovy] ---- > gradle test testBoth