Search code examples
gradlegroovygradle-plugin

How to apply plugin from repo from custom gradle plugin


I read this answer, but as I understand it is not applicable for newer version of Gradle.

Preconditions:

  • Gradle 8.4
  • Custom plugin

I created plugin with build.gradle

buildscript {
    dependencies {
        classpath 'ru.vyarus:gradle-quality-plugin:4.9.0' // it's just a try to provide dependency throught plugin
    }
}

plugins {
    id 'java-gradle-plugin'
    id 'groovy'
    id 'maven-publish'
}

repositories {
    mavenLocal()
    mavenCentral()
    gradlePluginPortal()
}

gradlePlugin {
    plugins {
        create('base-configurer-plugin') {
            id = 'com.test.gradle.base-configurer-plugin'
            implementationClass = 'com.test.BaseGradlePlugin'
        }
    }
}

dependencies {
    compileOnly 'ru.vyarus:gradle-quality-plugin:4.9.0' // added for possibility to import in custom plugin code
}

And plugin code

@Override
void apply(Project project) {
    project.dependencies {
        implementation 'ru.vyarus:gradle-quality-plugin:4.9.0'
    }
    project.pluginManager.apply(QualityPlugin) // I tried many ways to apply with manipulating this apply() method
}

But I got an error when I try to apply this plugin from other project:

Unable to load class 'ru.vyarus.gradle.plugin.quality.QualityPlugin'
ru.vyarus.gradle.plugin.quality.QualityPlugin

Also I tried to add dependency via runtimeClasspath, but got another error:

> Dependencies can not be declared against the `runtimeClasspath` configuration.

runtime() is also not working cause

Gradle DSL method not found: 'runtime()'

So my question is:

How can I add plugin from custom Gradle plugin with it dependencies?

Thanks a lot for your time


Solution

  • To apply an external plugin from your own custom plugin, you need:

    1. The external plugin's code to be on the classpath of the custom plugin, and
    2. To tell Gradle to apply the external plugin by calling one of several methods available via the Gradle Project object.

    1. Putting the external plugin's code on the classpath

    Here you need to find the Maven coordinates of the external plugin JAR and add them to the build.gradle file of your plugin project like any other dependency of any other Gradle project.

    Here you should write:

    dependencies {
        implementation 'ru.vyarus:gradle-quality-plugin:4.9.0'
    }
    

    You use the implementation configuration, not compileOnly, because you need the code on the classpath at runtime.

    Gradle will look for this dependency in the repositories you have specified in the repositories block. I see this artifact is available at both Maven Central and the Gradle Plugin Portal so using either repository should be sufficient (you have specified both)1.

    Also, the code does not need to be on the classpath of the plugin project's buildscript (so no buildscript block) or the classpath of the project your custom plugin will be applied to (so no use of project.dependencies within the code of your custom plugin).

    2. Telling Gradle to apply the external plugin

    Once the external plugin's code is available to the custom plugin, you can then tell Gradle to apply it in your custom plugin code (ie within your own apply method). The recommended approach is using one of the methods on the PluginManager object.

    Writing Groovy code, this would be either:

    project.pluginManager.apply('ru.vyarus.quality')
    

    Or:

    // with import ru.vyarus.gradle.plugin.quality.QualityPlugin
    
    project.pluginManager.apply(QualityPlugin::class)
    

    1Any such repositories would also have to be available to the plugins block of any project you choose to apply your custom plugin to. However, since the custom plugin is available at the Gradle Plugin Portal and the Gradle Plugin Portal is available as a repository to the plugins block by default, this should not be an issue.