Gradle Concepts TO DEPLETE: Difference between revisions

From NovaOrdis Knowledge Base
Jump to navigation Jump to search
 
(19 intermediate revisions by the same user not shown)
Line 3: Line 3:


=DEPLETE INTO=
=DEPLETE INTO=
{{Internal|Gradle Concepts|Gradle Concepts}}


<center>Deplete into [[Gradle Concepts]]</center>
=<span id='Build_Lifecycle_and_Gradle_Objects'></span>Build Lifecycle=
Each build run results in the instantiation of one or more of these ''core Gradle types'': the build starts with instantiation of a [[#Settings|Settings]] and a [[Gradle_Object_Instance#Overview|Gradle]] instance, then of one or more [[Gradle_Project_and_Build_Script#Overview|Projects]]. A Gradle execution results in instantiation and execution of [[#Task|task]]. Depending on the actual configuration of the build, many others objects are instantiated and used. All Gradle [https://docs.gradle.org/current/dsl/#N100CA core types are listed here].
The lifecycle of a Gradle build consists in an [[#Build_Initialization_Phase|initialization]], [[#Build_Configuration_Phase|configuration]] and an [[#Build_Execution_Phase|execution phase]]. Code can be written to react to a build's lifecycle events: {{Internal|Gradle_Project_and_Build_Script#Reacting_to_Build_Lifecycle_Events|Reacting to a Build Lifecycle Events}}
====<span id='Build_Initialization_Phase'></span>Initialization====
The build lifecycle starts with the initialization phase, when Gradle creates a [[Gradle_Settings_Script_and_Settings_Instance#Overview|Settings]] instance, then executes the [[Gradle_Settings_Script_and_Settings_Instance#Overview|settings script]], which updates the state of its [[Gradle_Settings_Script_and_Settings_Instance#Overview|Settings delegate]]. In this phase, Gradle determines which projects are going to take part in the build and creates a [[Gradle_Project_and_Build_Script#Overview|project representation]] for each of the projects, essentially defining the build's project hierarchy. The sub-projects are declared using the "include" or "includeFlat" Settings methods in  [[Gradle_Settings_Script_and_Settings_Instance#Overview|settings.gradle]].
<span id='Project_Instance_Creation'></span>The corresponding [[Gradle_Project_and_Build_Script#Overview|Project]] instances are created and arranged in the corresponding project hierarchy. Note that at the initialization phase, Project instances are not accessible from the settings script. Project data can be accessed via a [[Gradle_Settings_Script_and_Settings_Instance#ProjectDescriptor_-_Access_to_Projects_from_Settings|ProjectDescriptor]] interface instead.
====<span id='Build_Configuration_Phase'></span>Configuration====
The build continues with a configuration phase. Gradle executes the [[Gradle_Project_and_Build_Script#Overview|build.gradle]] configuration script against the [[Gradle_Project_and_Build_Script#Root_Project|root project]] instance and its [[Gradle_Project_and_Build_Script#Sub-Project|sub-projects]]. As part of the configuration sequence, [[Gradle_Plugins#Plugin_Initialization|plugins]] declared with apply(...) in the build scripts are downloaded and initialized in their corresponding [[Gradle_Settings_Script_and_Settings_Instance#Overview|Project]] instances. Note that prior to Gradle 1.4, all projects that are part of the hierarchy are configured. Gradle 1.4 and newer introduces [[Gradle_Configuration_on_Demand#Overview|configuration on demand]], that results in configuring only relevant projects.
====<span id='Build_Execution_Phase'></span>Execution====
The execution phase requires that one or more [[#Task|tasks]] is specified on command line. Gradle computes a task Directed Acyclic Graph of to be executed in order to fulfill the specified tasks, and then [[Gradle_Task#Task_Execution_Order|executes them]] honoring inter-task dependencies and insuring the fact that a task is executed only once.
=Configuration Scripts=
The configuration scripts are written in the ''Gradle build language'', which is a DSL and a Groovy extension. A build is configured by three types of configuration scripts, which together express build requirements and inform the build runtime: [[#Build_Script|build scripts]], a [[#Settings_Script|settings script]] and an [[#Init_Script|init script]].
Each of those scripts contains executable statements and script blocks, which are a special case of executable statement, consisting in a method invocation on a closure. The statements and script blocks are executed in the order in which they are declared in the script. The logic expressed in a specific script applies to its delegate object. Though syntax is similar for all three scripts, specific blocks must make sense with the delegate object. The corresponding delegate objects for all three types of configuration scripts will be described below.
::[[Image:Gradle_Configuration_Scripts.png]]
A configuration script may contain [[#Statement|statements]], [[#Script_Block|script blocks]], and any elements allowed in a Groovy script, such as method and class definitions.
<span id='Statement'></span>A '''statement''' may be a method call, property assignment and local variable definition. One of the simplest possible statements, which will be executed in the order in which is found in the script, is:
<syntaxhighlight lang='groovy'>
println 'I am here'
</syntaxhighlight>
If the delegate object has an accessor that follows Java Beans conventions, then the result of the accessor invocation can be obtained simply specifying the corresponding variable name. For example, the root project instance returned by:
<syntaxhighlight lang='java'>
public interface Settings ... {
    ProjectDescriptor getRootProject();
}
</syntaxhighlight>
can be accessed from the corresponding settings.gradle script with <tt>rootProject</tt>.
<span id='Script_Block'></span>A '''script block''' is method call that takes a configuration closure as an argument. Executing the script block results in modification of the associated delegate object, based on the content of the closure. Equivalent terminology, often used in documentation, is to delegate the closure against the target object. This means that the closure will be executed in scope of the class of the target instance. For all Groovy closures, <tt>it</tt> is the default parameter passed to the closure. A build configuration that does not declare any [[#Plugin|plugin]] has a set of standard script blocks. Plugins may, and usually do, add new script blocks.
<font color=darkgray>Example of a script block.</font>
Each configuration script implements the [https://docs.gradle.org/current/dsl/org.gradle.api.Script.html Script] interface, which exposes a number of useful methods and properties.
==Init Script==
{{Internal|Gradle_Init_Script#Overview|Init Script}}
=The Gradle Object Instance=
{{Internal|Gradle_Object_Instance#Overview|The Gradle Object Instance}}
=<span id='Artifact_Publishing'></span>Artifacts and Artifact Publishing=
=<span id='Artifact_Publishing'></span>Artifacts and Artifact Publishing=


Line 96: Line 37:


A <span id='Module_Version'></span>'''module version''' is a label that designates a distinct set of changes released as a unit. The most widely-used versioning strategy is [[Software_Development#Semantic_Versioning|semantic versioning]].
A <span id='Module_Version'></span>'''module version''' is a label that designates a distinct set of changes released as a unit. The most widely-used versioning strategy is [[Software_Development#Semantic_Versioning|semantic versioning]].
=Repository=
{{Internal|Gradle Repositories|Gradle Repositories}}
=<span id='Extension'></span>Extensions=
A Project implements [https://docs.gradle.org/current/dsl/org.gradle.api.plugins.ExtensionAware.html ExtensionAware]. Some plugins create extensions. For example, [[Gradle_Maven_Plugin#Overview|maven-plugin]] creates a "[[Gradle_Maven_Publish_Plugin#Mechanics|publishing]]" extension, the [[Gradle_Distribution_Plugin#Overview|Distribution plugin]] creates a "distributions" extension.
=<span id='Component'></span>Software Component=
A software components may be added by a [[#Plugin|plugin]]. For example the [[Gradle_Java_Plugin#Overview|Java plugin]] adds a "java" component, accessible via components.java. The artifact associated with the Java component is the generated JAR file, and the dependencies are those of the [[Gradle_Java_Plugin#runtime|runtime]] configurations. The [[Gradle_War_Plugin|War plugin]] adds a "web" software component whose artifact is the generated WAR file, with no dependencies.
The available components can be displayed with:
<syntaxhighlight lang='groovy'>
task util {
    components.each { println it.name }
}
</syntaxhighlight>


=The Gradle Wrapper=
=The Gradle Wrapper=
Line 150: Line 70:


{{Internal|Gradle Build Caching#Overview|Build Caching}}
{{Internal|Gradle Build Caching#Overview|Build Caching}}
=Configuration on Demand=
{{Internal|Gradle Configuration on Demand#Overview|Configuration on Demand}}
=Gradle Programming=
{{Internal|Gradle_Programming#Overview|Gradle Programming}}
=TO REDISTRIBUTE=
* [[Gradle Programming|Gradle Programming]]

Latest revision as of 20:49, 23 April 2021


DEPLETE INTO

Gradle Concepts

Artifacts and Artifact Publishing

A Gradle project produces artifacts, which are the files the project provides to the outside world. An artifact may be built locally by a plugin such as the Application plugin, which in turn delegates the artifact building part to Distribution plugin, or by other plugins. This creates the artifact locally, in the project build area. More details about how to configure artifact generation is available in:

Gradle Artifacts

In most cases, we want these artifacts to be pushed to external repositories, as described here:

Gradle Artifact Publishing Concepts

Module

A module is a piece of software that evolves over time. Every module has a name, and each release of a module is identified by a module version. Modules can be hosted in repositories. Modules usually are described by module metadata, which is information associate with a module. Metadata includes coordinates for locating the module in a repository (group ID, artifact name and version), information about the module's transitive dependencies, authors, etc. In Maven, the metadata file is called POM. This is an example of module metadata published into a Maven repository by a "playground.b:b:1.0" module that depends on "playground.a:a:1.0" module:

<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
    http://maven.apache.org/xsd/maven-4.0.0.xsd" 
    xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <modelVersion>4.0.0</modelVersion>
  <groupId>playground.b</groupId>
  <artifactId>b</artifactId>
  <version>1.0</version>
  <dependencies>
    <dependency>
      <groupId>playground.a</groupId>
      <artifactId>a</artifactId>
      <version>1.0</version>
      <scope>runtime</scope>
    </dependency>
  </dependencies>
</project>

A module version is a label that designates a distinct set of changes released as a unit. The most widely-used versioning strategy is semantic versioning.

The Gradle Wrapper

https://docs.gradle.org/current/userguide/gradle_wrapper.html

Gradle Wrapper is the recommended way to execute a Gradle build. The Wrapper is a script that invokes a declared version of Gradle, downloading it beforehand if necessary.

./gradlew ...

The wrapper caches the appropriate Gradle runtime under $USER_HOME/.gradle/wrapper/dists/. Using the wrapper effectively locks a specific Gradle version to the project. One of the advantages of using the Gradle wrapper is that other people that attempt to build the project do not have to have Gradle installed on their system, everything Gradle needs to run comes with the wrapper. If the code is build with AWS CodeBuild and the image used for building does not have gradle installed, or it has an older version, building the project with gradlew is an immediate solution.

Gradle Wrapper Initialization

Per-project graddle wrapper infrastructure can be created with gradle init. Spring Initializr also creates wrapper scripts during the process of Spring project initialization. For a project already operational, gradle init will detect build.gradle and it will bail out. For such situations, create a temporary directory, gradle init it, and move gradle and gradlew into the Gradle project:

mkdir tmp
cd tmp
gradle init
mv gradle gradlew <target-gradle-project>

Gradle Version

Gradle Version

The Gradle Daemon

https://docs.gradle.org/current/userguide/gradle_daemon.html

Configured with "org.gradle.daemon" and "org.gradle.daemon.idletimeout" Gradle property. On by default.

Build Caching

Build Caching