How to detect if a plugin was NOT applied?

plugins

(Róbert Papp) #1

The opposite question is easy: plugins.withType or plugins.withId, but how do I detect if a plugin is not applied?

For example: in my custom plugin I want to execute code only in modules the Android plugin is not applied:
Let’s say the “Android” plugin is
id = "com.android.base"
type = com.android.build.gradle.api.AndroidBasePlugin

So I have

project.plugins.withId("com.android.base") {
    // code only valid when it's an Android module
}

how do I implement an “else” for this?


(Róbert Papp) #2

I was thinking

project.afterEvaluate {
    if (project.plugins.findPlugin("com.android.base") == null) {
        // no Android plugin in this project (submodule)
    }
}

but afterEvaluate is too late since I’m registering tasks via TaskContainer.register in that block. Since the tasks would be added in afterEvaluate the users who want to configure the task would need to put their code in afterEvaluate too to be able to use for example TaskContainer.named(...).configure { ... }. That’s not a nice build.gradle :frowning:

Am I missing a concept in this process somewhere?


(Chris Doré) #3

It’s not what you are looking for, but have you considered adding your logic to your own plugin that you apply to the non-android projects? If necessary, you could have this plugin throw an exception if it is used alongside the android plugin.


(Róbert Papp) #4

Yeah, I though about splitting, but it’s a plugin that concerns many/all modules, and I want to keep the config to a minimum: e.g. allprojects { apply plugin: '...' } in root build.gradle. The tricky bit is that the root’s allprojects block is applied first, so at this point findPlugin would give me a valid answer yet.

I’m playing with the idea of just simply doing project == project.rootProject, because that module is usually not Android and if it is I can detect it.

There’s probably no APIs for this, because the first point it’s known if all plugins are applied is afterEvaluate, or maybe it’s not even guaranteed then.

Is there a callback that’s called when project.plugins gets sealed or it’s supported to even apply a plugin in Gradle.buildFinished? (latter means I’m going to have to pick an alternative like @Chris_Dore suggested.)


(Daniel Lacasse) #5

Thanks @TWiStErRob for this question. There is no way to finalize the plugin container. This is something we are actively working on with the Provider API work, however, we aren’t at the level of locking containers as well as providing finalizing callback yet.

Unless your project has several thousands of subprojects, I would simply over-configure by registering all the tasks you require and disable the tasks if the android plugins get added. If performance is a concern, I would then profile the build in order to arrive at a quantifiable performance hit that we can then look at improving inside Gradle.


(Róbert Papp) #6

Am I missing a concept in this process somewhere?

registering all the tasks you require and disable the tasks

That’s it! Nice workaround @Daniel_L, thanks!