DEV Community

Roger Viñas Alcon
Roger Viñas Alcon

Posted on

First Steps Developing Custom Gradle Plugins

Not long ago Gradle scared me a lot 👻 ... maybe it was because of Groovy? 😱

But today I am complete in ❤️ with Gradle! Please don't tell Maven 😜

Gradle plugins allows us to reuse build logic across different projects, and we can implement them in any JVM compatible language: Java, Kotlin, Groovy, ...

In this demo we will implement basic Gradle plugins following the Developing Custom Gradle Plugins documentation. If you have time, take a look at Designing Gradle plugins and among other sections Convention over configuration and Capabilities vs. conventions

It will be fun I promise!

GitHub logo rogervinas / gradle-plugins-first-steps

🧞‍♂️ First Steps Developing Custom Gradle Plugins

Step by step

Let's follow these steps:

gradle-plugins-first-steps

In this demo we will use a sample multi-module Gradle project named my-gradle-project with two modules and a custom hello task defined as:

tasks.create("hello") {
  doLast {
    println("Hello from ${project.name}!")
  }
}
Enter fullscreen mode Exit fullscreen mode

So we can simply execute ./gradlew hello and check all the plugins that are applied.

Create plugins in the Build Script

As a first step, we can define plugins directly on our build script. This is enough if we do not have to reuse them outside the build script they are defined in.

Build Script settings plugin

To create a settings plugin and apply it in my-gradle-project > settings.gradle.kts:

class MyBuildSettingsPlugin : Plugin<Settings> {
  override fun apply(settings: Settings) {
    println("Plugin ${this.javaClass.simpleName} applied on ${settings.rootProject.name}")
    // TODO configure `settings`
  }
}

apply<MyBuildSettingsPlugin>()
Enter fullscreen mode Exit fullscreen mode

For simplicity this example plugin only prints a line whenever is applied. A real plugin should do something with the Settings object that is passed as parameter.

Try it running ./gradlew hello and it should print this line:

Plugin MyBuildSettingsPlugin applied on my-gradle-project
Enter fullscreen mode Exit fullscreen mode

Build Script project plugin

To create a project plugin in my-gradle-project > build.gradle.kts:

class MyBuildProjectPlugin : Plugin<Project> {
    override fun apply(project: Project) {
        println("Plugin ${this.javaClass.simpleName} applied on ${project.name}")
        // TODO configure `project`
    }
}
Enter fullscreen mode Exit fullscreen mode

Then for example we can apply the plugin on all projects:

allprojects {
    apply<MyBuildProjectPlugin>()
}
Enter fullscreen mode Exit fullscreen mode

Again this example plugin only prints a line whenever is applied. A real plugin should do something with the Project object that is passed as parameter.

Try it running ./gradlew hello and it should print these lines:

> Configure project :
Plugin MyBuildProjectPlugin applied on my-gradle-project
Plugin MyBuildProjectPlugin applied on my-module-1
Plugin MyBuildProjectPlugin applied on my-module-2
Enter fullscreen mode Exit fullscreen mode

Create plugins in the buildSrc module

As a second step, we can define project plugins in a special module named buildSrc. All plugins defined there will be only visible to every build script within the project.

But most important, we can add tests! 🤩

First we create buildSrc module under my-gradle-project using Gradle init and the kotlin-gradle-plugin template

We implement the plugin in MyBuildSrcProjectPlugin.kt:

class MyBuildSrcProjectPlugin : Plugin<Project> {
  override fun apply(project: Project) {
    println("Plugin ${this.javaClass.simpleName} applied on ${project.name}")
    project.tasks.register("my-buildsrc-project-task") { task ->
      task.doLast {
        println("Task ${task.name} executed on ${project.name}")
      }
    }
  }
}