Rich version being ignored for plugin in version catalog

The following was tested on 8.4 and 8.5.

Here’s a boiled down example. A TOML file is used for the version catalog and it looks like this:

[versions]
jedis = { require = "[4.4.6,)", prefer = "5.0.1" }
spotless = { require = "[6.12.0,)", prefer = "6.22.0"}

[libraries]
jedis = { module = "redis.clients:jedis", version.ref = "jedis" }

[plugins]
spotless = { id = "com.diffplug.spotless", version.ref = "spotless" }

And the build file is this:

plugins {
    kotlin("jvm") version "1.9.21"
    alias(libs.plugins.spotless)
}

dependencies {
    implementation(libs.jedis)
}

At the time of writing the latest version of the spotless plugin is 6.23.0, so one minor version before the prefer. For Jedis the latest is 5.1.0 and there is also a 5.0.2 patch version.

Based on the docs the expectation is both the plugin and normal dependency would resolve to the prefer in this scenario. What actually happens is the normal dependency, jedis, follows that behavior but the plugin does not.

$ ./gradlew buildEnvironment
...
+--- com.diffplug.spotless:com.diffplug.spotless.gradle.plugin:[6.12.0,) -> 6.23.0
...
$ ./gradlew dependencyInsight --configuration runtimeClasspath --dependency jedis
redis.clients:jedis:{require [4.4.6,); prefer 5.0.1} -> 5.0.1
\--- runtimeClasspath

It appears for the plugin it does not utilize the prefer which was unexpected and leads to non-repeatable builds.

In practice I don’t actually need rich versions for plugins and perhaps the maintainers also don’t think it makes sense but it shouldn’t silently ignore.

The larger context for how I’m using this is creating a version catalog and platform to be distributed more broadly within a company with the primary goal of setting a floor of certain versions (the min on the require range) but keep the prefer closer to latest. The mix of require/prefer was extended to plugins while not particularly necessary and I could use a single version (effectively a require).

I agree that this is a bug.
It should either fail or take the prefer version into account.
Also using the typical combination of a strictly range and a prefer version does not consider the prefer.
Neither if you do the same with the inline-shorthand-notation "[6.12.0,)!!6.22.0".
And if you only have a prefer version like spotless = { prefer = "6.22.0"}, Gradle will complain that there is no version defined.

You should definitely create an issue about this.

Thanks. I filed `prefer` version not considered for plugin · Issue #27208 · gradle/gradle · GitHub .

1 Like