Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Writing a buildSrc Gradle plugin that can be published

Tags:

plugins

gradle

I'm writing a custom Gradle plugin for my company to assist with integration tests of our product. My team wants to have the plugin be built with and used in the main product build (like a 'buildSrc' plugin would), but also need the plugin to be published as an artifact for other teams to use in integration with our product.

If I try and include it as a standalone plugin in the settings.gradle file and then also include it in the buildscript as a dependency, it obviously does not work because the buildscript block is interpreted first.

I also tried running another build from within the buildscript like so:

buildscript {
  def connection = GradleConnector.newConnector()
    .forProjectDirectory(file("${project.projectDir}/theplugin"))
    .connect()

  try {
    connection.newBuild()
      .forTasks('clean', 'build', 'install')
      .run()
  } finally {
    connection.close()
  }

  repositories {
    mavenLocal()
    ...
  }

  dependencies {
    classpath 'com.company.product.gradle.theplugin'
  }
}

This causes the plugin to be built and placed in the local Maven repo, but then the initial Gradle build fails directly afterward because it can't resolve the newly built archive. If I run it again, it works. I don't understand this behavior.

I'm probably going down a rabbit hole with this approach. Is there a way to make this work and in a less 'hacky' way?

like image 408
Jon Peterson Avatar asked Sep 10 '14 19:09

Jon Peterson


People also ask

How do I create a Gradle plugin?

To create a Gradle plugin, you need to write a class that implements the Plugin interface. When the plugin is applied to a project, Gradle creates an instance of the plugin class and calls the instance's Plugin. apply() method.

What is buildSrc in Gradle?

buildSrc is a separate build whose purpose is to build any tasks, plugins, or other classes which are intended to be used in build scripts of the main build, but don't have to be shared across builds.


1 Answers

I discovered a hacky way to accomplish this: symlink the plugins to the buildSrc (on *nix at least).


project directory

project/
  buildSrc/ -> gradle_plugins/
  gradle_plugins/
    pluginA/
    pluginB/
    ...
    build.gradle
    settings.gradle
  ...
  build.gradle
  settings.gradle

project/settings.gradle

include 'gradle_plugins:pluginA'
include 'gradle_plugins:pluginB'
...

project/gradle_plugins/settings.gradle

include 'pluginA'
include 'pluginB'
...

project/gradle_plugins/build.gradle

...
rootProject.dependencies {
    runtime project(path)
}
...
like image 65
Jon Peterson Avatar answered Nov 15 '22 06:11

Jon Peterson