I have trouble understanding the groovy syntax in gradle.
If named parameters (in groovy) are using the :
suffix, then I assume that the code apply plugin: 'java'
means to call the function apply(plugin = 'java')
. This is strange because the function apply
is not even defined. The following gives me an error in my gradle script:
println apply.getClass()
> Could not get unknown property 'apply' for root project 'Simple' of type
org.gradle.api.Project.
So what is apply
and where is it defined? Why doesn't the code above just print the class of the apply
element?
And one other thing that is strange to me is the following:
dependencies {
compile 'org.slf4j:slf4j-api:1.7.12'
testCompile 'junit:junit:4.12'
}
The syntax suggests that the code wrapped in {}
is a closure, but what are the compile
and testCompile
elements? If it was a closure, then the code above would just return 'junit:junit:4.12'
as a string and the rest should fail to compile. It looks like it's more a definition of a map. But again, if the code above is data, then I should be able to enter it at the groovysh
shell.
groovy:000> dependencies {
compile 'org.slf4j:slf4j-api:1.7.12'
testCompile 'junit:junit:4.12'
}
groovy:001> groovy:002> groovy:003> ERROR groovy.lang.MissingMethodException:
No signature of method: groovysh_evaluate.dependencies() is applicable for argument types: (groovysh_evaluate$_run_closure1) values: [groovysh_evaluate$_run_closure1@b7c4869]
This is confusing to me. I thought that gradle scripts are just groovy scripts, but it seems that the gradle DSL adds element to the groovy language. A groovy clojure becomes a map, a function call with named parameters becomes something different.
Can someone enlighten me on this groovy DSL ;)
Gradle uses Groovy language for writing scripts.
To just use Gradle, you can go without understanding Groovy. To understand how a Gradle file syntax works, you definitely need to understand Groovy.
Gradle and Groovy are primarily classified as "Java Build" and "Languages" tools respectively. "Flexibility" is the primary reason why developers consider Gradle over the competitors, whereas "Java platform" was stated as the key factor in picking Groovy. Gradle and Groovy are both open source tools.
The Gradle build language Gradle provides a domain specific language, or DSL, for describing builds. This build language is available in Groovy and Kotlin. A Groovy build script can contain any Groovy language element. A Kotlin build script can contain any Kotlin language element.
plugin: 'java'
is a groovy map. See the Project.apply() documentation and the explanation for this syntax in the groovy documentation.
Regarding dependencies, see DependencyHandler.
Groovy is a very dynamic language, where you can actually call non-declared methods and have a handler do something based on the called method name. AFAIK, that's the trick used here. See the source code.
I'm not a groovy developer, and although I find the DSL elegant, I also find it confusing at times, because I find it hard to link some parts of the DSL to concrete methods in the documentation. But you end up understanding it and getting used to it.
compile 'org.slf4j:slf4j-api:1.7.12'
is not a map, it's a method invocation. In Groovy you can omit brackets, so the call is equivalent to
compile( 'org.slf4j:slf4j-api:1.7.12' )
Also such methods in Gradle can take the second argument:
compile( 'org.slf4j:slf4j-api:1.7.12' ){ exclude module:'log4j' }
In this case, the module:'log4j'
is a map with omitted square brackets, and the call can be rewritten as
compile( 'org.slf4j:slf4j-api:1.7.12' ){ exclude( [module:'log4j'] ) }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With