Monday, 3 October 2016

Gradle Multi-Project Build with local SNAPSHOT dependency resolution

Note - 2016-10-22 - I missed Gradle Composite Builds which do something very similar

I often find myself on a project with multiple applications depending on common libraries, so I tend to end up with a super project looking like this:

|
|-app1
|-app2
|-lib

All three projects are separate git projects, separately built and deployed; the apps are on a continuous deployment pipeline, the lib requires a decision to cut a release to move it from a SNAPSHOT version to a fixed version. The top level project is just a convenience to allow checking them all out in one shot and building them all with one command.

During development of a feature that requires a change to the lib, I would update the dependency in the app that needs the feature to X.X.X-SNAPSHOT and work on them both at the same time.

In Maven this worked OK for development - both Maven and most IDEs would successfully resolve any SNAPSHOT dependencies locally if possible. Then after cutting a release of the app you only had to delete the -SNAPSHOT bit from the dependency version and job done.

However, Gradle does not do this by default; you have to specify the dependency as being part of your multi-module build as so:

dependencies {
  ...
  compile project(':lib')
  ...
}


This is much more invasive - changing to a release version of the lib now requires replacing that with:

dependencies {

  ...
  compile 'mygroup:lib:1.2.3'
  ...
}

So you have to add the group of the lib, and know which precise version to specify, rather than just deleting '-SNAPSHOT' from the version. This makes it harder to automate changing the dependency - ideally, I would like to release the lib automatically as part of the continuous deployment process of the app after pushing a commit of the app which references a SNAPSHOT version of the lib.

I'm experimenting with a way around this by manipulating the top level gradle build as so:


subprojects.each { it.evaluate() }

def allDependencies = subprojects.collect { it.configurations.collect { it.dependencies }.flatten() }.flatten()
def localDependencies = allDependencies.findAll { dependency ->
    subprojects.any { it.name == dependency.name && it.version == dependency.version && it.group == dependency.group }
}

subprojects {
    configurations.all {
        resolutionStrategy.dependencySubstitution {
            localDependencies.each {
                substitute module("${it.group}:${it.name}:${it.version}") with project(":${it.name}")
            }
        }
    }
}

This effectively gives the Maven behaviour - and IntelliJ at least respects it correctly and resolves the dependencies to the same workspace

You can play with an example here:
https://github.com/lidalia-example-project/parent

10 comments:

  1. I Will Provide Seo Blog Comment Service. & niche relevant blog comment service we provide a quality service with 100% Buyer satisfaction and My team Believed in Quality work not Quantity Contact me Now 24/7.

    ReplyDelete
  2. The software has a user-friendly interface that makes it easier for customer relationship executives to store, process and retrieve information. The software can also be hosted along with the company website. SugarCRM Philippines

    ReplyDelete
  3. The effects of spyware include system degradation, computer malfunction, excessive pop ups, credit card fraud and also identity theft are just a few to name. Getintopc

    ReplyDelete
  4. I might want to thank you for the endeavors you have made in composing this article. I am trusting the same best work from you later on too..  http://www.getinntopc.com

    ReplyDelete
  5. Great job for publishing such a beneficial web site. Your web log isn’t only useful
    filehippo.com

    ReplyDelete
  6. Nice Blog Post.Thanks For Sharing With us.

    ReplyDelete
  7. well done by the admin great job..

    ReplyDelete
  8. Absolutely fantastic posting! Lots of useful information and inspiration, both of which we all need!Relay appreciate your work.
    software development company in delhi

    ReplyDelete