Reputation: 373
I read the gradle was written in groovy.
However my build.gradle file doesn't look like groovy.
Infact it doesn't look like a language at all.
Here's my build.gradle file:
apply plugin: 'com.android.application'
android {
compileSdkVersion 25
buildToolsVersion "25.0.2"
defaultConfig {
applicationId "com.israelkariti.location2_1"
minSdkVersion 14
targetSdkVersion 25
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:25.3.1'
compile 'com.android.support.constraint:constraint-layout:1.0.0-beta4'
compile 'com.google.android.gms:play-services-maps:10.2.1'
testCompile 'junit:junit:4.12'
}
Can someone please explain to me what's up with this syntax.
How does that syntax is a Groovy code?
And if i m missing something big than please elaborate on how this thing work.
thank you
Upvotes: 3
Views: 1054
Reputation: 14493
Well, Gradle adds some magic for its DSL, but technically speaking is each Gradle script fully valid Groovy.
To understand all the things like dependencies
, apply plugin:
and so on, we need to learn about the different types of Gradle scripts:
build.gradle
)settings.gradle
)init.gradle
)All these script are executed in different scopes, since they are "applied on" different objects. Gradle calls this behaviour "attaching a delegate object".
For build scripts (like the one, you asked about), this object is a Project
. Now lets analyze your Gradle script:
apply plugin: 'com.android.application'
The Project
interface extends the PluginAware
interface, which defines an apply
method taking a Map<String,?>
. In Groovy, the map notation is [key:value, ...]
, brackets can be omitted and map keys of type String
are not written in quotes. So, plugin: 'com.android.application'
is nothing more but a Groovy map and its handed to the apply
method.
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
...
}
I'll continue with this part and finish with the android
part, because its easier to understand this way:
dependencies
is not a Gradle keyword, its simply the name of a method of the already mentioned Project
interface. This method takes a Closure
, which is wrapped inside the braces. Normal method call brackets are omitted again. The closure is executed on a DependencyHandler
object. Now we just add dependencies to our configurations. We could use the add
method and pass a configuration name and a dependency notation (and optionally a new closure).
Here starts the Gradle magic. For each existing configuration in the project's ConfigurationContainer
, a new method with the name of the respective configuration is added to the DependencyHandler
, so we can simply use this method instead of using add
all the time. When developing for Java, these configurations and therefor methods are compile
, runtime
, testCompile
(among others). The fileTree
is, once again, just a method of the Project
interface.
android {
compileSdkVersion 25
...
}
The methods defined by the Project
interface are not the only available methods. Gradle plugins (like the Android plugin you are using) can add extensions or conventions. This way, properties and methods can be called like they would belong to the Project
object. This is how the android
part can be configured via a closure right in the build script.
Inside the android
closure, some additional Gradle magic happens. You probably know that, in Groovy, one can omit the get
or set
part and access properties directly (while possible getters or setters are still called). Gradle also adds a method for each property with the name of the property, which can be used as setter. This way, we can call the compileSdkVersion
method to set the compileSdkVersion
property. Once again, brackets are omitted. This is just some syntactic sugar, which lets us omit the assignment operator.
Whenever you start a new braces level, you basically use a closure to configure an object. Sometimes a new object is created, sometimes an existing property is used. Sometimes, you need to read the documentation to understand what's happening exactly.
Upvotes: 3