Creating a plugin in the project source directory

We have defined the plugin and used it in the same build file. We will see how to extract the plugin code from the build file and put it in a separate source file in the project source directory. Also, we will discuss how to test the plugin.

When we define the plugin in our build file, we cannot reuse it in other projects. We now have the definition and usage of the plugin in the same file. To separate the definition and usage, we can create the plugin class in the buildSrc directory of a Gradle project. In a Gradle multi-project, we must use the buildSrc directory of the root project. This means that for a multi-project build, we can reuse the plugin in other projects of the multi-project build.

We already discussed when we wrote a custom task that any sources in the buildSrc directory are automatically compiled and added to the classpath of the project. First, we will create the buildSrc/src/main/groovy/sample directory. In this directory, we will create an InfoPlugin.groovy file with the following code:

package sample 
 
import org.gradle.api.* 
 
/** 
* Gradle plugin to show Gradle version. 
*/ 
class InfoPlugin implements Plugin<Project> { 
 
    void apply(Project project) { 
        // Add InfoPluginExtension to project accessible 
        // via info{} configuration block. 
        project.extensions.create('info', InfoPluginExtension) 
 
        // Add info task to project. 
        project.tasks.create('info') << { 
            println "$project.info.prefix: $project.gradle.gradleVersion" 
        } 
    } 
 
} 

Next, we will create the InfoPluginExtension.groovy file in the directory:

package sample 
 
/** 
* Extension class for the InfoPlugin. 
*/ 
class InfoPluginExtension { 
 
    /** 
    * Used in InfoPlugin. 
    */ 
    String prefix 
} 

In our build file in the root of the project, we will reference our plugin with the package and class name:

// Apply InfoPlugin from buildSrc directory. 
apply plugin: sample.InfoPlugin 
 
// Configure InfoPlugin via InfoPluginExtension. 
info { 
    prefix = 'Gradle version' 
} 

When we run the  info task, we will see in the output that first the plugin code is compiled and then the info task is executed:

$ gradle info
:buildSrc:clean
:buildSrc:compileJava UP-TO-DATE
:buildSrc:compileGroovy
:buildSrc:processResources UP-TO-DATE
:buildSrc:classes
:buildSrc:jar
:buildSrc:assemble
:buildSrc:compileTestJava UP-TO-DATE
:buildSrc:compileTestGroovy UP-TO-DATE
:buildSrc:processTestResources UP-TO-DATE
:buildSrc:testClasses UP-TO-DATE
:buildSrc:test UP-TO-DATE
:buildSrc:check UP-TO-DATE
:buildSrc:build
:info
Gradle version: 2.10
BUILD SUCCESSFUL
Total time: 1.815 secs

Testing a plugin

One of the tasks that are executed for the project in the buildSrc directory is the test task. We can write test cases for testing the plugin code, just like in any other project. We add a build.gradle file in buildSrc and define the dependencies for the JUnit test framework. In the following sample build file, we will add a dependency for JUnit:

repositories { 
    jcenter() 
} 
 
dependencies { 
    testCompile 'junit:junit:4.12' 
} 

Next, we can add an InfoPluginTest.groovy test case in the buildSrc/src/test/groovy/sample directory:

package sample 
 
import org.gradle.api.* 
import org.gradle.testfixtures.ProjectBuilder 
import org.junit.* 
 
class InfoPluginTest { 
 
    @Test 
    void infoTaskIsAddedToProject() { 
        final Project project = ProjectBuilder.builder().build() 
        project.apply plugin: sample.InfoPlugin 
        assert project.tasks.findByName('info') 
    } 
 
    @Test 
    void configurePrefix() { 
        final Project project = ProjectBuilder.builder().build() 
        project.apply plugin: sample.InfoPlugin 
        project.info.prefix = 'Sample' 
        assert project.info.prefix == 'Sample' 
    } 
 
} 

We use the ProjectBuilder class to create a fixture for the Project object. We can apply the plugin to the project and then test to see whether the info task is available. The Project object cannot execute tasks in the project; it is only for simple checks like this one.

When we invoke the info task from the command line, our test class is compiled and executed. If a test fails, the project will abort; but if all tests pass, the project continues.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.220.237.24