We have a multi platform project, however each platform has its own platform-dependent implementation of some classes. In our case, 2 of these target platforms require the same plugin, however they require different versions of that plugin.
So far, I have tried to do this by setting pluginVersion
via either -PbuildingForB
or gradle.taskGraph.whenReady
, then setting a classpath in the dependencies block of the buildscript block, and finally applying the plugin after the plugins block. I have also tried to use extra
instead of var/val
. Unfortunately, this errors with Unresolved reference: pluginVersion
and Cannot get property 'pluginVersion' on extra properties extension as it does not exist
, respectfully.
val versionA = "1.0"
val versionB = "2.0"
var pluginVersion = versionA
pluginVersion = project.findProperty("buildingForB")?.let {
if (it == "true") versionB else versionA
} ?: versionA
gradle.taskGraph.whenReady {
if (tasks.contains(task("buildPlatformB")))
pluginVersion = versionB
}
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath("com.example:example-plugin:${pluginVersion]}")
}
}
plugins {
...
}
apply(plugin = "com.example")
errors with Unresolved reference: pluginVersion
You can choose the version entirely within the buildscript
block, eg:
buildscript {
val pluginVersion = findProperty("buildingForB")?.let { "2.0" } ?: "1.0"
repositories {
mavenCentral()
}
dependencies {
classpath("com.example:example-plugin:$pluginVersion")
}
}
// Using the *id* of the plugin, which is different to the group and artifact name above
apply(plugin = "com.example")
This must be done because the buildscript
block is compiled separately before the rest of the script.
As discussed in the comments, this approach will not give the elegant Kotlin accessors associated with the plugin, as these are only generated when plugins are added in the plugins
block1; and the plugins
block can only use hard-coded versions2.
Full functionality is however still available without the accessors but not with full type safety. This is the same approach that a plugin author would have to take when writing a binary plugin.
Also, taking a step back, this approach is not following Gradle best practice. The recommended approach would be to move to use a multi-project build, where each module used a different versions of the plugin and built a single target.
1https://docs.gradle.org/current/userguide/kotlin_dsl.html#type-safe-accessors 2https://docs.gradle.org/current/userguide/plugins.html#plugins_dsl_limitations