gradle自定义任务和插件

2,731 阅读3分钟
  1. 定制任务的不同方式

  1. 方式2定制task

    在根目录下创建buildSrc/src/main/groovy/com/hero/test/文件夹,并创建MTask.groovy

    package com.hero.test
    
    import org.gradle.api.*
    import org.gradle.api.tasks.*
    
    class MTask extends DefaultTask {
        //此处不要定义变量名为name
        @Input String aa;
        @Input int num;
    
        MTask(){
            description = 'hello'
            group = 'test'
        }
    
        @TaskAction
        void start(){
            logger.quiet "name:$aa , num:$num"
        }
    }
    

    在跟目录的build.gradle中使用这个task

    import com.hero.test.MTask  //导入自定义的task
    
    task test(type: MTask){
    	//配置输入和输出
        aa = "hero"
        num = 19
    }
    
    
  2. 实现一个对象插件的几种选择:

  1. 用方式2实现一个插件

    在buildSrc/main/groovy/com/hero/test/下新建MPlugin.groovy

    package com.hero.test
    
    import org.gradle.api.Plugin
    import org.gradle.api.Project
    import com.hero.test.MTask
    
    class MPlugin implements Plugin<Project> {
        @Override
        void apply(Project project){
            //添加一个task,并配置了输入和输出
            project.task('plugintask',type: MTask) {
                aa = 'sss'
                num = 33
            }
        }
    }
    

    使用gradle tasks可以查看task

    使用gradle plugintask可以执行该task

  2. 插件扩展机制

    在跟目录的build.gradle中定义一个扩展属性的闭包

    apply plugin: com.hero.test.MPlugin
    
    mext {
        aa = 'test'
        num = 222
    }
    

    定义一个插件扩展的对象,/buildSrc/src/main/groovy/com/hero/test/Ext.groovy

    package com.hero.test
    class Ext{
        String aa;
        int num;
    }
    

    在插件中注册和使用扩展属性

    package com.hero.test
    
    import org.gradle.api.Plugin
    import org.gradle.api.Project
    import com.hero.test.MTask
    import com.hero.test.Ext
    
    class MPlugin implements Plugin<Project> {
        @Override
        void apply(Project project){
        	//注册扩展容器,与build.gradle中的闭包同名
            project.extensions.create('mext', Ext)
            //查找已配置的属性
            def extension = project.extensions.findByName('mext')
            project.task('plugintask',type: MTask) {
            	//将包装在闭包中的扩展属性赋给task的约定映射
                conventionMapping.aa = { extension.aa }
                conventionMapping.num = { extension.num }
            }
        }
    }
    

    在task中获取配置值

    package com.hero.test
    
    import org.gradle.api.*
    import org.gradle.api.tasks.*
    
    class MTask extends DefaultTask {
        @Input String aa;
        @Input int num;
    
        MTask(){
            description = 'hello'
            group = 'test'
        }
    
        @TaskAction
        void start(){
        	//需要使用getter获取值,直接使用是null值
            String a = getAa()
            String n = getNum()
            logger.quiet "name:$a , num:$n"
        }
    }
    

    约定映射:插件中的每个task都有一个名字是conventionMapping的属性。每个从DefaultTask继承而来的task都拥有这个属性。使用这个属性将扩展模型的值赋给task的输入或者输出字段。通过将扩展模型值包装成一个闭包,实现惰性赋值。意味着这个值只有当task执行时才会被计算。为了获取存储在约定映射中的属性值,需要显式地使用getter方法,否则会返回null。

  3. 被用来扩展一个对象的DSL的扩展是扩展可知的。一个已注册的扩展模型会暴露一些属性和方法,用来给构建脚本建立新的构建语言结构。额外属性是通过ext命名空间创建的简单变量,一般提供给构建脚本使用。尽量避免在插件中使用额外属性。

  4. 插件定义名称——用名称代替全限定类名

    在buildSrc/src/main下创建resources目录,再创建META-INF/gradle-plugins/,再创建mplugin.properties文件并赋值:implementation-class=com.hero.test.MPlugin

    在根目录中引用插件apply plugin: 'mplugin'

  5. 开发和使用独立的对象插件

    1. 项目和仓库配置

      在项目下创建plugin项目,并将buildSrc下的文件拷贝过来

    2. 构建插件项目

      项目不需要再访问buildSrc的代码,需要定义对Groovy和Gradle API类库的依赖。通过Maven插件,可以非常容易地为插件生成POM文件和将工件发布到Maven仓库。需要配置Maven部署器将POM文件和工件上传到本地目录。需要指定插件的group,name和version

      apply plugin: 'groovy'
      apply plugin: 'maven'
      
      //插件名称,group,version
      archivesBaseName = 'mplugin'
      group = 'com.hero.test'
      version = '1.0'
      
      repositories {
          mavenCentral()
      }
      
      dependencies {
          compile localGroovy()
          compile gradleApi()
      }
      
      uploadArchives {
          repositories {
              mavenDeployer {
              	//将插件上传到本地的repo目录
                  repository(url: "file://$projectDir/../repo")
              }
          }
      }
      
    3. 在plugin目录下执行gradle uploadArchives命令,在repo目录下可以看到mplugin的jar和pom文件

    4. 在根目录中使用mplugin

      apply plugin: 'mplugin'
      
      buildscript {
          repositories {
          	//本地maven仓库地址,即repo路径
              maven {
                  url "file://$projectDir/repo"
              }
              mavenCentral()
          }
      
          dependencies {
          	//定义对mplugin的依赖
              classpath 'com.hero.test:mplugin:1.0'
          }
      }