設定檔是每個 Gradle 建置的進入點。

author gradle 7

在 Gradle 建置生命週期的早期,初始化階段會在您的專案根目錄中尋找設定檔。

當找到設定檔 settings.gradle(.kts) 時,Gradle 會實例化一個 Settings 物件。

Settings 物件的用途之一是讓您宣告要包含在建置中的所有專案。

設定腳本

設定腳本可以是 Groovy 中的 settings.gradle 檔案,或是 Kotlin 中的 settings.gradle.kts 檔案。

在 Gradle 組裝建置的專案之前,它會建立一個 Settings 實例,並針對它執行設定檔。

Settings

當設定腳本執行時,它會配置此 Settings。因此,「設定檔」會定義 Settings 物件。

Settings 實例和 settings.gradle(.kts) 檔案之間存在一對一的對應關係。

Settings 物件

Settings 物件是 Gradle API 的一部分。

  • 在 Groovy DSL 中,Settings 物件的文件位於此處

  • 在 Kotlin DSL 中,Settings 物件的文件位於此處

設定腳本中的許多頂層屬性和區塊都是 Settings API 的一部分。

例如,我們可以使用 Settings.rootProject 屬性在設定腳本中設定根專案名稱

settings.rootProject.name = "application"

通常縮寫為

settings.gradle.kts
rootProject.name = "application"
settings.gradle
rootProject.name = 'application'

標準 Settings 屬性

Settings 物件在您的設定腳本中公開一組標準屬性。

下表列出了一些常用的屬性

名稱 描述

buildCache

建置快取配置。

plugins

已應用於設定的外掛容器。

rootDir

建置的根目錄。根目錄是根專案的專案目錄。

rootProject

建置的根專案。

settings

傳回此設定物件。

下表列出了一些常用的方法

名稱 描述

include()

將給定的專案新增至建置。

includeBuild()

將指定路徑的建置包含到複合建置中。

設定腳本結構

Settings 腳本是一系列對 Gradle API 的方法呼叫,這些呼叫通常使用 { …​ },這是 Groovy 和 Kotlin 語言中的特殊快捷方式。{ } 區塊在 Kotlin 中稱為lambda,在 Groovy 中稱為closure

簡而言之,plugins{ } 區塊是一個方法調用,其中 Kotlin lambda 物件或 Groovy closure 物件作為引數傳遞。它是以下簡短形式:

plugins(function() {
    id("plugin")
})

區塊會對應到 Gradle API 方法。

函數內部的程式碼是針對名為 receiverthis 物件(在 Kotlin lambda 中)和 delegatethis 物件(在 Groovy closure 中)執行的。Gradle 會判斷正確的 this 物件並調用正確的對應方法。方法調用 id("plugin") 物件的 this 類型為 PluginDependenciesSpec

設定檔是由建立在 DSL 之上的 Gradle API 呼叫組成。Gradle 會逐行、從上到下執行腳本。

讓我們看看一個範例並將其分解

settings.gradle.kts
pluginManagement {  (1)
    repositories {
        gradlePluginPortal()
    }
}

plugins {   (2)
    id("org.gradle.toolchains.foojay-resolver-convention") version "0.9.0"
}

rootProject.name = "simple-project"     (3)

dependencyResolutionManagement {    (4)
    repositories {
        mavenCentral()
    }
}

include("sub-project-a")     (5)
include("sub-project-b")
include("sub-project-c")
settings.gradle
pluginManagement {  (1)
    repositories {
        gradlePluginPortal()
    }
}

plugins {   (2)
    id("org.gradle.toolchains.foojay-resolver-convention") version "0.9.0"
}

rootProject.name = 'simple-project'     (3)

dependencyResolutionManagement {    (4)
    repositories {
        mavenCentral()
    }
}

include("sub-project-a")    (5)
include("sub-project-b")
include("sub-project-c")
1 定義外掛的位置
2 應用設定外掛。
3 定義根專案名稱。
4 定義依賴解析策略。
5 將子專案新增至建置。

1. 定義外掛的位置

設定檔可以使用 pluginManagement 區塊來管理您建置的外掛版本和儲存庫。它提供了一種方式來定義專案中應使用哪些外掛以及應從哪些儲存庫解析它們。

settings.gradle.kts
pluginManagement {  (1)
    repositories {
        gradlePluginPortal()
    }
}
settings.gradle
pluginManagement {  (1)
    repositories {
        gradlePluginPortal()
    }
}

2. 應用設定外掛

設定檔可以選擇性地應用外掛,這些外掛是配置專案設定所必需的。這些通常是 Develocity 外掛Toolchain Resolver 外掛,如下例所示。

在設定檔中應用外掛只會影響 Settings 物件。

settings.gradle.kts
plugins {   (2)
    id("org.gradle.toolchains.foojay-resolver-convention") version "0.9.0"
}
settings.gradle
plugins {   (2)
    id("org.gradle.toolchains.foojay-resolver-convention") version "0.9.0"
}

3. 定義根專案名稱

設定檔使用 rootProject.name 屬性定義您的專案名稱

settings.gradle.kts
rootProject.name = "simple-project"     (3)
settings.gradle
rootProject.name = 'simple-project'     (3)

每個建置只有一個根專案。

4. 定義依賴解析策略

設定檔可以選擇性地定義規則和配置,用於跨專案的依賴解析。它提供了一種集中管理和自訂依賴解析的方式。

settings.gradle.kts
dependencyResolutionManagement {    (4)
    repositories {
        mavenCentral()
    }
}
settings.gradle
dependencyResolutionManagement {    (4)
    repositories {
        mavenCentral()
    }
}

您也可以在此區段中包含版本目錄。

5. 將子專案新增至建置

設定檔使用 include 陳述式新增所有子專案,藉此定義專案的結構

settings.gradle.kts
include("sub-project-a")     (5)
include("sub-project-b")
include("sub-project-c")
settings.gradle
include("sub-project-a")    (5)
include("sub-project-b")
include("sub-project-c")

您也可以使用 includeBuild 包含整個建置。

設定檔腳本編寫

Settings 物件上還有許多屬性和方法,可用於配置您的建置。

重要的是要記住,雖然許多 Gradle 腳本通常以簡短的 Groovy 或 Kotlin 語法編寫,但設定腳本中的每個項目本質上都是在 Gradle API 中的 Settings 物件上調用一個方法

include("app")

實際上是

settings.include("app")

此外,您可以充分利用 Groovy 和 Kotlin 語言的強大功能。

例如,您可以迭代專案根資料夾中的目錄清單並自動包含它們,而不是多次使用 include 來新增子專案

rootDir.listFiles().filter { it.isDirectory && (new File(it, "build.gradle.kts").exists()) }.forEach {
    include(it.name)
}
此類型的邏輯應在外掛中開發。