第 5 部分:编写构建脚本
通过开发构建脚本,学习编写 Gradle 构建的基础知识。
步骤 1. Project
对象
构建脚本调用 Gradle API 来配置构建。
在配置阶段,Gradle 会在根目录和子项目目录中找到构建脚本。
当找到构建脚本 build.gradle(.kts)
时,Gradle 会配置一个 Project 对象。
您可以直接在脚本中使用 Project 接口上的任何方法和属性。
例如
defaultTasks("some-task") // Delegates to Project.defaultTasks()
reportsDir = file("reports") // Delegates to Project.file() and the Java Plugin
defaultTasks 'some-task' // Delegates to Project.defaultTasks()
reportsDir = file('reports') // Delegates to Project.file() and the Java Plugin
步骤 2. 构建脚本
让我们分解一下插件的构建脚本
plugins { (1)
`java-gradle-plugin` (2)
id("org.jetbrains.kotlin.jvm") version "1.9.0" (3)
}
repositories { (4)
mavenCentral() (5)
}
dependencies { (6)
testImplementation("org.jetbrains.kotlin:kotlin-test-junit5") (7)
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
}
gradlePlugin { (8)
val greeting by plugins.creating { (9)
id = "license.greeting"
implementationClass = "license.LicensePlugin"
}
}
// Additional lines //
1 | 在 Kotlin DSL 中使用来自 KotlinSettingsScript 的 plugins{} 块 |
2 | 应用 Java Gradle 插件开发插件,以添加对开发 Gradle 插件的支持 |
3 | 应用 Kotlin JVM 插件,以添加对 Kotlin 的支持 |
4 | 使用 Project.repositories() 为此项目配置仓库 |
5 | 使用 Maven Central 解析依赖项 |
6 | 使用 Project.dependencies() 为此项目配置依赖项 |
7 | 使用 Kotlin JUnit 5 集成 |
8 | 在 Kotlin DSL 中使用来自 GradlePluginDevelopmentExtension 的 gradlePlugin{} 块 |
9 | 定义插件的 id 和 implementationClass |
plugins { (1)
id 'java-gradle-plugin' (2)
id 'groovy' (3)
}
repositories { (4)
mavenCentral() (5)
}
dependencies { (6)
testImplementation libs.spock.core
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}
gradlePlugin { (7)
plugins {
greeting {
id = 'license.greeting' (8)
implementationClass = 'license.LicensePlugin'
}
}
}
// Additional lines //
1 | 在 Groovy DSL 中使用来自 PluginDependenciesSpec API 的 plugins{} 块 |
2 | 应用 Java Gradle 插件开发插件,以添加对开发 Gradle 插件的支持 |
3 | 应用 Groovy 插件,以添加对 Groovy 的支持 |
4 | 使用 Project.repositories() 为此项目配置仓库 |
5 | 使用 Maven Central 解析依赖项 |
6 | 使用 Project.dependencies() 为此项目配置依赖项 |
7 | 在 Groovy DSL 中使用来自 PluginAware API 的 gradlePlugin{} 块 |
8 | 定义插件的 id 和 implementationClass |
插件用于增强构建能力,按如下方式包含
plugins {
id("java") // core plugin, no version required
id("org.some.plugin") version "2.8" // community plugin, version required
}
plugins {
id 'java' // core plugin, no version required
id 'org.some.plugin' version '2.8' // community plugin, version required
}
仓库部分让 Gradle 知道从哪里拉取依赖项
repositories {
mavenCentral() // get dependencies from the Maven central repository
}
repositories {
mavenCentral() // get dependencies from the Maven central repository
}
依赖项是构建应用或库的要求
dependencies {
// group: 'org.apache.commons', name: 'commons-lang3', version: '3.13.0'
implementation("org.apache.commons:commons-lang3:3.13.0")
}
dependencies {
// group: 'org.apache.commons', name: 'commons-lang3', version: '3.13.0'
implementation 'org.apache.commons:commons-lang3:3.13.0'
}
在此示例中,implementation()
表示必须将 commons-lang3
库添加到 Java classpath。
为 Gradle 项目声明的每个依赖项都必须应用于一个范围。也就是说,依赖项在编译时、运行时或两者都需要。这称为配置 (configuration),当依赖项仅在运行时 classpath 中需要时,使用 implementation
配置。
配置块(不要与上述依赖配置混淆)通常用于配置已应用的插件
gradlePlugin { // Define a custom plugin
val greeting by plugins.creating { // Define `greeting` plugin using the `plugins.creating` method
id = "license.greeting" // Create plugin with the specified ID
implementationClass = "license.LicensePlugin" // and specified implementation class
}
}
gradlePlugin { // Define a custom plugin
plugins {
greeting { // Define a plugin named greeting
id = 'license.greeting' // using the id
implementationClass = 'license.LicensePlugin' // and implementationClass
}
}
}
应用 java-gradle-plugin
时,用户必须使用 gradlePlugin{}
配置块配置正在开发的插件。
任务是在构建期间执行的工作单元。它们可以由插件或内联定义
val functionalTest by tasks.registering(Test::class) {
testClassesDirs = functionalTestSourceSet.output.classesDirs
classpath = functionalTestSourceSet.runtimeClasspath
useJUnitPlatform()
}
tasks.named<Test>("test") {
// Use JUnit Jupiter for unit tests.
useJUnitPlatform()
}
tasks.register('functionalTest', Test) {
testClassesDirs = sourceSets.functionalTest.output.classesDirs
classpath = sourceSets.functionalTest.runtimeClasspath
useJUnitPlatform()
}
tasks.named('test') {
// Use JUnit Jupiter for unit tests.
useJUnitPlatform()
}
在 Gradle init 生成的示例中,我们定义了两个任务
-
functionalTest
:此任务使用tasks.register()
注册。它为功能测试配置测试任务。 -
test
:此任务使用tasks.named()
为现有的test
任务配置。它还将任务配置为使用 JUnit Jupiter 进行单元测试。
步骤 3. 更新构建脚本
在接下来的几节中,我们将把 LicensePlugin
更新为一个可以自动为源代码文件生成许可证头的插件。首先,让我们用新插件 license
的正确名称更新构建脚本
gradlePlugin {
val license by plugins.creating { // Update name to license
id = "com.tutorial.license" // Update id to com.gradle.license
implementationClass = "license.LicensePlugin"
}
}
gradlePlugin {
// Define the plugin
plugins {
license { // Update name to license
id = 'com.tutorial.license' // Update id to com.gradle.license
implementationClass = 'license.LicensePlugin'
}
}
}
步骤 3. 应用插件
让我们将 license
插件应用到 app
子项目
plugins {
application
id("com.tutorial.license") // Apply the license plugin
}
plugins {
id 'application'
id('com.tutorial.license') // Apply the license plugin
}
步骤 4. 查看插件任务
使用 Gradle init 生成 Gradle 插件项目时,会创建一个“hello world”插件。在 LicensePlugin
中,只是一个简单的任务,用于在控制台打印一条问候语,任务名称是 greeting
class LicensePlugin: Plugin<Project> {
override fun apply(project: Project) { // Apply plugin
project.tasks.register("greeting") { task -> // Register a task
task.doLast {
println("Hello from plugin 'com.tutorial.greeting'") // Hello world printout
}
}
}
}
class LicensePlugin implements Plugin<Project> {
void apply(Project project) {
// Register a task
project.tasks.register("greeting") {
doLast {
println("Hello from plugin 'com.tutorial.greeting'")
}
}
}
}
正如我们所见,license
插件在应用后,会暴露一个 greeting
任务,其中包含一个简单的打印语句。
步骤 5. 查看插件任务
当 license
插件应用到 app
项目时,greeting
任务就可用了
要在根目录中查看该任务,请运行
$ ./gradlew tasks --all
------------------------------------------------------------
Tasks runnable from root project 'authoring-tutorial'
------------------------------------------------------------
...
Other tasks
-----------
app:greeting
app:task1
app:task2
lib:task3
最后,使用 ./gradlew greeting
或 运行 greeting
任务
$ ./gradlew :app:greeting
> Task :app:greeting
Hello from plugin 'com.tutorial.greeting'
下一步: 编写任务 >>