Writing custom Gradle plugins, part 1

Gradle is a plugin-oriented build system. Each plugin provides a set of tasks and conventions, and the code required to run the build process. Although many plugins are already provided in the core distribution (java, groovy, ant, maven, jetty…), the need may arise to develop your own. As this feature is currently not documented, we will write a series of blog posts demonstrating, step by step, how to create a plugin participating in the build lifecycle.

First steps

Of course, our plugin itself shall be built with Gradle.
Ours will use a Groovy layout, although the standard Java structure is also supported – this may be the subject of a future blog post.
Create the following directory layout :

 firstplugin +-- build.gradle +-- libs |   +--- gradle-0.6.jar |   +--- groovy-all-1.5.6.jar |   +--- slf4j-api-1.5.3.jar +-- src/main/groovy/com/zenika/plugins/FirstPlugin.java

Here is the related build script :

  1. usePlugin(‘groovy’)
  2. version=1.0
  3. repositories {
  4. flatDir(dirs: file(‘lib’))
  5. }
  6. dependencies {
  7. groovy “:groovy-all:1.5.6”
  8. groovy “:gradle:0.6”
  9. groovy “:slf4j-api:1.5.3”
  10. }

For now, the plugin consists of a single class “FirstPlugin.java” :

  1. package com.zenika.gradle.plugins;
  2. import org.gradle.api.Plugin;
  3. import org.gradle.api.Project;
  4. import org.gradle.api.internal.project.PluginRegistry;
  5. import java.util.Map;
  6. public class FirstPlugin implements Plugin {
  7. public void apply(Project project, PluginRegistry pluginRegistry, final Map<String, ?> customValues) {
  8. System.out.println(“Hello World!”);
  9. }
  10. }

Compiling and packaging it is as easy as :

  1. gradle clean libs

Using the plugin

To use our brand new plugin, it must be first registered in Gradle through a “settings.gradle” descriptor :

  1. flatDir(dirs:“C:/dev/gradle/firstplugin/build/libs”)
  2. dependencies(“:firstplugin:1.0”)

Please note that, for the sake of simplicity, we used a physical path on the local hard drive. In an enterprise environment, the plugin would rather be deployed on a remote repository like Nexus.
Now, let’s import the plugin in a build script :

  1. usePlugin(com.zenika.gradle.plugins.FirstPlugin)
  2. task test <<{
  3. println “Testing plugin”
  4. }

The “test” task doesn’t do much, but is required to allow our plugin to be loaded and executed, as it doesn’t define custom Gradle tasks on its own.
Let’s see what happens when the script gets executed :

  1. gradle test

The result should be :

 Hello World! :test Testing plugin

A side note on plugin descriptors

Requiring a “settings.gradle” descriptor file seems a bit laborious for a simple user-defined plugin. The forthcoming versions of Gradle will take it into account and simplify the process.
On the other hand, if your plugin gets packaged in the core distribution, the plugin descriptor is not required any more.
you can even declare a custom shortcut notation by editing the “plugin.properties” file :

  1. java=org.gradle.api.plugins.JavaPlugin
  2. groovy=org.gradle.api.plugins.GroovyPlugin
  3. war=org.gradle.api.plugins.WarPlugin
  4. osgi=org.gradle.api.plugins.osgi.OsgiPlugin
  5. jetty=org.gradle.api.plugins.jetty.JettyPlugin
  6. maven=org.gradle.api.plugins.MavenPlugin
  7. projectreports=org.gradle.api.plugins.ProjectReportsPlugin
  8. ant=org.gradle.api.plugins.ant.AntPlugin
  9. firstplugin=com.zenika.gradle.plugins.FirstPlugin

and use it like any other core plugin :

  1. usePlugin(‘firstplugin’)

Conclusion

In this article, we have seen how to develop a simple custom Gradle plugin.
In the next installments of this series, we will show how to pass properties to our plugin, how to write custom tasks, and how to integrate them in the build lifecycle.

Auteur/Autrice

Une réflexion sur “Writing custom Gradle plugins, part 1

  • 19 juillet 2009 à 10 h 18 min
    Permalien

    I believe the Gradle 0.7 API for plugins changes dramatically compared to 0.6. When 0.7 gets release, you may want to update this piece.

    Répondre

Laisser un commentaire

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.

%d blogueurs aiment cette page :