Can a plugin itself add buildscript dependencies and then apply a plugin

I have created a plugin that performs some configuration of another plugin to reduce build script code that needs to be repeated across many projects enterprise-wide otherwise.

I’m struggling with the attempt that this plugin adds a buildscript repository and dependency to the project. What should be applied to a project is something like:

buildscript {
  repositories {
    maven {
      url "https://plugins.gradle.org/m2/"
    }
  }
  dependencies {
    classpath "gradle.plugin.com.palantir.gradle.docker:gradle-docker:0.13.0"
  }
}

apply plugin: "com.palantir.docker"

However I can’t figure out what the proper life-cycle callback is to add the above buildscript instructions. I have been able to apply the plugin, but adding a repository or dependency just does not take effect.

I think you’ve got a bit of a chicken or egg problem here. The buildscript dependencies.classpath is used to create the classloader which runs the scripts and plugins in the build.

Now you want a plugin to add dependencies to the configuration after the classloader has been created? I think it’s too late by that stage since the classloader won’t be recreated. In fact I’m surprised you don’t get a “can’t add files to a configuration which has been resolved” message

Your plugin should have a dependency on the gradle-docker module, and then it will be included in the buildscript classpath whenever someone includes your plugin. Then all your plugin needs to do is apply it.
In other words, the resulting pom of your plugin will contain a dependency on gradle-docker.

Yes, that worked out, added a build.gradle script to the plugin

apply plugin: 'groovy'

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

dependencies {
    compile gradleApi()
    compile localGroovy()

    compile "gradle.plugin.com.palantir.gradle.docker:gradle-docker:0.13.0"
}

And that works perfect!

Hi @Martin_Ahrer, I’m also trying to create a plugin that would apply a third party plugin to projects. I have added a compile dependency of the third party plugin in my custom plugin’s buildscript. However, when I use project.plugins.apply(com.xyz.pluginName), I get the following error message:

A problem occurred evaluating root project ‘project’.
> com/xyz/pluginName

Can you please provide information with how you solved that problem?

The correct syntax is project.plugins.apply("com.xyz.pluginName").

Hi @fredc, project.plugins.apply() has two signatures - one takes the class type and the other takes a String of plugin id. I used both, but neither works.

com.xyz.pluginName looks like a plugin name rather than a class name. If there’s still a (different) error after adding the quotes, perhaps the plugin name is incorrect. Or perhaps the plugin doesn’t register a name. Hard to say without more information.

It wasn’t exactly com.xyz.pluginName; I was just giving an example. When I use the class name, I get the following:

A problem occurred evaluating root project ‘project’.
> com/xyz/pluginName

When I use the plugin name, I get the following:

Failed to apply plugin …
> Plugin with id ‘com.xyz.pluginName’ not found

The problem is that a classpath dependency is needed to be added in the project buildscript. Not sure if it is possible to do it dynamically from a custom plugin. Please let me know if you find a way to do it.

Did you get your plugin working @MiOnim?

The snippet above showing compile "gradle:docker:v" is likely only working in the IDE, but not at gradle runtime.

To add dependencies to the buildscript of all projects using buildSrc dependencies, you must add those dependencies to the runtime configuration. Compile dependencies will allow buildSrc to build, but only runtime elements get promoted to the buildscript classpath automatically.

(Sorry for the bold, just want to make sure anyone scanning along notices).

This is not true. In buildSrc, the runtime configuration inherits dependencies from compile just like any other project using the java or groovy plugins.

$ cat buildSrc/build.gradle
repositories {
    maven { url 'https://plugins.gradle.org/m2/' }
}
dependencies {
    compile 'gradle.plugin.com.palantir.gradle.docker:gradle-docker:0.13.0'
}

$ cat build.gradle
task qwe {
    doLast { println com.palantir.gradle.docker.DockerRunPlugin.class.name }
}

$ ~/.gradle/wrapper/dists/gradle-4.9-all/92mlvw4ggh6usn1so8gz6fmpn/gradle-4.9/bin/gradle -q qwe
com.palantir.gradle.docker.DockerRunPlugin

Weird… right you are. Odd then; I wonder why I thought that? Might have just been IDE complaining. Welp, sorry for the comment spam!