{"id":40,"date":"2013-05-07T15:56:01","date_gmt":"2013-05-07T15:56:01","guid":{"rendered":"https:\/\/code4reference.com\/?p=40"},"modified":"2013-05-07T15:56:01","modified_gmt":"2013-05-07T15:56:01","slug":"code4referencegradle-custom-plugin-part-2","status":"publish","type":"post","link":"https:\/\/code4reference.com\/?p=40","title":{"rendered":"Code4ReferenceGradle custom plugin (part-2)"},"content":{"rendered":"<p>This tutorial is followup of the <a href=\"http:\/\/code4reference.com\/2012\/08\/gradle-custom-plugin-part-1\">gradle custom plugin tutorial part-1<\/a>. If you haven\u2019t gone through it yet, then I would recommend you to first read it in order to get the better context. In this tutorial we will cover the following topics.<\/p>\n<p><strong><u>Project info :<\/u><\/strong><br \/>\n<strong>Project name :<\/strong> Gradle custom plugin<br \/>\n<strong>Gradle version<\/strong> : 1.1<br \/>\n<strong>OS platform<\/strong> : Ubuntu 12.10<br \/>\n<strong>Prerequisite :<\/strong> Basic understanding of Gradle script.<br \/>\nHere, we will follow the same directory hierarchy listed in the first part.<\/p>\n<ol>\n<li>\n<p>Let\u2019s define a custom class named Code4ReferenceTask which extends DefaultTask class and put this file in the same folder where Code4ReferencePlugin.groovy is kept. This class contains a method named showMessage() which is annotated with <strong><em>@TaskAction<\/em><\/strong>. Gradle calls this method when the task is executed.<\/p>\n<pre>\npackage com.code4reference.gradle;\n\nimport org.gradle.api.DefaultTask\nimport org.gradle.api.tasks.TaskAction\n\nclass Code4ReferenceTask extends DefaultTask {\n\n    @TaskAction\n    def showMessage() {\n        println \"----------showMessage-------------\"\n    }\n}\n<\/pre>\n<p>Now we need to do some minor modifications in the Code4ReferencePlugin.groovy to include the custom task. The modified Code4ReferencePlugin class is as following.<\/p>\n<pre>\npackage com.code4reference.gradle;\n\nimport org.gradle.api.*;\n\nclass Code4ReferencePlugin implements Plugin {\n    def void apply(Project project) {\n           \/\/Define the task named c4rTask of type Code4ReferenceTask\n           project.task('c4rTask', type: Code4ReferenceTask)\n    }\n}\n<\/pre>\n<p>You may notice that only the highlighted line has been changed from the past implementation. Now the \u201cc4rTask\u201d is of Code4ReferenceTask type. Execute the <strong><em>gradle uploadArchives<\/em><\/strong> command in the <strong><em>plugin<\/em><\/strong> directory. This will update the jar file in Maven repo. Now execute the command below in <strong><em>user<\/em><\/strong> directory with the same old build.gradle. We will get the following output.<\/p>\n<pre>\n$gradle c4rTask\n:c4rTask\n----------showMessage-------------\nBUILD SUCCESSFUL\n\nTotal time: 14.057 secs\n<\/pre>\n<\/li>\n<li>\n<p>The above implementation is the simplest one and doesn\u2019t do much. What if we want to pass the arguments from Gradle script to this task? We can achieve it by accessing <strong><em>extension object<\/em><\/strong>. The Gradle Project has an associated ExtensionContainer object that helps keep track of all the settings and properties being passed to plugins class. Let\u2019s define an extension class which can hold the arguments and pass those to the Task class. The highlighted lines in the Code4ReferencePlugin class help to pass the arguments to the Task class.<\/p>\n<pre>\npackage com.code4reference.gradle;\n\nimport org.gradle.api.*;\n\n\/\/For passing arguments from gradle script.\nclass Code4ReferencePluginExtension {\n    String message = 'Hello from Code4Reference'\n    String sender = 'Code4Reference'\n}\nclass Code4ReferencePlugin implements Plugin {\n    def void apply(Project project) {\n           project.extensions.create(\"c4rArgs\", Code4ReferencePluginExtension)\n           project.task('c4rTask', type: Code4ReferenceTask)\n    }\n}\n<\/pre>\n<p>We have defined Code4ReferencePluginExtension as Extension class which contains two variables message and sender. These serve as the arguments for the custom defined task. We need to modify the Code4RefernceTask class to access the arguments. The highlighted lines have been added to the previous Code4ReferenceTask class implementation.<\/p>\n<pre>\npackage com.code4reference.gradle;\n\nimport org.gradle.api.DefaultTask\nimport org.gradle.api.tasks.TaskAction\n\nclass Code4ReferenceTask extends DefaultTask {\n\n    @TaskAction\n    def showMessage() {\n        println \"------------showMessage-------------------\"\n        println \"From : ${project.c4rArgs.sender},\\\n                  message : ${project.c4rArgs.message}\"\n    }\n}\n<\/pre>\n<p>Execute the <strong><em>gradle uploadArchives<\/em><\/strong> command in the plugin directory. This will update the jar file in Maven repo. Also, we need to update the build.gradle in the <b><i>user<\/i><\/b> directory.<\/p>\n<pre>\n\/\/custom-plugin-2\/user\nbuildscript {\n    repositories {\n        maven {\n            url uri('..\/repo')\n        }\n    }\n    dependencies {\n        classpath group: 'com.code4reference',\n                  name: 'code4ReferencePlugin',\n                  version: '1.2-SNAPSHOT'\n    }\n}\n\napply plugin: 'code4reference'\n\nc4rArgs {\n    sender = 'Rakesh'\n    message = 'Hello there !!!!'\n}\n\n<\/pre>\n<p>You may have noticed that c4rArgs closure has been added and sender and message variables are set in the closure. These two variables are accessible in the showMessage() method. Now run the build.gradle present in user directory. we get the following output.<\/p>\n<pre>\n$gradle c4rTask\n:c4rTask\n-------------------------showMessage-----------------------------\nFrom : Rakesh, message : Hello there !!!!\n\nBUILD SUCCESSFUL\n\nTotal time: 15.817 secs\n<\/pre>\n<\/li>\n<li>\n<p>What if we want to pass the nested arguments? We can achieve this by nesting the Extension objects. Here is the code for Code4ReferencePlugin class. Only highlighted lines have been added in this class.<\/p>\n<pre>\npackage com.code4reference.gradle;\n\nimport org.gradle.api.*;\n\n\/\/Extension class for nested argumetns\nclass C4RNestedPluginExtention {\n     String receiver = \"Admin\"\n     String email = \"admin@code4reference.com\"\n\n }\n\/\/For keeping passing arguments from gradle script.\nclass Code4ReferencePluginExtension {\n    String message = 'Hello from Code4Reference'\n    String sender = 'Code4Reference'\n    C4RNestedPluginExtention nested = new C4RNestedPluginExtention()\n}\nclass Code4ReferencePlugin implements Plugin {\n    def void apply(Project project) {\n           project.extensions.create(\"c4rArgs\", Code4ReferencePluginExtension)\n           project.c4rArgs.extensions.create(\"nestedArgs\",C4RNestedPluginExtention)\n           project.task('c4rTask', type: Code4ReferenceTask)\n    }\n}\n\n<\/pre>\n<p>It\u2019s time to modify the Code4ReferenceTask class as well. Highlighted lines have been added in this class to access the nested arguments.<\/p>\n<pre>\npackage com.code4reference.gradle;\n\nimport org.gradle.api.DefaultTask\nimport org.gradle.api.tasks.TaskAction\n\nclass Code4ReferenceTask extends DefaultTask {\n\n    @TaskAction\n    def showMessage() {\n        println \"------------showMessage-------------------\"\n        println \"From : ${project.c4rArgs.sender},\\\n                 message : ${project.c4rArgs.message}\"\n        println \"To : ${project.c4rArgs.nestedArgs.receiver},\\\n                 email : ${project.c4rArgs.nestedArgs.email}\"\n    }\n}\n<\/pre>\n<p>Execute the <strong><em>gradle uploadArchives<\/em><\/strong> command again in the plugin directory to update the jar file in Maven repo. Now modify the build.gradle file present in user directory to pass the nested arguments.<\/p>\n<pre>\nbuildscript {\n    repositories {\n        maven {\n            url uri('..\/repo')\n        }\n    }\n    dependencies {\n        classpath group: 'com.code4reference',\n                  name: 'code4ReferencePlugin',\n                  version: '1.2-SNAPSHOT'\n    }\n}\n\napply plugin: 'code4reference'\n\nc4rArgs {\n    sender = 'Rakesh'\n    message = 'Hello there !!!!'\n\n    nestedArgs{\n       receiver = \"gradleAdmin\"\n       email = \"gradleAdmin@code4reference.com\"\n    }\n}\n\n<\/pre>\n<p>We have added the highlighted line in the build.gradle file.<\/p>\n<\/li>\n<li>\n<p>Testing of code is an important aspect of code development. Now we are going to add the unit test for the custom task and plugin. For this, we need to create the directory structure for the test classes. We need to put the test folder in the src directory. Execute the command below in plugin directory to create the test directories.<\/p>\n<pre>\n$mkdir -p src\/test\/groovy\/com\/code4reference\/gradle\/\n<\/pre>\n<p>Test directory structure follows the same package directory structure which has been used for source code package directory. In this directory, put the test classes for Code4ReferencePlugin and Code4ReferenceTask. In test class, ProjectBuilder is used to access the project object. These test cases are easy to write, similar to the Junit test cases. The code of test classes is as following:<\/p>\n<pre>\npackage com.code4reference.gradle;\n\nimport org.junit.Test\nimport org.gradle.testfixtures.ProjectBuilder\nimport org.gradle.api.Project\nimport static org.junit.Assert.*\n\nclass Code4ReferenceTaskTest {\n    @Test\n    public void canAddTaskToProject() {\n        Project project = ProjectBuilder.builder().build()\n        def task = project.task('c4rtakstest', type: Code4ReferenceTask)\n        assertTrue(task instanceof Code4ReferenceTask)\n    }\n}\n<\/pre>\n<pre>\npackage com.code4reference.gradle;\n\nimport org.junit.Test\nimport org.gradle.testfixtures.ProjectBuilder\nimport org.gradle.api.Project\nimport static org.junit.Assert.*\n\nclass Code4ReferencePluginTest {\n    @Test\n    public void code4referencePluginAddsCode4ReferenceTaskToProject() {\n        Project project = ProjectBuilder.builder().build()\n        project.apply plugin: 'code4reference'\n        println \"code4referencePluginAddsCode4ReferenceTaskToProject\"\n        assertTrue(project.tasks.c4rTask instanceof Code4ReferenceTask)\n    }\n}\n<\/pre>\n<p>To run the test, execute the following command in plugin folder.<\/p>\n<pre>\n$gradle test                #For success test cases.\n:compileJava UP-TO-DATE\n:compileGroovy UP-TO-DATE\n:processResources UP-TO-DATE\n:classes UP-TO-DATE\n:compileTestJava UP-TO-DATE\n:compileTestGroovy\n:processTestResources UP-TO-DATE\n:testClasses\n:test\n\nBUILD SUCCESSFUL\n\nTotal time: 42.799 secs\n\n$gradle test    #In case of test case failure,\n                #you can expect output similar to given below.\n:compileJava UP-TO-DATE\n:compileGroovy UP-TO-DATE\n:processResources UP-TO-DATE\n:classes UP-TO-DATE\n:compileTestJava UP-TO-DATE\n:compileTestGroovy\n:processTestResources UP-TO-DATE\n:testClasses\n:test\n\ncom.code4reference.gradle.Code4ReferencePluginTest &gt; code4referencePluginAddsCode4ReferenceTaskToProject FAILED\n    java.lang.AssertionError at Code4ReferencePluginTest.groovy:14\n\n2 tests completed, 1 failed\n\nFAILURE: Build failed with an exception.\n\n* What went wrong:\nExecution failed for task ':test'.\n&gt; There were failing tests. See the report at: file:\/\/\/home\/rakesh\/programming\/mygitrepo\/Code4Reference\/GradleExample\/custom-plugin-2\/plugin\/build\/reports\/tests\/index.html\n\n* Try:\nRun with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.\n\nBUILD FAILED\n\n<\/pre>\n<p>Gradle test provides the test report and its location. This file can be opened using any browser to examine the stack trace.<\/p>\n<\/li>\n<\/ol>\n<p>you can find the custom-plugin part 2 <a href=\"http:\/\/github.com\/rakeshcusat\/Code4Reference\/tree\/master\/GradleExample\/custom-plugin-2\">source code here<\/a>.<br \/>\nPlease feel free to comment on the post or the website.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This tutorial is followup of the gradle custom plugin tutorial part-1. If you haven\u2019t gone through it yet, then I would recommend you to first read it in order to get the better context. In this tutorial we will cover the following topics. Project info : Project name : Gradle custom plugin Gradle version : [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-40","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/code4reference.com\/index.php?rest_route=\/wp\/v2\/posts\/40","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/code4reference.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/code4reference.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/code4reference.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/code4reference.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=40"}],"version-history":[{"count":0,"href":"https:\/\/code4reference.com\/index.php?rest_route=\/wp\/v2\/posts\/40\/revisions"}],"wp:attachment":[{"href":"https:\/\/code4reference.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=40"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/code4reference.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=40"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/code4reference.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=40"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}