Hello everybody,
I’m here to ask for suggestions.
I’m designing and implementing a Gradle plugin, say FooPlugin
, in Kotlin.
The plugin relies on a FooExtension
which is created and added to a project upon plugin application:
class FooPlugin : Plugin<Project> {
override fun apply(target: Project) {
val extension = target.extensions.create("foo", FooExtension::class.java)
// set up default values for extension properties
}
}
If I well understood how plugin development works, the notation above implies that, whenever someone imports my plugin in their build.gradle.kts
, the default values of FooExtension
properties are computed upon FooPlugin
application.
Yet, users can write:
foo {
// override FooExtension properties values here
}
to override my default values.
Now suppose my default values are not available at plugin application time because, for instance, they can only be computed after some other plugin has been computed.
This is, for instance, the case of the org.jetbrains.kotlin.js
plugin, aimed at setting up Kotlin JS projects.
In fact, it requires the user to choose among a Node- or Browser-compliant compilation fashion (or both), by means of the following syntax:
kotlin {
js {
nodeJs{ } // or browser { }
}
}
There, the nodeJs{ }
creates new tasks for handling NodeJS projects.
My problem is that I rely on the existence of these tasks to set up FooExtension
properties’ default values.
So, currently, I endowed my FooExtension
with a method
fun defaultValuesFrom(project: Project) { /* updates the properties of FooExtension by inspecting the tasks currently in project */ }
which is capable of inspecting the tasks currently hosted by a project to set up the FooExtension
.
This solution actually works, but it requires users to use my plugin as follows:
kotlin {
js {
nodeJs{ } // or browser { }
}
}
val project = this
// foo MUST be configured after kotlin
foo {
defaultValuesFrom(project) // this must be called EXPLICITLY by users
}
In particular, it bothers me that users must explicitly call defaultValuesFrom(project)
.
I’d rather invoke it automatically behind the scenes, upon invocation of foo
, i.e. upon my plugin configuration.
However, I found no way to intercept or override my plugin configuration to inject my custom action.
My questions are:
- is there any way to do so?
- is there a better design for my needs?