We can add extensions to our project in Gradle to extend the build script with extra capabilities. Actually we can add extensions to any object in Gradle that implements the ExtensionAware
interface. The Task
interface for example extends the ExtensionAware
interface so we can add custom extensions to Gradle tasks as well. Inside a task configuration we can then use that extension.
In the following build script we use a custom extension for JavaCompile
tasks to configure the compiler -Xlint
arguments. The extension is added via the plugin com.mrhaki.gradle.JavaCompilerLintPlugin
. First we take a look ate the extension class. This is a POGO for configuring the compiler arguments with -Xlint
options:
// File: buildSrc/src/main/groovy/com/mrhaki/gradle/JavaCompilerLintExtension.groovy package com.mrhaki.gradle /** * Extension class for use with JavaCompile tasks * to set -Xlint options. */ class JavaCompilerLintExtension { Boolean cast Boolean classfile Boolean deprecation Boolean depAnn Boolean divzero Boolean empty Boolean fallthrough Boolean finallyblocks Boolean options Boolean overrides Boolean path Boolean processing Boolean rawtypes Boolean serial Boolean staticref Boolean tryblocks Boolean unchecked Boolean varargs void enableAll() { cast = true classfile = true deprecation = true depAnn = true divzero = true empty = true fallthrough = true finallyblocks = true options = true overrides = true path = true processing = true rawtypes = true serial = true staticref = true tryblocks = true unchecked = true varargs = true } /** * Create list of compiler -Xlint arguments. * * @return List of -Xlint compiler arguments. */ List<String> asCompilerArgs() { final List<String> optionArgs = [] optionArgs << optionArg('cast', cast) optionArgs << optionArg('classfile', classfile) optionArgs << optionArg('deprecation', deprecation) optionArgs << optionArg('dep-ann', depAnn) optionArgs << optionArg('divzero', divzero) optionArgs << optionArg('empty', empty) optionArgs << optionArg('fallthrough', fallthrough) optionArgs << optionArg('finally', finallyblocks) optionArgs << optionArg('options', options) optionArgs << optionArg('overrides', overrides) optionArgs << optionArg('path', path) optionArgs << optionArg('processing', processing) optionArgs << optionArg('rawtypes', rawtypes) optionArgs << optionArg('serial', serial) optionArgs << optionArg('static', staticref) optionArgs << optionArg('try', tryblocks) optionArgs << optionArg('unchecked', unchecked) optionArgs << optionArg('varargs', varargs) // filter null values. final List<String> compilerArgs = optionArgs.findAll() return compilerArgs } /** * Create -Xlint compile option if option is set. * * @param name Name of the -Xlint compile option. * @param enable Set option argument as -Xlint:option if true, otherwise as -Xlint:-option if false. * @return Null if enable is null, otherwise a valid -Xlint compiler option. */ private String optionArg(final String name, final Boolean enable) { if (enable != null) { final String option = enable ? name : "-$name" return "-Xlint:$option" } return null } }
Next we have a plugin class that registers the extension with the name lint
on all JavaCompile
tasks in our project:
// File: buildSrc/src/main/groovy/com/mrhaki/gradle/JavaCompilerLintPlugin.groovy package com.mrhaki.gradle import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.api.tasks.compile.JavaCompile /** * Plugin for applying a custom extension to * JavaCompile tasks for configuring the * -Xlint options. */ class JavaCompilerLintPlugin implements Plugin<Project> { void apply(final Project project) { // For all JavaCompile tasks we add // a custom extension with the name lint // for configuring -Xlint options. project.tasks.withType(JavaCompile) { task -> // Let Gradle create a new extension. // Users can configure a compile task // from the Java plugin like: // compileJava { // lint { // cast = true // } // } JavaCompilerLintExtension taskExtension = task.extensions.create('lint', JavaCompilerLintExtension) // Use options set via the lint extension // and assign them to the options.compilerArgs // property. // We do this in doFirst because the options are not // set yet at the Gradle configuration phase. task.doFirst { options.compilerArgs = taskExtension.asCompilerArgs() } } } }
We have everything ready, so let's use the plugin in our Java project:
// File: build.gradle apply plugin: 'java' apply plugin: com.mrhaki.gradle.JavaCompilerLintPlugin repositories { jcenter() } dependencies { testCompile 'junit:junit:4.11' } compileJava { // Here we use the custom // task extension. The closure // delegates to JavaCompilerLintExtension. lint { enableAll() empty = false depAnn = false } } compileTestJava { // All JavaCompile task have the // lint extension. lint { cast = true } }
Written with Gradle 2.11.