Concise syntax for specifying the version for any artifact within a group?

What is the best way to ensure that an entire group contains the same version? For example, lets say I wanted to ensure that all Spring dependencies (including transitive) were the same version? The best I can come up with was something like this:

configurations.all {
  resolutionStrategy {
    ['tx','jdbc', .... ].each { force "org.springframework:spring-$it:$springVersion" }
  }
}

The approach above is not ideal since I have to continually update the resolutionStrategy with any Spring dependency brought in. Based on a little bit of experimentation and the documentation on ResolutionStrategy#force it does not appear restricting versions without specifying the exact artifact is supported. Does anyone have any tips on dealing with this?

There are a number of frameworks that release many artifacts within the same group and require the versions to be the same (i.e. Spring, slf4j, etc). If there is no concise way of specifying a version for an entire group, I think it would be really nice if something like this could be supported:

configurations.all {
  resolutionStrategy {
    force "org.springframework:*:$springVersion"
  }
}

Another variant that would be nice is to support a wildcard in the group so that subgroups like org.springframework.security would also be impacted. For example, something like the following would ensure any artifact with a group starting with org.springframework would use the same version:

configurations.all {
  resolutionStrategy {
    force "org.springframework*:*:$springVersion"
  }
}

Of course allowing force to accept a closure would also be nice. Something like the following would enforce springVersion for everything artifact that starts with the group org.springframework and return null (indicate use the default resolution for it) for other artifacts:

configurations.all {
  resolutionStrategy {
    force { return it.group.startsWith('org.springframework') ? springVersion : null; }
  }
}

Any thoughts to how I can implement this? Any thoughts to the suggestions above?

Thanks, Rob Winch

I’d personally not use force for this. I’d prefer to treat it as an error condition if something came in transitively that violated the rule. Then you could apply localised excludes to the offending first level dependency that brought it in. The benefit is that you have an understanding of what you are changing.

There are some hooks on the ‘Configuration.getIncoming()’ object for listening to dependency resolution.

A current shortcoming is that you have little visibility of the dependency graph though so determining what dragged in an offending dependency can be tricky. This is something we are actively working on improving and there will be some new stuff added in 1.2 for this.