Plugin-Development: Plugin applier plugin with evaluation dependencies

plugins

(Marvin Strangfeld) #1

Hi, I’m currently developing some Gradle plugins and I have the following problem:
I would like to have a plugin applier plugin that determines what kind of sub-projects I have and applies the correct plugin to them.
Something like that:

class PluginApplierPlugin : Plugin<Project> {
    override fun apply(project: Project) {
        if (project.analyze() == ProjectType1) {
            project.applyPlugins(listOf("com.example.plugin1", "com.example.plugin2")
        } else {
            project.applyPlugins(listOf("com.example.plugin1", "com.example.plugin3")
        }
    }
    fun Project.applyPlugins(plugins: List<String>) {
        plugins.forEach {
            project.plugins.apply(it)
        }
    }
}

In my root-project’s build.gradle.kts file I want to do something like this:

subprojects {
    apply {
        plugin("pluginApplier")
    }
}

This all works perfectly except for one small thing:
Let’s say plugin1 registers an extension like this:

class Plugin1 : Plugin<Project> {
    override fun apply(project: Project) {
        project.extensions.create("extension1", FirstExtension::class.java, project)
    }
}

And plugin2 registers a task and configures it with the properties of another project’s extension and therefore, it has to depend on it’s evaluation:

class Plugin2 : Plugin<Project> {
    override fun apply(project: Project) {
        val otherProject = project.rootProject.project("otherProject")
        val extension = otherProject.extensions.getByType(FirstExtension::class.java)
        project.tasks.register("task1", MyCustomTask::class.java) {
            it.message = extension.message
        }
        project.evaluationDependsOn(otherProject)
    }
}

This works perfectly without specifying the extension in ./otherProject/build.gradle.kts but when I do so:

configure<FirstExtension> {
    message = "Hello, World!"
}

It throws:

FAILURE: Build failed with an exception.

* Where:
Build file '.../multiProject/otherProject/build.gradle.kts' line: 1

* What went wrong:
Extension of type 'FirstExtension' does not exist. Currently registered extension types: [ExtraPropertiesExtension]

What am I doing wrong here? Has anybody an idea how this could work?


(Marvin Strangfeld) #2

So I actually found a workaround by just moving evaluationDependsOn() into the configure closure of the task:

class Plugin2 : Plugin<Project> {
    override fun apply(project: Project) {
        val otherProject = project.rootProject.project("otherProject")
        val extension = otherProject.extensions.getByType(FirstExtension::class.java)
        project.tasks.register("task1", MyCustomTask::class.java) {
            project.evaluationDependsOn(otherProject)
            it.message = extension.message
        }
    }
}

But I’m not quite sure if this is the best solution…