gradle-versions-plugin icon indicating copy to clipboard operation
gradle-versions-plugin copied to clipboard

Version updates for tooling

Open binkley opened this issue 4 years ago • 3 comments

Fantastic plugin -- thank you for this.

I'm looking for finding when "tooling" versions change for Gradle-distributed plugins.

In this case, I'd like to know I should update the JaCoCo tooling version for the built-in "jacoco" plugin. Ideally, when the Eclipse unbrella updates the distributed JaCoCo plugin, and I have specified a toolVersion property of the built-in "jacoco" plugin that is out of date, I'd like to see that in my report of potential version updates.

Perhaps the answer is: Don't use the toolVersion property! For JaCoCo, I could see this being the case. However, for the general ecosystem of plugins, I'd like the option of treating the "tooling version" separately from the plugin version, and knowing when I have them in/out of sync. (And there are some oddball plugins which run different versions numbers than the tool(s) they wrap.)


To reproduce:

I set (as of 2020-11-01) a toolVersion property to "0.8.6" (latest as of this date) for the "jacoco" plugin in my Gradle build script. I run ./gradlew dependencyUpdates and it is happy. I changed toolVersion to "0.8.5", reran the task, and the report output does not indicate anything out of date.

Perhaps I did it wrong?

@ben-manes 's versions plugin is in my recommendations for modern Java/JVM build practices: https://github.com/binkley/modern-java-practices, and I'd like to speak to the point of "tooling version" separately from plugin versions.

binkley avatar Nov 05 '20 18:11 binkley

Yes, I have that frustration as well. Unfortunately I'm not sure how best to surface this as it is not clear from Gradle. What I observed are implicit dependencies that were added to the resolved set, but were not explicitly declared. For lack of a better term, I called them "hidden" and filtered them out of the report.

https://github.com/ben-manes/gradle-versions-plugin/blob/4f2d15c3e234409f8c2fb4655cbd1dc9772281c3/src/main/groovy/com/github/benmanes/gradle/versions/updates/Resolver.groovy#L95-L100

Tweaking the log statement to include the configuration's name then we get

$ gradle dU -i | grep "Skipping hidden dependency" | sort -u
Skipping hidden dependency: com.github.spotbugs:spotbugs:4.1.3 [spotbugs]
Skipping hidden dependency: com.puppycrawl.tools:checkstyle:8.37 [checkstyle]
Skipping hidden dependency: net.sourceforge.pmd:pmd-java:6.28.0 [pmd]
Skipping hidden dependency: org.jacoco:org.jacoco.agent:0.8.5 [jacocoAgent]
Skipping hidden dependency: org.jacoco:org.jacoco.ant:0.8.5 [jacocoAnt]
Skipping hidden dependency: org.openjdk.jmh:jmh-core:1.26 [jmh]
Skipping hidden dependency: org.openjdk.jmh:jmh-generator-bytecode:1.26 [jmh]
Skipping hidden dependency: org.slf4j:slf4j-simple:1.8.0-beta4 [spotbugsSlf4j]

Since these are hidden, the dynamic version (+) isn't applied so we don't see upgrade options. They would have to be detected, rewritten, then re-resolved to get the upgrade options. However they would be dangling, unrelated to your dependency management, and only understandable if you know the toolVersion mapping. Since this seemed confusing, I removed these as unclear how to proceed.

ben-manes avatar Nov 05 '20 19:11 ben-manes

Lordy, I see your issue. I did some checking through plugin sources (in this case, JaCoCo), and "toolVersion" is ad hoc, that is not implementing an interface (https://github.com/gradle/gradle/blob/master/subprojects/jacoco/src/main/java/org/gradle/testing/jacoco/plugins/JacocoPluginExtension.java -- this is the class my editor navigated me to when I drilled down on the toolVersion property of a jacoco block in build.gradle). So the only way I can see to access "toolVersion" is via reflection (ugh). Apparently "toolVersion" is just a convention, not enforced via code.

Perhaps an API feature request to the Gradle team? (Sorry, I'm out of ideas)


I'll update my modern build guidelines to call out this situation when using the Versions plugin.

binkley avatar Nov 06 '20 14:11 binkley

From that source code, these hidden dependencies are what Gradle calls "default dependencies". This cannot be queried for, only discovered after the fact. We could categorize them separately in the report to hint towards updates, hoping to not confuse users too much.

Since this feature isn't used very often, another approach is to special case it. It could be detected and reported on a per-tool basis to provide a nicer description. This wouldn't scale but since only a handful of plugins use this technique, it might be good enough.

PRs welcome if anyone wants to give it a try.

ben-manes avatar Nov 06 '20 17:11 ben-manes