Gradle's version comparison violates SemVer

I was just bit by a difference between Gradle’s default version sorting (see StaticVersionComparator) and the Semantic Versioning specification. In particular this comes up during dependency resolution, especially if you have a dynamic version like 1.+ or latest.integration

Here’s an example:

  • Gradle: 0.1.0-milestone <0.1.0-milestone.1.dev.1< 0.1.0-milestone.1
  • SemVer: 0.1.0-milestone < 0.1.0-milestone.1 < 0.1.0-milestone.1.dev.1

While I know Gradle is older than SemVer and Gradle’s logic is based on PHP’s version_compare (according to the comments), SemVer’s growing popularity over the past few years makes this an unfortunate difference. As someone who’s spending a good chunk of time developing tooling around SemVer, it would great for Gradle to easily support SemVer compliance for version sorting.

Any thoughts on how this could either be made configurable or (unlikely) if the behavior could be changed? I’d be willing to contribute if there’s a consensus on how this should work.

As far as I know, we haven’t yet exposed quite enough to effectively “order versions”.

@daz is this right?

No, there’s not really any way to do this at present. Ideally, it would be the module’s responsibility to declare it uses SemVer, allowing Gradle to order versions using the appropriate algorithm.

One option for implementing this would be to extend the “Component Module Metadata Rules” so that a Module can be declared as being compliant with Semantic Versioning. We could then perform appropriate ordering for versions of that module. See org.gradle.api.artifacts.dsl.ComponentModuleMetadataHandler for more details.

That makes sense. If I get some time, I might take a look and propose something on the dev list. Thanks for pointing me in the right direction!