Manage dependencies in multi-module project


(Thibault Kruse) #1

Would it be useful to manage multi-module gradle dependencies in buildSrc/src/main/groovy/Dependencies.gradle ? What are the downsides?

In a multi-module gradle build, it is always complex to manage dependency versions while at the same time:

  • avoid duplicate gradle code across all modules
  • avoid duplicating same version numbers across all modules
  • avoiding + resolving transitive dependency conflicts
  • keep plugins like gradle-versions-plugin working
  • Make IDEs understand, also allow code completion and navigation

The worst way is to define all dependencies in each module repeating the dependency group and version, because that make managing versions a nightmare.

Solution that I found in blogs and tutorials are:

  • Keep version numbers in gradle.properties
  • Keep version numbers as variables in root build.gradle, typically in ext {} block
  • Use Spring dependency management plugin (optionally with BOM)
  • Use new configurations per dependency (group)

What I am thinking about is:

It is better to define version strings in plain Groovy without gradle API using the buildScr folder:

buildSrc/src/main/groovy/myproject/Dependencies.groovy

package myproject

class Dependencies {
    static Map<String, String> versions = [
        junit: '4.12'
    ]
    static Map<String, String> libraries = [
        "junit:junit:${versions.junit}"
    ]
}

sub/build.gradle:

import example.Dependencies

dependencies {
    testCompile Dependencies.libraries
}

Result:

  • Pro: IDE (IntelliJ) jumps to definition, supports code completion
  • Pro: Can use plain Groovy or gradle api if necessary
  • Con: location buildSrc/src/main/groovy/myproject/Dependencies.groovy is quite remote, could be optimized though to buildSrc/src/Dependencies I guess.

So far I see no other downsides, I wonder why I never saw anyone doing this.