alighters

程序、写作、人生

创建 Gradle Plugin

| Comments

在使用 Android Studio 开发的同时,必定离不开 Gradle,再加之最近对 Gradle 在 InstanRun 所扮演的角色颇有兴趣。所以,这里先有一个开篇,理解并编写简单的 gradle plugin。

写一个简单的插件

创建一个 build.gradle 文件

1
2
3
4
5
6
7
8
9
apply plugin: GreetingPlugin

class GreetingPlugin implements Plugin<Project> {
    void apply(Project project) {
        project.task('hello') << {
            println "Hello from the GreetingPlugin"
        }
    }
}

在当前目录下,执行 gradle -q hello,会得到输出:Hello from the GreetingPlugin

设置输入参数

若是需要通过类型来指定参数,可以自定义一个 Extension 相应的 class, 并添加至 project 的 extensions 中,指定名称为 greeting,使用 greeting 来设定参数。替换上面的 build.gradle 文件内容,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
apply plugin: GreetingPlugin

greeting.message = 'Hi from Gradle'

class GreetingPlugin implements Plugin<Project> {
    void apply(Project project) {
        // Add the 'greeting' extension object
        project.extensions.create("greeting", GreetingPluginExtension)
        // Add a task that uses the configuration
        project.task('hello') << {
            println project.greeting.message
        }
    }
}

class GreetingPluginExtension {
    def String message = 'Hello from GreetingPlugin'
}

执行同上命令,会得到输出 Hi from Gradle.

利用闭包输入参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
apply plugin: GreetingPlugin

greeting {
    message = 'Hi'
    greeter = 'Gradle'
}

class GreetingPlugin implements Plugin<Project> {
    void apply(Project project) {
        project.extensions.create("greeting", GreetingPluginExtension)
        project.task('hello') << {
            println "${project.greeting.message} from ${project.greeting.greeter}"
        }
    }
}

class GreetingPluginExtension {
    String message
    String greeter
}

通过以闭包的格式来设置 greeting 参数 message 和 greeter,来控制输出。 执行之后,会得到输出 Hi from Gradle.

输出文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class GreetingToFileTask extends DefaultTask {

    def destination

    File getDestination() {
        project.file(destination)
    }

    @TaskAction
    def greet() {
        def file = getDestination()
        file.parentFile.mkdirs()
        file.write "Hello!"
    }
}

task greet(type: GreetingToFileTask) {
    destination = { project.greetingFile }
}

task sayGreeting(dependsOn: greet) << {
    println file(greetingFile).text
}

ext.greetingFile = "$buildDir/hello.txt"

代码中首先定义了 GreetingToFileTask 的 task,含有一个属性名称为 destination,通过使用 @TaskAction 的注解,指定了该 task 所执行的内容。之后,将其以参数的形式传至 greet 的 task 之中,并设置了 destination 属性的值为当前目录下 build/hello.txt。最后使用 sayGreeting 的 task 来依赖 greet。 在当前目录下,执行 gradle -q sayGreeting, 会得到 Hello! 的输出,并会创建 build 目录,及其下面 hello.txt 的文件且其内容为 Hello!。

项目创建

1.在新的 Library 中,将其中的 build.gradle 文件改为如下:

1
2
3
4
5
6
apply plugin: 'groovy'

dependencies {
    compile gradleApi()
    compile localGroovy()
}

2.编写 groovy 插件代码 在 src/main 目录下,建立 groovy 文件夹,之后是相应的包名路径,在路径下创建 GreetingPlugin.groovy 的文件,内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
package com.lighters.gradle.lib

import org.gradle.api.Plugin
import org.gradle.api.Project

class GreetingPlugin implements Plugin<Project> {
    void apply(Project project) {
      project.task('hello') << {
        println "hello"
      }
    }
}

3.配置插件,编写 src/main/resources/META-INF/gradle-plugins/com.lighters.gradletest.properties,设置其内容,为相应的类名称:

1
implementation-class=com.lighters.gradle.lib.GreetingPlugin

4.发布至本地仓库 在 Library 的 build.gradle 文件中,添加如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
repositories {
    mavenCentral()
}
group='com.lighters.gradle.lib'
version='1.0.1'

uploadArchives {
    repositories {
        mavenDeployer {
            repository(url: uri('../repo'))
        }
    }
}

之后,执行 gradle 刷新同步任务,会在 other 中,看到 uploadArchives 的任务,执行这个任务,就会在本地创建好 repo 的仓库。

5.在主项目中引入使用如下:

1
2
3
4
5
6
7
8
9
10
11
12
buildscript {
    repositories {
        maven {
            url uri('../repo')
        }
    }
    dependencies {
        classpath group: 'com.lighters.gradle.lib', name: 'gradletest',
                  version: '1.0.1'
    }
}
apply plugin: 'com.lighters.gradletest'

Gradle 任务 build 完成之后,会看到一个新多出来的 hello 任务,执行这个任务,则可得到 “hello” 的输出。

扩展

  • 自定义 Task 可通过实现 DefaultTask ,来定义 Task, 通过使用 TaskAction 注解的形式,来指定 task 的输出行为。

  • 参数传递 使用 project 对象的 extendtions 参数来创建参数对象,如下:

1
project.extensions.create('myArgs', MyCustomPluginExtension)

其中,MyCustomPluginExtension 是一个简单的对象,只指定属性字段即可。

另外,也可指定 myArgs 参数,来实现嵌套参数:

1
 project.myArgs.extensions.create('nestArgs', MyNestPluginExtension)

Demo

具体代码,可参照:GradleDemos

参考资料

版权归作者所有,转载请注明原文链接:/blog/2016/11/01/create-gradle-plugin/

给 Ta 个打赏吧...

Comments