开发Gradle plugin

最近在学习如何编写 Gradle plugin, 记录一下学习心得
插件分类
Gradle 插件有三种实现方式 Script plugins、Precomplied script plugins 和 Binary plugins
Script plugins: 在build.gradle中直接实现插件逻辑,只能在当前构建中使用。Precomplied script plugins: 在项目中的独立文件(.gradle或.gradle.kts)中实现插件逻辑,可以在项目中的多个构建中使用。Binary plugins: 使用独立项目实现插件逻辑,并打包为jar文件,在项目中通过引用jar文件来使用。
本文使用独立项目来制作 Binary plugins.
环境准备
需要安装 Java 和 Gradle
文中使用的是 Java 21.0.3 和 Gradle 8.10.2
初始化项目
gradle init --type java-gradle-plugin
Welcome to Gradle 8.10.2!
Here are the highlights of this release:
- Support for Java 23
- Faster configuration cache
- Better configuration cache reports
For more details see https://docs.gradle.org/8.10.2/release-notes.html
Starting a Gradle Daemon (subsequent builds will be faster)
Project name (default: gradle-plugin-demo):
Select build script DSL:
1: Kotlin
2: Groovy
Enter selection (default: Kotlin) [1..2]
Generate build using new APIs and behavior (some features may change in the next minor release)? (default: no) [yes, no]
> Task :init
For more information, please refer to https://docs.gradle.org/8.10.2/userguide/custom_plugins.html in the Gradle documentation.
BUILD SUCCESSFUL in 1m 5s
1 actionable task: 1 executed
运行 init 命令之后会需要回答3个问题
Project name: 设置项目名字,(默认是当前目录的名字)Build script DSL:选择构建脚本的语言,默认是KotlinNew APIs and behavior: 是否启用新的API和特性,默认是no
gradle的项目都有一个构建文件 build.gradle 根据构建语言的不同文件的后缀名有所区别
Groovy 的是 build.gradle , Kotlin 的是 build.gradle.kts
初始化之后的目录结构如下:
.
├── .gitattributes
├── .gitignore
├── gradle
│ ├── libs.versions.toml
│ └── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── plugin
│ ├── build.gradle.kts
│ └── src
│ ├── functionalTest
│ │ └── java
│ │ └── org
│ │ └── example
│ │ └── GradlePluginDemoPluginFunctionalTest.java
│ ├── main
│ │ ├── java
│ │ │ └── org
│ │ │ └── example
│ │ │ └── GradlePluginDemoPlugin.java
│ │ └── resources
│ └── test
│ ├── java
│ │ └── org
│ │ └── example
│ │ └── GradlePluginDemoPluginTest.java
│ └── resources
└── settings.gradle.kts
19 directories, 12 files
grale: 配置gradle-wrapper用来定义项目使用的gradle的版本,libs.versions.toml是gradle的依赖版本管理文件是 [[Gradle版本目录(Version Catalogs)]] 的另一种实现方式plugin: 插件代码的目录,包含核心代码,测试代码settings.gradle.kts:Gradle的配置文件
Plugin id
我们可以在 build.gradle.kts 文件中看到如下内容
gradlePlugin {
// Define the plugin
val greeting by plugins.creating {
id = "org.example.greeting"
implementationClass = "org.example.GradlePluginDemoPlugin"
}
}
这里定义我们的插件的 id , 这个 id 就是插件的唯一标识。
入口类
public class GradlePluginDemoPlugin implements Plugin<Project> {
public void apply(Project project) {
// Register a task
project.getTasks().register("greeting", task -> {
task.doLast(s -> System.out.println("Hello from plugin 'org.example.greeting'"));
});
}
}
实现 Plugin<Project> 的类将作为插件的入口类 , 在一个插件在 Gradle 中被使用将会执行入口类的 apply(Project) 方法。
project.getTasks().register("greeting", task -> {
task.doLast(s -> System.out.println("Hello from plugin 'org.example.greeting'"));
});
通过 register 我们可以注册一个名字叫做 greeting 的 task 到 Gradle 的构建中. 这个task在运行的时候会在控制台输出 Hello from plugin 'org.example.greeting'
现在我们可以运行一下 org.example.GradlePluginDemoPluginFunctionalTest#canRunTask() 这个测试方法来看看一下实际效果
> Task :greeting
Hello from plugin 'org.example.greeting'
可以看到名字叫做 greeting 的插件被执行了,然后输出了 Hello form plugin 'org.example.greeting'
这就是我们通过 init 命令创建的 Gradle plugin 的 Hello world
