July 25, 2020
Motivation
I recently started a project for making migrations for Keycloak
possible in a liquibase-like style.
To be able to invoke this migrations from gradle I had to write a gradle plugin. I didn’t find a good ressource how to do so, so I decided to make a quick write up.
Basics
Gradle is a build automation tool from the java ecosystem. It has a lot of plugins for various use cases.
Buildfiles are describedin Groovy as default but Gradle recently added the possibility to also write build scripts in a Kotlin DSL.
The Kotlin support will hit version 1.0 with Gradle 5.0.
Getting started
To start the plugin project we have to initialize a new gradle project first:
mkdir kotlintestplugin
cd kotlintestplugin
gradle init --dsl kotlin
We start with a really basic build file. We just need gradleApi()
as special dependency.
build.gradle.kts
plugins {
kotlin("jvm") version "1.3.0"
}
dependencies {
compile(kotlin("stdlib"))
compile(kotlin("reflect"))
implementation(gradleApi())
implementation(localGroovy())
}
repositories {
jcenter()
}
Defining the task
At first we will start with defining the plugin task and then construct the rest of the plugin structure.
src/main/de/klg71/kotlintestplugin/KotlinTestPlugin.kt
open class TestTask : DefaultTask() {
@TaskAction
fun testAction() {
println("Hello World")
}
}
We simply created a task to print some “Hello World” message.
Creating the Plugin
We add a new class to create the real plugin for gradle.
src/main/de/klg71/kotlintestplugin/KotlinTestPlugin.kt
open class TestTask : DefaultTask() {
@TaskAction
fun testAction() {
println("Hello World")
}
}
// The plugin needs to inherit from Plugin<Project>
open class KotlinTestPlugin : Plugin<Project> {
override fun apply(project: Project) {
// Register our defined task
project.tasks.create<TestTask>("kotlinTestPlugin", TestTask::class.java).run {
// Set description and group for the task
description = "Print test message"
group = "TestPlugin"
}
}
}
Finishing the plugin
To be able to apply our plugin to a project we need to create a small manifest file describing the plugin.
src/main/resources/META-INF/gradle-plugins/de.klg71.kotlintestplugin.properties
implementation-class=de.klg71.kotlintestplugin.KotlinTestPlugin
We also need a gradle.properties
file to set group, version and desciption.
gradle.properties
group = de.klg71
version = 0.0.1-SNAPSHOT
description = kotlintestplugin
Building the plugin
Now we can just execute the jar
gradle task to create the plugin binary.
gradle jar
The jar can now be found unter build/libs/kotlintestplugin-0.0.1-SNAPSHOT.jar
.
We will need it in the next step to test the plugin.
Testing the plugin
We create a new gradle project to test our plugin.
mkdir kotlin_plugin_test_project
gradle init --dsl kotlin
mkdir libs
Now copy the jar created above into the newly created libs directory.
The last thing to do is to apply this plugin to our test project:
build.gradle.kts
buildscript {
repositories {
flatDir {
dirs("libs")
}
}
dependencies {
classpath("de.klg71:kotlintestplugin:0.0.1-SNAPSHOT")
}
}
apply(plugin="de.klg71.kotlintestplugin")
We can now see the plugin task if we execute the tasks
target. And the task kotlinTestPlugin
to print the message.
gradle tasks
>>>>
TestPlugin tasks
----------------
kotlinTestPlugin - Print test message
gradle kotlinTestPlugin
>>>>
> Task :kotlinTestPlugin
Hello World
Wrapping it up
We created a simple gradle plugin in Kotlin to print a message. We then applied this plugin to a sample project.
You can find the plugin and testproject on Github:
Another example plugin example: