第 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 類別路徑。
為 Gradle 專案宣告的每個相依性都必須套用至範圍。亦即,相依性在編譯時間、執行時間或兩者都需要。這稱為設定檔,而 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 外掛程式專案時建立一個「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
或
$ ./gradlew :app:greeting
> Task :app:greeting
Hello from plugin 'com.tutorial.greeting'
下一步: 撰寫任務 >>