Gradle - configure subprojects based on plugin presence

plugins

#1

I am fighting with a fairly simple gradle problem but despite searching I cannot find a solution. Very simple, in a multi project build, I need configure some subproject based on the plugins they load.
So If sub project has plugin ‘war’ or ‘ear’ do this… I have tried the following without success:

subprojects {
if (it.plugins.hasPlugin(‘war’) || (it.plugins.hasPlugin(‘ear’) {
apply plugin: ‘my super special plugin’


}
}

The above never apply plugin: ‘my super special plugin’

Any suggestion? Thanks


(Sterling Greene) #2

You’re looking for PluginManager.withPlugin:

https://docs.gradle.org/current/dsl/org.gradle.api.plugins.PluginManager.html#org.gradle.api.plugins.PluginManager:withPlugin(java.lang.String, org.gradle.api.Action)

(Sorry, Discourse seems to barf on this link)

subprojects {
    pluginManager.withPlugin("war") {
        apply plugin: 'my super special plugin'
    }
}

#3

Thanks a lot!, that works perfectly!
I am having just a bit of problem selecting both war and ear ids. The following won’t work. Is it possible or Do I need to have to separate blocks pluginManager.withPlugin(“xxx”). I have quite some code to apply

subprojects {
    pluginManager.withPlugin("war") || pluginManager.withPlugin("ear") {
        apply plugin: 'my super special plugin'
    }
}

(uklance) #4

I think you want pluginManager.hasPlugin(id) which returns boolean rather than withPlugin(id, action) which executes an action and returns void

https://docs.gradle.org/current/dsl/org.gradle.api.plugins.PluginManager.html


#5

I tried, it never returns true, I suspect that it evaluates before “war” plugins is applied?


(uklance) #6

Yep, likely a timing issue. You could use an afterEvaluate closure to delay evaluation

subprojects {
   afterEvaluate {
      if (pluginManager.hasPlugin('foo')) {
        ... 
      } 
   } 
} 

(Sterling Greene) #8

The configuration can be shared/passed around:

subprojects {
   def configurationForEarOrWar = { /* stuff */ }
   pluginManager.withPlugin("war", configurationForEarOrWar)
   pluginManager.withPlugin("ear", configurationForEarOrWar)
}

#9

@sterling Thanks. It works perfect and solves the problem


#10

@Lance somehow afterEvaluate did not help. hasPlugin still returned false


(Sterling Greene) #11

No problem.

As a style/usability comment, if there are several plugins that your plugin knows how to configure, it would be better to unconditionally apply your special plugin and then have the plugin do withPlugin(...). That makes it easier for people who use your plugin to “do the right thing”.


#12

Thanks for the good suggestion.
It is not really my plugin, it’s websphere deployment plug-in that can run on both war and ear projects.
Somehow (i don’t recall why) I found out that if I just applied it, the overall build and deploy would fail on some modules.
In this way you suggested works perfectly