How to apply another plugin within a RuleSource plugin


(Hoobajoob) #1

I am working on a standalone RuleSource plugin within which I would like to generate tasks that issue REST requests using tasks implemented by this REST plugin.

Is this possible?

To apply this REST plugin and make it a dependency of the RuleSource plugin, how do I do it? I don’t see a way to define a Mutate or other type of method to get it done.

Not even sure really where to start - can’t seem to find any documentation on this.


(Mike Kobit) #2

The way I have done this is by implementing Plugin and then using a static nested class with the Rules. I see it done the same way in the Gradle source code in multiple places as well.

public class MyPlugin implements Plugin<Project> {

  @Override
  public void apply(Project project) {
    project.getPluginManager().apply('myOtherPlugin');
  }


  public static class Rules extends RuleSource {
    // rules here
  }
}

(Hoobajoob) #3

Ah - ok, so kind of a hybrid approach. I’ll start tinkering with that - thanks! Any links to the gradle source you found as examples?

How does the myOtherPlugin get resolved by the ultimate consumer of the plugin without a buildscript block?


(Mike Kobit) #4

The JavaLanguagePlugin is one example.

I believe that buildscript should resolve correctly because Gradle will also resolve the transitive dependencies of the selected artifact (if I understand what you are asking).


(Hoobajoob) #5

I was referring to these entries that are typically found in build scripts:

buildscript {
  repositories {
    maven {
      url "https://plugins.gradle.org/m2/"
    }
  }
  dependencies {
    classpath "org._10ne.gradle:rest-gradle-plugin:0.4.2"
  }
}

…I’d prefer that someone applying my plugin wouldn’t have to know that they need to add a buildscript block for what would appear to them to be an unrelated plugin that they themselves are not directly applying to their build script.


(Hoobajoob) #6

With this skeletal implementation:

class MyPlugin implements Plugin<Project> {
    @Override
    void apply( Project target ) {
        target.pluginManager.apply('org.tenne.rest')
    }
}

…I get this error when trying to apply MyPlugin to the ultimate build script:

* What went wrong:
A problem occurred evaluating root project 'MyProject'.
> Failed to apply plugin [class 'com.myCompany.gradle.plugins.MyPlugin']
   > Plugin with id 'org.tenne.rest' not found.

(Hoobajoob) #7

Aha! All has become magically clear.

So, I need to effectively take the repo and classpath config that would normally be found in the buildscript block for applying a plugin, and translate those into runtime dependencies in the build.gradle file for my standalone project, like so:

repositories {
    maven {
        url "https://plugins.gradle.org/m2/"
    }
}

dependencies {
    runtime 'org._10ne.gradle:rest-gradle-plugin:0.4.2'
}

Now when the target build script applies my plugin, this other plugin comes along via transitive dependencies and my error above goes away.

Thank you for the pointers, @mkobit!!