Gradle Extra Properties: Difference between revisions

From NovaOrdis Knowledge Base
Jump to navigation Jump to search
No edit summary
 
(10 intermediate revisions by the same user not shown)
Line 1: Line 1:
=External=
* https://docs.gradle.org/current/userguide/writing_build_scripts.html#sec:extra_properties
=Internal=
=Internal=
* [[Gradle Runtime and Project Configuration#Gradle_Extra_Properties|Gradle Runtime and Project Configuration]]
* [[Gradle Properties - Runtime and Project Configuration#Gradle_Extra_Properties|Gradle Properties - Runtime and Project Configuration]]
* [[Gradle_Project_Coordinates,_State_and_Configured_Properties#Extra_Properties|Gradle Project Coordinates, State and Configured Properties]]
 
=Overview=
=Overview=
An '''extra property''' is a property that can be declared on most model object instances available to the closure being executed. Extra properties allow defining variables that are used multiple times within the same script, such as a file that is referred from multiple locations of the build script. An extra property is equivalent to a user-defined variable.  
An '''extra property''' is a property that can be declared on most model object instances available to the closure being executed. Extra properties allow defining variables that are used multiple times within the same script, such as a file that is referred from multiple locations of the build script. An extra property is equivalent to a user-defined variable.  
Line 6: Line 11:
The extra property name cannot contain dots, dashes, etc.
The extra property name cannot contain dots, dashes, etc.


Internally, extra properties are stored as key-value pairs in a map, associated with the model object instance. For [[settings.gradle]], the available model objects are [[Gradle_Settings|Settings]] and [[Org.gradle.api.invocation.Gradle|Gradle]] (ProjectDescriptor does not allow defining extra properties). They allow defining extra properties at the [[Gradle_Concepts#Initialization|build initialization phase]]. [[Gradle_Settings|Settings]] allows defining extra properties, but those properties cannot be easily accessed at [[Gradle_Concepts#Configuration|configuration]] and [[Gradle_Concepts#Execution|execution]] phase, so the best candidate for defining extra properties during the configuration phase is [[Org.gradle.api.invocation.Gradle|Gradle]].
Internally, extra properties are stored as key-value pairs in a map, associated with the model object instance. For [[settings.gradle]], the available model objects are [[Gradle_Settings|Settings]] and [[Org.gradle.api.invocation.Gradle|Gradle]] (ProjectDescriptor does not allow defining extra properties). They allow defining extra properties at the [[Gradle_Concepts#Initialization|build initialization phase]]. [[Gradle_Settings|Settings]] allows defining extra properties, but those properties cannot be easily accessed at [[Gradle_Concepts#Configuration|configuration]] and [[Gradle_Concepts#Execution|execution]] phase, so the best candidate for defining extra properties during the configuration phase is [[Org.gradle.api.invocation.Gradle|Gradle]], that allows accessing extra properties with the gradle.<property-name> syntax.
 
For [[build.gradle]], extra properties can be defined on any available object model instances. The most common object to define properties on is the project instance. <span id='Project_Extra_Properties'></span>The extra properties defined on the project instance are considered [[Gradle_Project_Coordinates,_State_and_Configured_Properties#Extra_Properties|project properties]], alongside other project properties provided with [[Gradle_Project_Coordinates,_State_and_Configured_Properties#-P_Command-Line_Options|-P on command line]] or in [[gradle.properties#Overview|gradle.properties]].


For [[build.gradle]], extra properties can be defined on any available object model instances. The most common object to define properties on is the project instance. <span id='Project_Extra_Properties'></span><font color=darkgray>The the extra properties defined on the project instance are known as [[Gradle Project Properties|project properties]]</font>. Extra properties on a project are visible from its sub-projects, [[#Extra_Properties_and_Multi-Project_Builds|but not vice-versa]].
Extra properties on a project are visible from its sub-projects, [[#Extra_Properties_and_Multi-Project_Builds|but not vice-versa]].


Extra properties are declared using an "ext" namespace closure applied to the model object we intend to declare the extra properties for:
Extra properties are declared using an "ext" namespace closure applied to the model object we intend to declare the extra properties for:
Line 48: Line 55:
}
}
</syntaxhighlight>
</syntaxhighlight>
For the above example, <syntaxhighlight lang='text'>./gradlew displayColor</syntaxhighlight> will display "red" and "blue" respectively.
For the above example, <syntaxhighlight lang='text'>./gradlew displayColor</syntaxhighlight> will display "red" (for project) and "blue" (for gradle).


Extra properties can be accessed from anywhere their owning object can be accessed. This gives them a wider scope than [[Gradle Local Variables|local variables]].
Extra properties can be accessed from anywhere their owning object can be accessed. This gives them a wider scope than [[Gradle Local Variables|local variables]].
Line 73: Line 80:
</syntaxhighlight>
</syntaxhighlight>
which shows that the sub-project build script is executed after the root project build script is executed.
which shows that the sub-project build script is executed after the root project build script is executed.
=Programmatic Access to Extra Properties=
Programmatic access to extra properties is useful if developing [[Extending_Gradle_with_a_Custom_Enhanced_Task#Programmatic_Access_to_Properties|custom enhanced tasks]] or plugins.
<syntaxhighlight lang='groovy'>
getProject().getProperties().get("myProperty")
</syntaxhighlight>

Latest revision as of 22:39, 10 November 2020

External

Internal

Overview

An extra property is a property that can be declared on most model object instances available to the closure being executed. Extra properties allow defining variables that are used multiple times within the same script, such as a file that is referred from multiple locations of the build script. An extra property is equivalent to a user-defined variable.

The extra property name cannot contain dots, dashes, etc.

Internally, extra properties are stored as key-value pairs in a map, associated with the model object instance. For settings.gradle, the available model objects are Settings and Gradle (ProjectDescriptor does not allow defining extra properties). They allow defining extra properties at the build initialization phase. Settings allows defining extra properties, but those properties cannot be easily accessed at configuration and execution phase, so the best candidate for defining extra properties during the configuration phase is Gradle, that allows accessing extra properties with the gradle.<property-name> syntax.

For build.gradle, extra properties can be defined on any available object model instances. The most common object to define properties on is the project instance. The extra properties defined on the project instance are considered project properties, alongside other project properties provided with -P on command line or in gradle.properties.

Extra properties on a project are visible from its sub-projects, but not vice-versa.

Extra properties are declared using an "ext" namespace closure applied to the model object we intend to declare the extra properties for:

ext {
  color = 'blue'
}

An equivalent assignment is:

gradle.ext.color = 'blue'

or

project.ext.color = 'blue'

A benefit of using the closure over the other syntax is that multiple assignments can be declared compactly:

ext {
  color = 'blue'
  shape = 'square'
  size = 10
}

By requiring special syntax for adding a property, Gradle can fail fast when an attempt is made to set an extra property but the property name is misspelled or the property does not exist. Note that the "ext" script block or project.ext syntax must be used only for the declaration of the property, for subsequent access the extra property can be looked up directly on the project instance: once the properties have been declared, they can be read and set like predefined properties.

project.ext.color = 'green'
project.color = 'red' // project.ext.color and project.color are equivalent after property initialization

task displayColor {
  doLast {
    println project.ext.color
    println project.color
    println color
    println gradle.color
  }
}

For the above example,

./gradlew displayColor

will display "red" (for project) and "blue" (for gradle).

Extra properties can be accessed from anywhere their owning object can be accessed. This gives them a wider scope than local variables.

Extra Properties and Multi-Project Builds

The extra properties are not available and throw an execution error if they are accessed before are defined. That is why a multi-project build that declares extra properties in sub-projects' build.gradle and attempts to use them in the root project build.gradle will fail at the configuration phase:

BUILD FAILED in 3s
...
* Where:
Build file '.../root-project/build.gradle' line: 17
 
* What went wrong:
A problem occurred evaluating root project 'root-project'.
> Could not get unknown property 'myProperty' for project ':sub-project-A' of type org.gradle.api.Project.

The error occurs even "myProperty" was declared in sub-project-A's build.gradle, because the build file was not evaluated at the time the root project file is executed. If we log build.gradle evaluation, we get something like:

exiting root project build.gradle ....
entering sub-project-A build.gradle ....
exiting sub-project-A build.gradle ....

which shows that the sub-project build script is executed after the root project build script is executed.

Programmatic Access to Extra Properties

Programmatic access to extra properties is useful if developing custom enhanced tasks or plugins.

getProject().getProperties().get("myProperty")