In the tutorial in Chapter 4, Build Script Basics we used, for example, the
task()
method. Where does this method come from? We said earlier that the build script
defines a project in Gradle. For Gradle, this means that it creates an instance of
Project
and associates this Project
object with
the build script. As the build script executes, it configures this Project
object.
Any method you call in your build script, which is not defined
in the build script, is delegated to the Project
object.
Any property you access in your build script, which is not defined
in the build script, is delegated to the Project
object.
Let's try this out and try to access the name
property of the
Project
object.
Example 12.1. Accessing property of the Project object
build.gradle
task check << { println name println project.name }
Output of gradle -q check
> gradle -q check projectApi projectApi
Both println
statements print out the same property. The first uses auto-delegation to
the Project
object, for properties not defined in the build script. The other
statement uses the project
property available to any build script, which returns the
associated Project
object. Only if you define a property or a method which has the
same name as a member of the Project
object, you need to use the project
property.
Have a look at the
Project
API to find out more about project
properties and methods.
The Project
object provides some standard properties, which are available in
your build script. The following table lists a few of the commonly used ones.
Table 12.1. Project Properties
Name | Type | Default Value |
project
|
Project
|
The Project instance |
name
|
String
|
The name of the directory containing the build script. |
path
|
String
|
The absolute path of the project. |
buildFile
|
File
|
The build script. |
projectDir
|
File
|
The directory containing the build script. |
buildDirName
|
String
|
build
|
buildDir
|
File
|
|
group
|
Object
|
unspecified
|
version
|
Object
|
unspecified
|
ant
|
AntBuilder
|
An AntBuilder instance |
Below is a sample build which demonstrates some of these properties.
Example 12.2. Project properties
Build layout
projectCoreProperties/ build.gradle subProject/ build.gradle
build.gradle
task check << { allprojects { println "project path $path" println " project name = $name" println " project dir = '${rootProject.relativePath(projectDir)}'" println " build file = '${rootProject.relativePath(buildFile)}'" println " build dir = '${rootProject.relativePath(buildDir)}'" } }
Output of gradle -q check
> gradle -q check project path : project name = projectCoreProperties project dir = '' build file = 'build.gradle' build dir = 'build' project path :subProject project name = subProject project dir = 'subProject' build file = 'subProject/build.gradle' build dir = 'subProject/build'
Many of the methods of the Project
instance return task objects. We have already seen some ways that you can
use task objects in Chapter 4, Build Script Basics.
Look here to learn more about
Task
.
The project and the task API constitute the core layer of Gradle and provide all the possible interaction options with this layer. [8] This core-layer constitutes a language for dependency based programming. [9] There are many other projects providing such a language. There is Ant for Java, Rake and Rant for Ruby, SCons for Python, the good old Make and many more. [10] We think that one thing that makes Gradle special compared to the other tools, is its strong support for applying dependency based programming on multi-project builds. We also think that just Gradle's core layer (together with its integration of the Ant tasks), provides a more convenient build system than Ant's core layer.
[8] There is more to come for this layer in the other chapters, e.g. support for multi-project builds (see Chapter 31, Multi-project Builds).
[9] Martin Fowler has written about this: http://martinfowler.com/articles/rake.html#DependencyBasedProgramming
[10] Interestingly, Maven2 is the only major build system which does not use dependency based programming.