4

So a build.gradle file is basically a Groovy closure whose delegate is a Project object, and it has methods such as dependencies and repositories to which we pass additional closures. How is it that a statement like:

dependencies{
  testCompile 'junit:junit:4.12'
}

triggers a DependencyHandler.add​(String configurationName, Object dependencyNotation) call? Is this some special Groovy feature?

Bowen Jin
  • 153
  • 3
  • please be more clear of what you are asking – Akshay Mulgavkar Aug 23 '19 at 04:31
  • See [here](https://stackoverflow.com/a/56926678/1089967) where I attempt to run through most of the "magic" under the hood in a gradle script – lance-java Aug 23 '19 at 06:05
  • @lance-java so in the above code if I understand correctly, the closure should have a delegate that is an object of type DependencyHandler, thus testCompile should be a method on that object, however in the docs for DependencyHandler I do not see a method called testCompile or testImplementation https://docs.gradle.org/current/javadoc/org/gradle/api/artifacts/dsl/DependencyHandler.html – Bowen Jin Aug 31 '19 at 21:02
  • Correct so far. You won't find the "testCompile" method in the docs because it is handled by a "methodMissing" handler on the DependencyHandler implementation. This will ultimately use the method name ("testCompile" in this case) to add dependencies to a `Configuration` which is named "testCompile" – lance-java Aug 31 '19 at 21:11

1 Answers1

1

Following on from the comments section where I suggest this explanation of some of the common "magic" in Groovy scripts

In earlier versions of Gradle they were using methodMissing to intercept missing methods. Looking at the more recent sources I believe they are now using some of Groovy's dynamic class features to achieve similar behavior.

If you want to trace through the magic in the Gradle sources you should look at

lance-java
  • 25,497
  • 4
  • 59
  • 101