使用案例
舉例來說,假設一個包含三個子專案的專案產生兩個公開 Java 程式庫,這兩個程式庫使用第三個子專案作為內部共用程式庫。這是專案結構
├── internal-module
│ └── build.gradle.kts
├── library-a
│ ├── build.gradle.kts
│ └── README.md
├── library-b
│ ├── build.gradle.kts
│ └── README.md
└── settings.gradle.kts
├── internal-module
│ └── build.gradle
├── library-a
│ ├── build.gradle
│ └── README.md
├── library-b
│ ├── build.gradle
│ └── README.md
└── settings.gradle
假設我們所有的專案都將是 Java 專案。在這種情況下,我們希望將一組通用的規則套用至所有專案,例如原始碼目錄配置、編譯器旗標、程式碼樣式慣例、程式碼品質檢查等等。
三個專案中有兩個不僅僅是 Java 專案,它們是我們可能想要發布到外部儲存庫的程式庫。發布配置,例如程式庫的通用群組名稱以及儲存庫座標,可能是兩個程式庫都需要共用的跨領域問題。對於此範例,我們也假設我們想要強制我們的程式庫公開具有通用結構的一些文件。
組織建置邏輯
從上面的使用案例中,我們已識別出我們有兩種專案類型 - 通用 Java 專案和公開程式庫。我們可以透過分層兩個獨立的外掛程式來模型化此使用案例,每個外掛程式都定義套用它們的專案類型
├── buildSrc
│ ├── build.gradle.kts
│ ├── settings.gradle.kts
│ ├── src
│ │ ├── main
│ │ │ └── kotlin
│ │ │ ├── myproject.java-conventions.gradle.kts
│ │ │ └── myproject.library-conventions.gradle.kts
...
├── buildSrc
│ ├── build.gradle
│ ├── settings.gradle
│ ├── src
│ │ ├── main
│ │ │ └── groovy
│ │ │ ├── myproject.java-conventions.gradle
│ │ │ └── myproject.library-conventions.gradle
...
-
myproject.java-conventions
- 配置組織中任何 Java 專案通用的慣例。它套用核心java
和checkstyle
外掛程式以及外部com.github.spotbugs
外掛程式,配置通用編譯器選項以及程式碼品質檢查。 -
myproject.library-conventions
- 新增發布配置以發布到組織的儲存庫,並檢查 README 中是否有強制性內容。它套用java-library
和maven-publish
外掛程式以及myproject.java-conventions
外掛程式。
內部程式庫子專案套用 myproject.java-conventions
外掛程式
plugins {
id("myproject.java-conventions")
}
dependencies {
// internal module dependencies
}
plugins {
id 'myproject.java-conventions'
}
dependencies {
// internal module dependencies
}
兩個公開程式庫子專案套用 myproject.library-conventions
外掛程式。
plugins {
id("myproject.library-conventions")
}
dependencies {
implementation(project(":internal-module"))
}
plugins {
id("myproject.library-conventions")
}
dependencies {
implementation(project(":internal-module"))
}
plugins {
id 'myproject.library-conventions'
}
dependencies {
implementation project(':internal-module')
}
plugins {
id 'myproject.library-conventions'
}
dependencies {
implementation project(':internal-module')
}
請注意,將慣例外掛程式套用至子專案如何有效地宣告其類型。透過套用 myproject.java-conventions
外掛程式,我們聲明:這是一個「Java」專案。透過套用 myproject.library-conventions
外掛程式,我們聲明:這是一個「程式庫」專案。
此範例中建立的所有外掛程式都包含功能測試,這些測試使用 TestKit 來驗證其行為。
此範例沒有任何專案原始碼,僅佈局了假設的專案結構,其中兩個程式庫子專案依賴於共用的內部子專案。
編譯慣例外掛程式
在此範例中,慣例外掛程式實作為預先編譯的腳本外掛程式 - 這是最簡單的入門方式,因為您可以直接使用 Gradle 的 DSL 之一來實作建置邏輯,就像外掛程式是常規建置腳本一樣。
為了發現預先編譯的腳本外掛程式,buildSrc
專案需要在其 build.gradle.kts
檔案中套用 kotlin-dsl
外掛程式
為了發現預先編譯的腳本外掛程式,buildSrc
專案需要在其 build.gradle
檔案中套用 groovy-gradle-plugin
外掛程式
plugins {
`kotlin-dsl`
}
plugins {
id 'groovy-gradle-plugin'
}
注意事項
在預先編譯的腳本外掛程式中套用外部外掛程式
myproject.java-conventions
外掛程式使用 SpotBugs 外掛程式來執行靜態程式碼分析。
SpotBugs 是一個外部外掛程式 - 外部外掛程式需要在可以套用在預先編譯的腳本外掛程式中之前新增為實作相依性
repositories {
gradlePluginPortal() // so that external plugins can be resolved in dependencies section
}
dependencies {
implementation("com.github.spotbugs.snom:spotbugs-gradle-plugin:5.2.1")
testImplementation("junit:junit:4.13")
}
repositories {
gradlePluginPortal() // so that external plugins can be resolved in dependencies section
}
dependencies {
implementation 'com.github.spotbugs.snom:spotbugs-gradle-plugin:5.2.1'
testImplementation platform("org.spockframework:spock-bom:2.2-groovy-3.0")
testImplementation 'org.spockframework:spock-core'
}
tasks.named('test', Test) {
useJUnitPlatform()
}
-
外掛程式的相依性成品座標 (GAV) 可能與外掛程式 ID 不同。
-
Gradle 外掛程式入口網站 (
gradlePluginPortal()
) 新增為外掛程式相依性的儲存庫。 -
外掛程式版本由相依性版本決定。
新增相依性後,即可依 ID 在預先編譯的腳本外掛程式中套用外部外掛程式
plugins {
java
checkstyle
// NOTE: external plugin version is specified in implementation dependency artifact of the project's build file
id("com.github.spotbugs")
}
plugins {
id 'java'
id 'checkstyle'
// NOTE: external plugin version is specified in implementation dependency artifact of the project's build file
id 'com.github.spotbugs'
}
套用其他預先編譯的腳本外掛程式
預先編譯的腳本外掛程式可以套用其他預先編譯的腳本外掛程式。
myproject.library-conventions
外掛程式套用 myproject.java-conventions
外掛程式
plugins {
`java-library`
`maven-publish`
id("myproject.java-conventions")
}
plugins {
id 'java-library'
id 'maven-publish'
id 'myproject.java-conventions'
}
使用主要原始碼集中的類別
預先編譯的腳本外掛程式可以使用在外掛程式專案的主要原始碼集中定義的類別。
在此範例中,myproject.library-conventions
外掛程式使用來自 buildSrc/src/main/java
的自訂工作類別來配置程式庫 README 檢查
val readmeCheck by tasks.registering(com.example.ReadmeVerificationTask::class) {
readme = layout.projectDirectory.file("README.md")
readmePatterns = listOf("^## API$", "^## Changelog$")
}
def readmeCheck = tasks.register('readmeCheck', com.example.ReadmeVerificationTask) {
// Expect the README in the project directory
readme = layout.projectDirectory.file("README.md")
// README must contain a Service API header
readmePatterns = ['^## API$', '^## Changelog$']
}
有關撰寫自訂 Gradle 外掛程式的更多詳細資訊,請參閱使用者手冊。