Gradle自定义插件

本教程介绍了创建Gradle独立自定义插件的方法。 它涵盖以下主题
  • 创建任务,并在“自定义”插件中使用它
  • 独立的自定义插件
  • 简短的插件ID
  • 使用settings.gradle自定义Gradle设置

项目信息:

摇篮版本:1.1 操作系统平台:Ubuntu 12.10 先决条件:基本了解Gradle脚本。
创建独立的自定义插件

  1. 创建目录结构
    |-custom-plugin
       |  |-plugin
       |    |-src
       |      |-main
       |      |  |-groovy
       |      |  | |-com
       |      |  |   |-code4reference 
       |      |  |     |-gradle
       |      |  |-resources   
       |      |  | |-META-INF
       |      |  |   |-gradle-plugins 
       |      |-test
       |      |  |-groovy
       |      |  | |-com
       |      |  |   |-code4reference 
       |      |  |     |-gradle 
       |-user

    这里的插件目录包含所有源代码和资源文件,而用户目录包含使用自定义插件的使用者脚本。 执行以下命令以创建目录结构。 这里的groovy文件夹包含源代码包。

    $ mkdir -p custom-plugin/plugin/src/main/groovy/com/code4reference/gradle
      $ mkdir -p custom-plugin/plugin/src/main/resources/META-INF/gradle-plugins
      $ mkdir -p custom-plugin/user
  2. 自定义插件源代码

    每个插件都应该有一个实现类来扩展Plugin类。 让我们定义插件类。

    package com.code4reference.gradle;
    
    import org.gradle.api.*;
    
    class Code4ReferencePlugin implements Plugin {
        def void apply(Project project) {
            //c4rTask task has been defined below.
            project.task('c4rTask') << {
                println 'Hi from Code4Reference plugin!'
            }
        }
    }

    将此文件放在custom-plugin / plugin / src / main / groovy / com / code4reference / gradle目录中。 在这里, c4rTask任务已定义为打印一条简单的线。

  3. 简短的插件ID

    为了应用插件,我们通常使用一个简短的ID,例如apply plugin:'java'。 这里的“ java”是org.gradle.api.plugins.JavaPlugin类的简短插件ID。 简短的插件ID可以通过简单的步骤进行定义。 为此,我们需要创建一个属性文件,并将其放在类路径下的META-INF / gradle-plugins目录中。 文件名将是我们的短ID。 该属性文件必须包含以下所示的行,并且应指向插件实现类。 让我们将属性文件创建为code4reference.properties,并将其指向Code4ReferencePlugin类。

    implementation-class=com.code4reference.gradle.Code4ReferencePlugin
  4. Gradle脚本生成插件

    为了编译和构建此插件,我们将编写gradle脚本。 在插件目录中创建名为build.gradle的文件, 然后在其中复制下面的内容。

    apply plugin: 'groovy'
    apply plugin: 'maven'
    dependencies {
        compile gradleApi()
        groovy localGroovy()
    }
    repositories {
        mavenCentral()
    }
    
    group='com.code4reference'   //Group name makes easier to manager the packages.
    version='1.1-SNAPSHOT'
    
    uploadArchives {
        repositories {
            mavenDeployer {
                repository(url: uri('../repo'))
            }
        }
    }

    在此gradle脚本中,我们使用groovy插件编译groovy源代码,并将gradleAPI声明为编译时间依赖项。 您可能已经注意到我们使用了maven插件。 它基本上会创建插件jar文件并将其存储在maven存储库中。 在这里,我们在父目录中创建名为repo的Maven存储库,并将jar文件存储在其中。

  5. 构建插件并放入存储库
    $ gradle uploadArchives   #This will put the plugin-version.jar in maven repository.
    
    :compileJava UP-TO-DATE
    :compileGroovy UP-TO-DATE
    :processResources UP-TO-DATE
    :classes UP-TO-DATE
    :jar
    :uploadArchives
    Uploading: com/code4reference/plugin/1.1-SNAPSHOT/plugin-1.1-20120816.163101-1.jar to repository remote at file:/home/rakesh/programming/mygitrepo/Code4Reference/GradleExample/custom-plugin-1/repo/
    Transferring 5K from remote
    Uploaded 5K
    
    BUILD SUCCESSFUL
    
    Total time: 34.892 secs
  6. 使用settings.gradle注入设置

    当执行以上命令时,gradle会从settings.gradle中获取项目名称。 如果当前目录中不存在settings.gradle文件,则它将获取当前目录的名称并将其假定为项目名称。 然后,它形成存储jar文件的路径。 文件路径约定如下/group/name/projectName/version/projectname-version-timestamp.jar 。 您可能会在上面的输出中注意到jar路径名和jar文件名带有插件字,因为当前目录名是plugin,并且gradle假定它为项目名。 如果要覆盖此属性,并将code4ReferencePlugin作为项目名称,则需要在插件目录中创建settings.gradle文件,并放入下一行。

    rootProject.name = 'code4ReferencePlugin'

    现在再次执行命令以生成插件jar文件。

    $gradle uploadArchives
    compileJava UP-TO-DATE
    :compileGroovy UP-TO-DATE
    :processResources UP-TO-DATE
    :classes UP-TO-DATE
    :jar UP-TO-DATE
    :uploadArchives
    Uploading: com/code4reference/code4ReferencePlugin/1.1-SNAPSHOT/code4ReferencePlugin-1.1-20120816.164441-5.jar to repository remote at file:/home/rakesh/programming/mygitrepo/Code4Reference/GradleExample/custom-plugin-1/repo/
    Transferring 5K from remote
    Uploaded 5K
    
    BUILD SUCCESSFUL
    
    Total time: 8.61 secs

    现在问题解决了。 该jar将以名称code4ReferencePlugin- [version] -timestamp.jar生成。 如果要查找有关gradle和系统属性的更多信息,请在此处找到。

使用自定义插件

这确实是一个简单的步骤。 尽管我们使用其他插件,但是自定义插件也可以类似的方式使用。 现在在用户目录中创建另一个build.gradle文件,并复制下面给出的代码。

buildscript {
    repositories {
        maven {
            url uri('../repo')
        }
    }
    dependencies {
        classpath group: 'com.code4reference',
                  name: 'code4ReferencePlugin',
                  version: '1.1-SNAPSHOT'
    }
}
apply plugin: 'code4reference'

build.gradle脚本访问父目录中存在的Maven存储库。 我们还定义了依赖关系,该依赖关系基本上是从Maven访问jar文件的特定版本。 最后但并非最不重要的一点是,我们应用简短的插件ID“ code4reference”。 要运行此gradle脚本,请在用户目录中的终端上执行以下命令。

$ gradle c4rTask   #Remember we have created c4rTask in Code4ReferencePlugin class.
                   #You will get the following output.
:c4rTask
Hi from Code4Reference plugin!

BUILD SUCCESSFUL

Total time: 3.908 secs

Voilà! 您刚刚创建了自定义插件,并在其他项目脚本中使用了它。 您可以在此处找到本教程的源代码。 Code4参考

现在,将涵盖以下主题。

  • 定义自定义任务类
  • 将参数传递给自定义插件任务
  • 嵌套参数
  • 测试自定义插件

项目信息:
项目名称:Gradle自定义插件
摇篮版本:1.1 操作系统平台:Ubuntu 12.10 先决条件:基本了解Gradle脚本。

在这里,我们将遵循第一部分中列出的相同目录层次结构。

  1. 定义自定义任务

    让我们定义一个名为Code4ReferenceTask的自定义类,该类扩展了DefaultTask类,并将此文件放在保存Code4ReferencePlugin.groovy的同一文件夹中。 这个类包含一个名为showMessage(),这是标注有@TaskAction方法。 执行任务时,Gradle会调用此方法。

    package com.code4reference.gradle;
    
    import org.gradle.api.DefaultTask
    import org.gradle.api.tasks.TaskAction
    
    class Code4ReferenceTask extends DefaultTask {
    
        @TaskAction
        def showMessage() {
            println '----------showMessage-------------'
        }
    }

    现在,我们需要在Code4ReferencePlugin.groovy中进行一些小的修改,以包含自定义任务。 修改后的Code4ReferencePlugin类如下。

    package com.code4reference.gradle;
    
    import org.gradle.api.*;
    
    class Code4ReferencePlugin implements Plugin {
        def void apply(Project project) {
               //Define the task named c4rTask of type Code4ReferenceTask
               project.task('c4rTask', type: Code4ReferenceTask)
        }
    }

    您可能会注意到,与过去的实现相比,只有突出显示的行已更改。 现在,“ c4rTask”是Code4ReferenceTask类型的。 在插件目录中执行gradle uploadArchives命令。 这将更新Maven存储库中的jar文件。 现在,使用相同的旧build.gradle在用户目录中执行以下命令。 我们将获得以下输出。

    $gradle c4rTask
    :c4rTask
    ----------showMessage-------------
    BUILD SUCCESSFUL
    
    Total time: 14.057 secs
  2. 将参数传递给自定义插件任务

    上面的实现是最简单的,并没有做很多事情。 如果我们想将Gradle脚本的参数传递给该任务怎么办? 我们可以通过访问扩展对象来实现。 Gradle项目具有一个关联的ExtensionContainer对象,该对象有助于跟踪传递给插件类的所有设置和属性。 让我们定义一个扩展类,它可以容纳参数并将其传递给Task类。 Code4ReferencePlugin类中的突出显示的行有助于将参数传递给Task类。

    package com.code4reference.gradle;
    
    import org.gradle.api.*;
    
    //For passing arguments from gradle script.
    class Code4ReferencePluginExtension {
        String message = 'Hello from Code4Reference'
        String sender = 'Code4Reference'
    }
    class Code4ReferencePlugin implements Plugin {
        def void apply(Project project) {
               project.extensions.create('c4rArgs', Code4ReferencePluginExtension)
               project.task('c4rTask', type: Code4ReferenceTask)
        }
    }

    我们已将Code4ReferencePluginExtension定义为Extension类,其中包含两个变量message和sender。 这些用作自定义任务的参数。 我们需要修改Code4RefernceTask类以访问参数。 高亮显示的行已添加到以前的Code4ReferenceTask类实现中。

    package com.code4reference.gradle;
    
    import org.gradle.api.DefaultTask
    import org.gradle.api.tasks.TaskAction
    
    class Code4ReferenceTask extends DefaultTask {
    
        @TaskAction
        def showMessage() {
            println '------------showMessage-------------------'
            println 'From : ${project.c4rArgs.sender},\
                      message : ${project.c4rArgs.message}'
        }
    }

    在插件目录中执行gradle uploadArchives命令。 这将更新Maven存储库中的jar文件。 另外,我们需要更新用户目录中的build.gradle。

    //custom-plugin-2/user
    buildscript {
        repositories {
            maven {
                url uri('../repo')
            }
        }
        dependencies {
            classpath group: 'com.code4reference',
                      name: 'code4ReferencePlugin',
                      version: '1.2-SNAPSHOT'
        }
    }
    
    apply plugin: 'code4reference'
    
    c4rArgs {
        sender = 'Rakesh'
        message = 'Hello there !!!!'
    }

    您可能已经注意到,已经添加了c4rArgs闭包,并且在闭包中设置了发件人和消息变量。 这两个变量可在showMessage()方法中访问。 现在运行用户目录中存在的build.gradle。 我们得到以下输出。

    $gradle c4rTask
    :c4rTask
    -------------------------showMessage-----------------------------
    From : Rakesh, message : Hello there !!!!
    
    BUILD SUCCESSFUL
    
    Total time: 15.817 secs
  3. 嵌套参数

    如果我们想传递嵌套参数怎么办? 我们可以通过嵌套扩展对象来实现。 这是Code4ReferencePlugin类的代码。 此类中仅添加了突出显示的行。

    package com.code4reference.gradle;
    
    import org.gradle.api.*;
    
    //Extension class for nested argumetns
    class C4RNestedPluginExtention {
         String receiver = 'Admin'
         String email = 'admin@code4reference.com'
    
     }
    //For keeping passing arguments from gradle script.
    class Code4ReferencePluginExtension {
        String message = 'Hello from Code4Reference'
        String sender = 'Code4Reference'
        C4RNestedPluginExtention nested = new C4RNestedPluginExtention()
    }
    class Code4ReferencePlugin implements Plugin {
        def void apply(Project project) {
               project.extensions.create('c4rArgs', Code4ReferencePluginExtension)
               project.c4rArgs.extensions.create('nestedArgs',C4RNestedPluginExtention)
               project.task('c4rTask', type: Code4ReferenceTask)
        }
    }

    现在也该修改Code4ReferenceTask类。 在此类中添加了突出显示的行,以访问嵌套的参数。

    package com.code4reference.gradle;
    
    import org.gradle.api.DefaultTask
    import org.gradle.api.tasks.TaskAction
    
    class Code4ReferenceTask extends DefaultTask {
    
        @TaskAction
        def showMessage() {
            println '------------showMessage-------------------'
            println 'From : ${project.c4rArgs.sender},\
                     message : ${project.c4rArgs.message}'
            println 'To : ${project.c4rArgs.nestedArgs.receiver},\
                     email : ${project.c4rArgs.nestedArgs.email}'
        }
    }

    在插件目录中再次执行gradle uploadArchives命令以更新Maven存储库中的jar文件。 现在,修改用户目录中存在的build.gradle文件以传递嵌套参数。

    buildscript {
        repositories {
            maven {
                url uri('../repo')
            }
        }
        dependencies {
            classpath group: 'com.code4reference',
                      name: 'code4ReferencePlugin',
                      version: '1.2-SNAPSHOT'
        }
    }
    
    apply plugin: 'code4reference'
    
    c4rArgs {
        sender = 'Rakesh'
        message = 'Hello there !!!!'
    
        nestedArgs{
           receiver = 'gradleAdmin'
           email = 'gradleAdmin@code4reference.com'
        }
    }

    我们已在build.gradle文件中添加了突出显示的行。

  4. 测试插件和任务

    代码测试是代码开发的重要方面。 现在,我们将为自定义任务和插件添加单元测试。 为此,我们需要为测试类创建目录结构。 我们需要将测试文件夹放在src目录中。 在插件目录中执行以下命令以创建测试目录。

    $mkdir -p src/test/groovy/com/code4reference/gradle/

    测试目录结构遵循用于源代码包目录的相同包目录结构。 在此目录中,放入Code4ReferencePlugin和Code4ReferenceTask的测试类。 在测试类中,ProjectBuilder用于访问项目对象。 这些测试用例易于编写,类似于Junit测试用例。 测试类的代码如下:

    package com.code4reference.gradle;
    
    import org.junit.Test
    import org.gradle.testfixtures.ProjectBuilder
    import org.gradle.api.Project
    import static org.junit.Assert.*
    
    class Code4ReferenceTaskTest {
        @Test
        public void canAddTaskToProject() {
            Project project = ProjectBuilder.builder().build()
            def task = project.task('c4rtakstest', type: Code4ReferenceTask)
            assertTrue(task instanceof Code4ReferenceTask)
        }
    }
    package com.code4reference.gradle;
    
    import org.junit.Test
    import org.gradle.testfixtures.ProjectBuilder
    import org.gradle.api.Project
    import static org.junit.Assert.*
    
    class Code4ReferencePluginTest {
        @Test
        public void code4referencePluginAddsCode4ReferenceTaskToProject() {
            Project project = ProjectBuilder.builder().build()
            project.apply plugin: 'code4reference'
            println 'code4referencePluginAddsCode4ReferenceTaskToProject'
            assertTrue(project.tasks.c4rTask instanceof Code4ReferenceTask)
        }
    }

    要运行测试,请在plugin文件夹中执行以下命令。

    $gradle test                #For success test cases.
    :compileJava UP-TO-DATE
    :compileGroovy UP-TO-DATE
    :processResources UP-TO-DATE
    :classes UP-TO-DATE
    :compileTestJava UP-TO-DATE
    :compileTestGroovy
    :processTestResources UP-TO-DATE
    :testClasses
    :test
    
    BUILD SUCCESSFUL
    
    Total time: 42.799 secs
    
    $gradle test    #In case of test case failure,
                    #you can expect output similar to given below.
    :compileJava UP-TO-DATE
    :compileGroovy UP-TO-DATE
    :processResources UP-TO-DATE
    :classes UP-TO-DATE
    :compileTestJava UP-TO-DATE
    :compileTestGroovy
    :processTestResources UP-TO-DATE
    :testClasses
    :test
    
    com.code4reference.gradle.Code4ReferencePluginTest > code4referencePluginAddsCode4ReferenceTaskToProject FAILED
        java.lang.AssertionError at Code4ReferencePluginTest.groovy:14
    
    2 tests completed, 1 failed
    
    FAILURE: Build failed with an exception.
    
    * What went wrong:
    Execution failed for task ':test'.
    > There were failing tests. See the report at: file:///home/rakesh/programming/mygitrepo/Code4Reference/GradleExample/custom-plugin-2/plugin/build/reports/tests/index.html
    
    * Try:
    Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
    
    BUILD FAILED

    Gradle测试提供了测试报告及其位置。 可以使用任何浏览器打开此文件以检查堆栈跟踪。

您可以在此处找到源代码

参考: Gradle自定义插件(第1部分)  我们的JCG合作伙伴 Rakesh Cusat的Gradle自定义插件(第2部分)位于Code4Reference博客上。


翻译自: https://www.javacodegeeks.com/2012/08/gradle-custom-plugin.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值