Thanks both (@Pierre1 and @Lance) for your suggestions!
I implemented the approach suggested by @Pierre1 first and as he mentioned it worked fine. However, it fails for a multi-module gradle project where the plugin is added in the root projects as apply false
, then applied without a version in the subproject. In this case, the plugin artifact isn’t found in the project buildscript classpath. So I tried to search for it in the parent projects recursively as below:
def retrievePluginVersion(Project project) {
def pluginArtifact = findPluginArtifact(project)
assert pluginArtifact != null: 'Plugin missing in the buildscript classpath'
assert pluginArtifact.version != null: 'Plugin version is missing'
return pluginArtifact.version
}
def findPluginArtifact(Project project) {
def pluginArtifact = project.buildscript.configurations.classpath.resolvedConfiguration.resolvedArtifacts
.collect { it.moduleVersion.id }
.find { it.group == 'org.example' && it.name == 'artifact-id' }
if (pluginArtifact != null || project.parent == null) {
return pluginArtifact
}
return findPluginArtifact(project.parent)
}
This works fine for the failure scenario described above. However, in this case, gradle
complains that the project is trying to resolve artifacts of a different project.
Therefore, I switched to the second approach suggested by @Lance. This approach makes the version inference logic a lot simpler in the plugin source code with a bit of setup in build.gradle
. Another important aspect of this approach is that, it’s very friendly with functional tests with gradle-test-kit. Thus, it’s possible to write a functional test simulating the failure scenario and make sure it actually works.