Make a custom Gradle plugin that implements both Plugin<Project> and Plugin<Gradle>

Hello,

I’m trying to write a custom Gradle plugin. I want this plugin to be able to used by “build.gradle”, “settings.gradle” and “init.gradle”. If I implement the interface of Plugin, it can be used inside “build.gradle”. If I implemented Plugin it can be used inside “init.gradle”, and then able to modify the entire Gradle project.

I’m wondering if there’s a way I can make the plugin usable inside both “build.gradle” and “init.gradle”. I tried to make the Gradle plugin Class implements both interface and it seems not working.

public classMyGradlePlugin implements Plugin<Project>, Plugin<Gradle> {
public void apply(Project project) {

}
public void apply(Gradle gradle) {

}
}

I understand that if I only make a plugin for init.gradle, it could modify everything. However, I do want to consider users who is not using init.gradle settings and only wants to put the plugin inside their project build.gradle file.

I also understand that if I use the following, it would work. However, it cannot make it work with settings.gradle too.
allprojects{
apply plugin: somePluginOnProjectObject
}

Due to type erasure, the compiler actually sees Plugin<Project>, and Plugin<Gradle> as the same thing. See type erasure in java explained

There’s a chance you could do the following

class MyPlugin implements Plugin<Object> {
   void apply(Object o) {
      if (o instanceof Project) {
         applyProject((Project) o)
      } else if (o instanceof Settings) {
         applySettings((Settings) o)
      } else {
         throw new IllegalArgumentException(o.getClass().getName())
      } 
   } 
   void applyProject(Project project) {...} 
   void applySettings(Settings settings) {...} 
}

Thanks Lance, will this Object be able to be anything besides Settings, Gradle and Project? for example, can it be a ‘DefaultMavenArtifactRepository’ object?

You can see from the PluginAware javadocs

All Known Subinterfaces:
Gradle , Project , Settings