初始化腳本是在建置腳本執行之前運行的腳本。它們允許您自訂建置環境或在建置早期配置設定。
初始化腳本對於在多個專案中設定通用配置(例如儲存庫、外掛或自訂任務)非常有用。
使用初始化腳本
初始化腳本,也稱為init 腳本,與 Gradle 中的其他腳本類似。初始化腳本在建置開始之前運行。
它們適用於各種用途
-
設定企業範圍的配置(例如,自訂外掛位置)
-
根據環境配置屬性(例如,開發人員的機器與 CI 伺服器)
-
提供使用者特定資訊(例如,身份驗證憑證)
-
定義機器特定詳細資訊(例如,JDK 位置)
-
註冊建置監聽器(例如,希望監聽 Gradle 事件的外部工具可能會發現這很有用)
-
註冊記錄器(例如,自訂 Gradle 如何記錄其產生的事件)
一個主要的init 腳本限制是它們無法存取 buildSrc
專案中的類別。
調用初始化腳本
有幾種方法可以調用初始化腳本(依優先順序排列)
-
在命令列上使用選項
-I
或--init-script
指定檔案,後跟腳本的路徑。命令列選項可以多次出現,每次都新增另一個初始化腳本。如果命令列上指定的任何檔案不存在,建置將會失敗。
-
將名為
init.gradle(.kts)
的檔案放在$GRADLE_USER_HOME/
目錄中。 -
將名為
yourfilename.init.gradle(.kts)
的檔案放在$GRADLE_USER_HOME/init.d/
目錄中。 -
將名為
yourfilename.init.gradle(.kts)
的檔案放在$GRADLE_HOME/init.d/
目錄中。條目將按字母順序評估。這讓您可以封裝包含自訂建置邏輯和外掛的自訂 Gradle 發行版。您可以將其與 Gradle Wrapper 結合使用,使自訂邏輯可供您企業中的所有建置使用。
如果找到多個初始化腳本,它們將全部按照上述指定的順序執行。
給定目錄中的腳本按字母順序執行。例如,工具可以在命令列上指定初始化腳本,並在主目錄中指定另一個初始化腳本以定義環境。當執行 Gradle 時,這兩個腳本都將運行。
編寫初始化腳本
與 Gradle 建置腳本一樣,初始化腳本是 Groovy 或 Kotlin 腳本。每個初始化腳本都有一個與之關聯的 Gradle 實例。初始化腳本中的任何屬性參考和方法調用都將委託給此 Gradle
實例。
每個初始化腳本都實作 Script 介面。
編寫初始化腳本時,請注意您嘗試存取的參考範圍。例如,從 |
從初始化腳本配置專案
您可以使用初始化腳本來配置建置中的專案。這與在多專案建置中配置專案類似。
以下範例示範如何在評估專案之前從初始化腳本執行額外配置
repositories {
mavenCentral()
}
tasks.register('showRepos') {
def repositoryNames = repositories.collect { it.name }
doLast {
println "All repos:"
println repositoryNames
}
}
allprojects {
repositories {
mavenLocal()
}
}
repositories {
mavenCentral()
}
tasks.register("showRepos") {
val repositoryNames = repositories.map { it.name }
doLast {
println("All repos:")
println(repositoryNames)
}
}
allprojects {
repositories {
mavenLocal()
}
}
此範例使用此功能來配置額外的儲存庫,僅適用於特定環境。
> gradle --init-script init.gradle.kts -q showRepos
All repos:
[MavenLocal, MavenRepo]
> gradle --init-script init.gradle -q showRepos
All repos:
[MavenLocal, MavenRepo]
新增外部相依性
初始化腳本也可以使用 initscript()
方法宣告相依性,傳入一個宣告初始化腳本類別路徑的閉包。
宣告初始化腳本的外部相依性
initscript {
repositories {
mavenCentral()
}
dependencies {
classpath("org.apache.commons:commons-math:2.0")
}
}
initscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'org.apache.commons:commons-math:2.0'
}
}
傳遞給 initscript()
方法的閉包配置 ScriptHandler 實例。您可以透過將相依性新增至 classpath
配置來宣告初始化腳本類別路徑。
這與您宣告 Java 編譯類別路徑的方式相同。您可以使用 宣告相依性中描述的任何相依性類型,專案相依性除外。
宣告初始化腳本類別路徑後,您可以在初始化腳本中使用類別,就像在類別路徑上的任何其他類別一樣。以下範例新增到先前的範例,並使用來自初始化腳本類別路徑的類別。
具有外部相依性的初始化腳本
import org.apache.commons.math.fraction.Fraction
initscript {
repositories {
mavenCentral()
}
dependencies {
classpath("org.apache.commons:commons-math:2.0")
}
}
println(Fraction.ONE_FIFTH.multiply(2))
tasks.register("doNothing")
import org.apache.commons.math.fraction.Fraction
initscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'org.apache.commons:commons-math:2.0'
}
}
println Fraction.ONE_FIFTH.multiply(2)
tasks.register('doNothing')
> gradle --init-script init.gradle.kts -q doNothing
2 / 5
> gradle --init-script init.gradle -q doNothing
2 / 5
套用外掛
外掛可以像 Gradle 建置腳本或 Gradle 設定檔一樣套用於初始化腳本。
在初始化腳本中使用外掛
apply<EnterpriseRepositoryPlugin>()
class EnterpriseRepositoryPlugin : Plugin<Gradle> {
companion object {
const val ENTERPRISE_REPOSITORY_URL = "https://repo.gradle.org/gradle/repo"
}
override fun apply(gradle: Gradle) {
// ONLY USE ENTERPRISE REPO FOR DEPENDENCIES
gradle.allprojects {
repositories {
// Remove all repositories not pointing to the enterprise repository url
all {
if (this !is MavenArtifactRepository || url.toString() != ENTERPRISE_REPOSITORY_URL) {
project.logger.lifecycle("Repository ${(this as? MavenArtifactRepository)?.url ?: name} removed. Only $ENTERPRISE_REPOSITORY_URL is allowed")
remove(this)
}
}
// add the enterprise repository
add(maven {
name = "STANDARD_ENTERPRISE_REPO"
url = uri(ENTERPRISE_REPOSITORY_URL)
})
}
}
}
}
repositories{
mavenCentral()
}
data class RepositoryData(val name: String, val url: URI)
tasks.register("showRepositories") {
val repositoryData = repositories.withType<MavenArtifactRepository>().map { RepositoryData(it.name, it.url) }
doLast {
repositoryData.forEach {
println("repository: ${it.name} ('${it.url}')")
}
}
}
apply plugin: EnterpriseRepositoryPlugin
class EnterpriseRepositoryPlugin implements Plugin<Gradle> {
private static String ENTERPRISE_REPOSITORY_URL = "https://repo.gradle.org/gradle/repo"
void apply(Gradle gradle) {
// ONLY USE ENTERPRISE REPO FOR DEPENDENCIES
gradle.allprojects { project ->
project.repositories {
// Remove all repositories not pointing to the enterprise repository url
all { ArtifactRepository repo ->
if (!(repo instanceof MavenArtifactRepository) ||
repo.url.toString() != ENTERPRISE_REPOSITORY_URL) {
project.logger.lifecycle "Repository ${repo.url} removed. Only $ENTERPRISE_REPOSITORY_URL is allowed"
remove repo
}
}
// add the enterprise repository
maven {
name = "STANDARD_ENTERPRISE_REPO"
url = ENTERPRISE_REPOSITORY_URL
}
}
}
}
}
repositories{
mavenCentral()
}
@Immutable
class RepositoryData {
String name
URI url
}
tasks.register('showRepositories') {
def repositoryData = repositories.collect { new RepositoryData(it.name, it.url) }
doLast {
repositoryData.each {
println "repository: ${it.name} ('${it.url}')"
}
}
}
> gradle --init-script init.gradle.kts -q showRepositories
repository: STANDARD_ENTERPRISE_REPO ('https://repo.gradle.org/gradle/repo')
> gradle --init-script init.gradle -q showRepositories
repository: STANDARD_ENTERPRISE_REPO ('https://repo.gradle.org/gradle/repo')
初始化腳本中的外掛確保在運行建置時僅使用指定的儲存庫。
在初始化腳本中套用外掛時,Gradle 會實例化外掛並調用外掛實例的 Plugin.apply(T) 方法。
gradle
物件作為參數傳遞,可用於配置建置的所有方面。當然,套用的外掛可以作為 初始化腳本的外部相依性 中描述的外部相依性來解析