Best approach to apply custom plugin to root project via init script in a custom distribution


(Eric Deandrea) #1

If I am shipping a custom distribution with my own custom plugins, what would you say is the best way to make sure that all projects apply some custom plugin that is shipped with the distribution?

My thought was to have the init script add a BuildListener and in the listener apply the plugin I want to allprojects.


How to distribute a custom gradle plugin in a custom gradle distribution
(Peter Niederwieser) #2

You don’t necessarily need a ‘BuildListener’ for this. I’d use ‘gradle.rootProject { apply plugin: “…” }’ or ‘gradle.allprojects { apply plugin: “…” }’, depending on which one you want.


(Luke Daley) #3

Hi Eric,

Check out this post.


(Eric Deandrea) #4

Ok - I was under the impression that in the init script you didn’t have the project model available yet and couldn’t use the rootProject/allprojects closures. If they are available then great - makes things even easier for what I’m trying to do.


(Eric Deandrea) #5

So I’ve done some playing around. Here is the layout of my custom disto:

-Inside the init.d directory I have my init script. In the init.d directory I also have a directory called ‘libs’, and in there are all of the jar files that I have packaged (which contain my custom plugins & other libraries I am shipping with the distribution.

Here’s the init script:

// Make the plugin visible to all projects, by including it in the build script classpath.
rootProject {
 buildscript {
  dependencies {
   classpath fileTree(dir: "${initscript.sourceFile.parentFile}/libs", include: '**/*.jar')
  }
 }
}
  // Also make the plugins available to this init script
initscript {
 dependencies {
  classpath fileTree(dir: "${initscript.sourceFile.parentFile}/libs", include: '**/*.jar')
 }
}
  import some.package.to.build.util.BuildSystemProperty
import some.package.to.build.versionChecking.DistributionUtil
  // Print out the version information
println "\n-------------------------------------------------------------------------------"
println "My Company Gradle Build System ${DistributionUtil.getInstance().getBuildSystemProperty(BuildSystemProperty.DISTRIBUTION_VERSION)}"
println "My Company Plugins Version: ${DistributionUtil.getInstance().getBuildSystemProperty(BuildSystemProperty.PLUGINS_VERSION)}"
println "Core Gradle Distribution Version: ${gradle.gradleVersion}"
println "-------------------------------------------------------------------------------\n"
  gradle.allprojects {
 // Want to apply the mycompany-base plugin to all projects by default
 apply plugin: 'mycompany-base'
}

The output looks like this when I run any task:

-------------------------------------------------------------------------------
My Company Gradle Build System 1.2-UNCONTROLLED ARTIFACT
My Company Plugins Version: UNCONTROLLED ARTIFACT
Core Gradle Distribution Version: 1.2
-------------------------------------------------------------------------------
    FAILURE: Build failed with an exception.
  * Where:
Initialization script 'C:\gradle\custom-gradle-bin\init.d\custom-plugins.gradle' line: 29
  * What went wrong:
Failed to notify action.
> Plugin with id 'mycompany-base' not found.
  * Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
  BUILD FAILED
  Total time: 2.367 secs

But yet, if in the project’s build.gradle file I include the line

apply plugin: 'mycompany-base'

It works fine.

What am I doing wrong here? I know it is finding the jars for my plugins, since the println outputs call into classes that are in the jars and they work.


How to distribute a custom gradle plugin in a custom gradle distribution
(Peter Niederwieser) #6

Apparently (and as Luke tried to point out), this is GRADLE-2407. I’ll have to ask back if/how other people building custom distributions are coping with this.


(Luke Daley) #7

You are hitting GRADLE-2407, which was discussed in the post I linked to.

Because of this bug, you can’t implicitly apply the plugin (due to sequencing issues). This post outlines the approach you can take to reduce the application to one method call.


Please confirm it is NOT possible to apply a plugin in a init file
(Eric Deandrea) #8

What about the init script creating a BuildListener and then applying the plugin in the projectsLoaded event? Or would that be too late in the process to apply a plugin?


(Eric Deandrea) #9

Doesn’t seem to work in projectsLoaded of a BuildListener either - I get the same error:

-------------------------------------------------------------------------------
MY COMPANY Gradle Build System 1.2-UNCONTROLLED ARTIFACT
MY COMPANY Plugins Version: UNCONTROLLED ARTIFACT
Core Gradle Distribution Version: 1.2
-------------------------------------------------------------------------------
  Inside projectsLoaded - applying for project SomeTestProject
  FAILURE: Build failed with an exception.
  * What went wrong:
Failed to notify action.
> Plugin with id 'mycompany-base' not found.
  * Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
  BUILD FAILED
  Total time: 1.555 secs