Gradle 编写Plugin

文章目录

首先,是官方文档 Gradle的插件支持任意的JVM语言来编写,当前最常见的是Java或Kotlin

插件的类型

通常来说,插件的编写有3个位置

  1. 直接在项目里写脚本,比如kts或者groovy的,好处是简单清晰,但这样的插件问题是无法运行在别的项目,并且不太适合复杂逻辑
  2. 在目录里写,好处是可以使用多个文件,并且相对工程化一些,缺点同上
  3. 单独的工程,对,插件本身也可以是一个gradle项目,通常一个Gradle plugin会包含多个Task。当然,实际引用时只需要一个jar包即可,无论你项目的类型,并且,可以公开发布到mavenCentral或自己的私服,方便引用,一般来说强烈推荐这种方式

项目脚本的方式

创建一个项目 gradle init --type=basic,然后一路回车默认下来即可 首先,编写一个Plugin,并且引入插件

 1import org.gradle.api.*
 2
 3class ScriptPlugin implements Plugin<Project>{
 4   @Override
 5    public void apply(Project project) {
 6        println("Apply the script plugin")
 7    }
 8}
 9
10apply plugin: ScriptPlugin // 引入插件

这个插件只会做一个事,输出一行文本 然后,因为这个文件目前还在其他的文件里,我们将这个文件引入项目

1apply from: './s.groovy'

在引入前后分别执行 gradle tasks可以得到不同的日志

image.png

这里,可以看到这行日志,是执行在 configure project阶段 通常来说,引入插件不是目的,目的是在于添加task,并在后续中使用,我们修改一下插件的源码

 1import org.gradle.api.*
 2
 3class ScriptPlugin implements Plugin<Project>{
 4   @Override
 5    public void apply(Project project) {
 6        println("Apply the script plugin")
 7        // 形参project是当前项目的引用,可以通过task方法添加任务
 8        project.task('say') {
 9            doLast {
10                println('Say hello')
11            }
12            description = 'Say hello task' // 这个任务的描述,可以通过 gradle tasks --all 查看
13        }
14    }
15}
16
17apply plugin: ScriptPlugin // 引入插件

在修改后,我们使用groovy tasks --all查看一下任务列表

image.png

可以看到这里,有了新的task,用gradle -q say执行一下

image.png

让插件可以配置

我们通常在使用插件时,会有很多可配置的选项,比如android会让你配置安卓的编译版本、包名、是不是使用ndk等信息,自定义插件也不例外。

 1import org.gradle.api.*
 2
 3// 定义一个插件的扩展
 4abstract class ScriptPluginExtension {
 5    abstract Property<String> getMessage()
 6
 7    ScriptPluginExtension() {
 8        message.convention('hello')
 9    }
10}
11
12class ScriptPlugin implements Plugin<Project>{
13   @Override
14    public void apply(Project project) {
15        // 形参project是当前项目的引用,可以通过task方法添加任务和通过extension方法添加扩展
16
17        // 这里,就是获取扩展的值
18        def scriptExt = project.extensions.create('scriptPlugin', ScriptPluginExtension)
19        // def message = scriptExt.message.get() // 这里要注意,不能在apply方法中获取扩展的值,因为扩展的值是在配置阶段才会被设置的
20
21        project.task('say') {
22            doLast {
23                def message = scriptExt.message.get() // 要在运行时才能读取到配置的值
24                println("Say $message")
25            }
26            description = "Say task" // 这个任务的描述,可以通过 gradle tasks --all 查看
27        }
28    }
29}
30
31apply plugin: ScriptPlugin // 引入插件
1apply from: 's.groovy'
2
3scriptPlugin {
4    message = 'world'
5}

image.png