版本目錄是一個選定的相依性列表,可在建置腳本中參考,簡化相依性管理。

您可以從版本目錄中選取相依性,而無需直接使用字串表示法指定相依性

build.gradle.kts
dependencies {
    implementation(libs.groovy.core)
}
build.gradle
dependencies {
    implementation(libs.groovy.core)
}

在此範例中,libs 代表目錄,而 groovy 是其中可用的相依性。

其中定義 libs.groovy.core 的版本目錄是 gradle 目錄中的 libs.versions.toml 檔案

gradle/libs.versions.toml
[libraries]
groovy-core = { group = "org.codehaus.groovy", name = "groovy", version = "3.0.5" }

版本目錄提供多項優勢

  • 類型安全存取器:Gradle 為每個目錄產生類型安全存取器,在 IDE 中啟用自動完成功能。

  • 集中式版本管理:每個目錄對於建置中的所有專案都是可見的。

  • 相依性套件:目錄可以將常用的相依性分組到 套件 中。

  • 版本分離:目錄可以將相依性座標與版本資訊分離,允許共用版本宣告。

  • 衝突解決:與常規相依性表示法一樣,版本目錄宣告請求的 版本,但在 衝突解決 期間不強制執行它們。

雖然版本目錄定義了版本,但它們不會影響相依性解析過程。由於相依性圖表衝突或透過平台或相依性管理 API 套用的約束,Gradle 仍然可能選擇不同的版本。

目錄中宣告的版本通常不會強制執行,這表示建置中使用的實際版本可能會因相依性解析而異。

存取目錄

若要存取在位於 gradle 目錄中的標準 libs.versions.toml 檔案中定義的版本目錄中的項目,您可以在建置腳本中使用 libs 物件。例如,若要參考程式庫,您可以使用 libs.<別名>,而對於外掛程式,您可以使用 libs.plugins.<別名>

使用版本目錄宣告相依性

build.gradle.kts
dependencies {
    implementation(libs.groovy.core)
    implementation(libs.groovy.json)
    implementation(libs.groovy.nio)
}
build.gradle
dependencies {
    implementation libs.groovy.core
    implementation libs.groovy.json
    implementation libs.groovy.nio
}

與以下相同

build.gradle.kts
dependencies {
    implementation("org.codehaus.groovy:groovy:3.0.5")
    implementation("org.codehaus.groovy:groovy-json:3.0.5")
    implementation("org.codehaus.groovy:groovy-nio:3.0.5")
}
build.gradle
dependencies {
    implementation 'org.codehaus.groovy:groovy:3.0.5'
    implementation 'org.codehaus.groovy:groovy-json:3.0.5'
    implementation 'org.codehaus.groovy:groovy-nio:3.0.5'
}

存取器直接對應到 TOML 檔案中定義的別名和版本,提供對相依性和外掛程式的類型安全存取。這使 IDE 能夠提供自動完成、醒目提示錯字,並將遺失的相依性識別為錯誤。

別名和類型安全存取器

版本目錄中的別名由以破折號 (-)、底線 (_) 或點 (.) 分隔的識別碼組成。類型安全存取器是為每個別名產生的,標準化為點表示法

範例別名 產生的存取器

guava

libs.guava

groovy-core

libs.groovy.core

androidx.awesome.lib

libs.androidx.awesome.lib

建立目錄

版本目錄通常使用位於根建置的 gradle 子目錄中的 libs.versions.toml 檔案宣告

gradle/libs.versions.toml
[versions]
groovy = "3.0.5"
checkstyle = "8.37"

[libraries]
groovy-core = { module = "org.codehaus.groovy:groovy", version.ref = "groovy" }
groovy-json = { module = "org.codehaus.groovy:groovy-json", version.ref = "groovy" }
groovy-nio = { module = "org.codehaus.groovy:groovy-nio", version.ref = "groovy" }
commons-lang3 = { group = "org.apache.commons", name = "commons-lang3", version = { strictly = "[3.8, 4.0[", prefer="3.9" } }

[bundles]
groovy = ["groovy-core", "groovy-json", "groovy-nio"]

[plugins]
versions = { id = "com.github.ben-manes.versions", version = "0.45.0" }

TOML 目錄格式

TOML 檔案有四個區段

  • [versions] – 宣告版本識別碼。

  • [libraries] – 將別名對應到 GAV 座標。

  • [bundles] – 定義相依性套件。

  • [plugins] – 宣告外掛程式版本。

TOML 檔案格式非常寬鬆,可讓您將「點狀」屬性寫為完整物件宣告的捷徑。

版本

版本可以宣告為單一字串(在這種情況下,它們被解釋為必要版本),或宣告為 豐富版本

[versions]
other-lib = "5.5.0" # Required version
my-lib = { strictly = "[1.0, 2.0[", prefer = "1.2" } # Rich version

版本宣告的支援成員包括

程式庫

每個程式庫都對應到 GAV 座標:群組、Artifact、版本。它們可以宣告為簡單字串(在這種情況下,它們被解釋為座標),或宣告為個別的群組和名稱

[versions]
common = "1.4"

[libraries]
my-lib = "com.mycompany:mylib:1.4"
my-lib-no-version.module = "com.mycompany:mylib"
my-other-lib = { module = "com.mycompany:other", version = "1.4" }
my-other-lib2 = { group = "com.mycompany", name = "alternate", version = "1.4" }
mylib-full-format = { group = "com.mycompany", name = "alternate", version = { require = "1.4" } }

[plugins]
short-notation = "some.plugin.id:1.4"
long-notation = { id = "some.plugin.id", version = "1.4" }
reference-notation = { id = "some.plugin.id", version.ref = "common" }

您也可以使用 strictlyprefer 定義嚴格或偏好版本

[libraries]
commons-lang3 = { group = "org.apache.commons", name = "commons-lang3", version = { strictly = "[3.8, 4.0[", prefer = "3.9" } }

如果您想要參考在 [versions] 區段中宣告的版本,請使用 version.ref 屬性

[versions]
some = "1.4"

[libraries]
my-lib = { group = "com.mycompany", name="mylib", version.ref="some" }

套件

套件將多個程式庫別名分組,以便可以在建置腳本中一起參考它們。

[versions]
groovy = "3.0.9"

[libraries]
groovy-core = { group = "org.codehaus.groovy", name = "groovy", version.ref = "groovy" }
groovy-json = { group = "org.codehaus.groovy", name = "groovy-json", version.ref = "groovy" }
groovy-nio = { group = "org.codehaus.groovy", name = "groovy-nio", version.ref = "groovy" }

[bundles]
groovy = ["groovy-core", "groovy-json", "groovy-nio"]

這對於使用單一別名引入多個相關的相依性非常有用

build.gradle.kts
dependencies {
    implementation(libs.bundles.groovy)
}
build.gradle
dependencies {
    implementation libs.bundles.groovy
}

外掛程式

此區段透過將外掛程式 ID 對應到版本號碼來定義外掛程式及其版本。就像程式庫一樣,您可以使用 [versions] 區段中的別名定義外掛程式版本,或直接指定版本。

[plugins]
versions = { id = "com.github.ben-manes.versions", version = "0.45.0" }

可以使用 plugins {} 區塊在建置的任何專案中存取它。若要從目錄參考外掛程式,請使用 alias() 函數

build.gradle.kts
plugins {
    `java-library`
    checkstyle
    alias(libs.plugins.versions)
}
build.gradle
plugins {
    id 'java-library'
    id 'checkstyle'
    // Use the plugin `versions` as declared in the `libs` version catalog
    alias(libs.plugins.versions)
}
您無法在設定檔或設定外掛程式中使用在版本目錄中宣告的外掛程式。

避免子群組存取器

若要避免產生子群組存取器,請使用 camelCase 表示法

別名 存取器

groovyCore

libs.groovyCore

groovyJson-core

libs.groovyJson.core

保留關鍵字

某些關鍵字(如 extensionsclassconvention)是保留字,不能用作別名。此外,bundlesversionsplugins 不能是相依性別名中的第一個子群組。

例如,別名 versions-dependency 無效,但 versionsDependencydependency-versions 有效。

發布目錄

在大多數情況下,gradle/libs.versions.toml 將被簽入儲存庫,並可供取用。

但是,這並不總是解決在組織內或針對外部消費者共用目錄的問題。共用目錄的另一種選項是撰寫設定外掛程式,將其發布到 Gradle 外掛程式入口網站或內部儲存庫,並讓消費者在其設定檔中套用該外掛程式。

或者,Gradle 提供了一個版本目錄外掛程式,該外掛程式能夠宣告和發布目錄。

若要執行此操作,您需要套用 version-catalog 外掛程式

build.gradle.kts
plugins {
    `version-catalog`
    `maven-publish`
}
build.gradle
plugins {
    id 'version-catalog'
    id 'maven-publish'
}

然後,此外掛程式將公開 目錄擴充功能,您可以使用它來宣告目錄

build.gradle.kts
catalog {
    // declare the aliases, bundles and versions in this block
    versionCatalog {
        library("my-lib", "com.mycompany:mylib:1.2")
    }
}
build.gradle
catalog {
    // declare the aliases, bundles and versions in this block
    versionCatalog {
        library('my-lib', 'com.mycompany:mylib:1.2')
    }
}

外掛程式必須以程式設計方式建立,請參閱 程式化目錄 以取得詳細資訊。

然後,可以透過套用 maven-publishivy-publish 外掛程式並配置發布以使用 versionCatalog 組件來發布此類目錄

build.gradle.kts
publishing {
    publications {
        create<MavenPublication>("maven") {
            from(components["versionCatalog"])
        }
    }
}
build.gradle
publishing {
    publications {
        maven(MavenPublication) {
            from components.versionCatalog
        }
    }
}

發布此類專案時,將自動產生(和上傳)libs.versions.toml 檔案,然後可以從其他 Gradle 建置取用

匯入已發布的目錄

版本目錄外掛程式 產生的目錄可以透過 Settings API 匯入

settings.gradle.kts
dependencyResolutionManagement {
    versionCatalogs {
        create("libs") {
            from("com.mycompany:catalog:1.0")
        }
    }
}
settings.gradle
dependencyResolutionManagement {
    versionCatalogs {
        libs {
            from("com.mycompany:catalog:1.0")
        }
    }
}

從檔案匯入目錄

Gradle 會自動匯入 gradle 目錄中名為 libs.versions.toml 的目錄。

版本目錄建置器 API 允許從外部檔案匯入目錄,從而在建置的不同部分之間啟用重複使用,例如與 buildSrc 共用主要建置的目錄。

例如,您可以依照下列方式在 buildSrc/settings.gradle(.kts) 檔案中包含目錄

settings.gradle.kts
dependencyResolutionManagement {
    versionCatalogs {
        create("libs") {
            from(files("../gradle/libs.versions.toml"))
        }
    }
}
settings.gradle
dependencyResolutionManagement {
    versionCatalogs {
        libs {
            from(files("../gradle/libs.versions.toml"))
        }
    }
}

VersionCatalogBuilder.from(Object dependencyNotation) 方法僅接受單一檔案,這表示像 Project.files(java.lang.Object…​) 這樣的表示法必須參考一個檔案。否則,建置將會失敗。

請記住,如果名為 libs.versions.toml 的版本目錄位於您的 gradle 資料夾中,則不需要匯入它。它將會自動匯入。

但是,如果您需要從多個檔案匯入版本目錄,建議使用程式碼式方法,而不是依賴 TOML 檔案。這種方法允許從不同檔案宣告多個目錄

settings.gradle.kts
dependencyResolutionManagement {
    versionCatalogs {
        // declares an additional catalog, named 'testLibs', from the 'test-libs.versions.toml' file
        create("testLibs") {
            from(files("gradle/test-libs.versions.toml"))
        }
    }
}
settings.gradle
dependencyResolutionManagement {
    versionCatalogs {
        // declares an additional catalog, named 'testLibs', from the 'test-libs.versions.toml' file
        testLibs {
            from(files('gradle/test-libs.versions.toml'))
        }
    }
}

匯入多個目錄

您可以宣告多個目錄,透過使用 Settings API 來更好地組織相依性

settings.gradle.kts
dependencyResolutionManagement {
    versionCatalogs {
        create("libs") {
            from(files("gradle/libs.versions.toml"))
        }
        create("tools") {
            from(files("gradle/tools.versions.toml"))
        }
    }
}
build.gradle.kts
dependencies {
    implementation(libs.someDependency)
    implementation(tools.someTool)
}

為了最大限度地減少命名衝突的風險,每個目錄都會產生一個套用到所有專案的擴充功能,因此建議選擇唯一的名稱。一種有效的方法是選擇以 Libs 結尾的名稱。

變更目錄名稱

預設情況下,libs.versions.toml 檔案用作 libs 目錄的輸入。但是,如果已存在具有相同名稱的擴充功能,您可以重新命名預設目錄

settings.gradle.kts
dependencyResolutionManagement {
    defaultLibrariesExtensionName = "projectLibs"
}
settings.gradle
dependencyResolutionManagement {
    defaultLibrariesExtensionName = 'projectLibs'
}

覆寫目錄版本

您可以在匯入目錄時覆寫版本

settings.gradle.kts
dependencyResolutionManagement {
    versionCatalogs {
        create("amendedLibs") {
            from("com.mycompany:catalog:1.0")
            // overwrite the "groovy" version declared in the imported catalog
            version("groovy", "3.0.6")
        }
    }
}
settings.gradle
dependencyResolutionManagement {
    versionCatalogs {
        amendedLibs {
            from("com.mycompany:catalog:1.0")
            // overwrite the "groovy" version declared in the imported catalog
            version("groovy", "3.0.6")
        }
    }
}

在上述範例中,任何參考 groovy 版本的相依性都將自動更新為使用 3.0.6

覆寫版本僅影響匯入和宣告相依性時使用的內容。由於衝突解決,實際解析的相依性版本可能會有所不同。

程式化目錄

版本目錄可以透過程式化方式在 settings.gradle(.kts) 檔案中宣告。

settings.gradle.kts
dependencyResolutionManagement {
    versionCatalogs {
        create("libs") {
            version("groovy", "3.0.5")
            version("checkstyle", "8.37")
            library("groovy-core", "org.codehaus.groovy", "groovy").versionRef("groovy")
            library("groovy-json", "org.codehaus.groovy", "groovy-json").versionRef("groovy")
            library("groovy-nio", "org.codehaus.groovy", "groovy-nio").versionRef("groovy")
            library("commons-lang3", "org.apache.commons", "commons-lang3").version {
                strictly("[3.8, 4.0[")
                prefer("3.9")
            }
        }
    }
}
settings.gradle
dependencyResolutionManagement {
    versionCatalogs {
        libs {
            version('groovy', '3.0.5')
            version('checkstyle', '8.37')
            library('groovy-core', 'org.codehaus.groovy', 'groovy').versionRef('groovy')
            library('groovy-json', 'org.codehaus.groovy', 'groovy-json').versionRef('groovy')
            library('groovy-nio', 'org.codehaus.groovy', 'groovy-nio').versionRef('groovy')
            library('commons-lang3', 'org.apache.commons', 'commons-lang3').version {
                strictly '[3.8, 4.0['
                prefer '3.9'
            }
        }
    }
}
如果您在專案中有預設的 libs.versions.toml,請勿將 libs 用於您的程式化版本目錄名稱。

以程式設計方式建立版本目錄會使用 Settings API

settings.gradle.kts
dependencyResolutionManagement {
    versionCatalogs {
        create("libs") {
            version("groovy", "3.0.5")
            version("checkstyle", "8.37")
            library("groovy-core", "org.codehaus.groovy", "groovy").versionRef("groovy")
            library("groovy-json", "org.codehaus.groovy", "groovy-json").versionRef("groovy")
            library("groovy-nio", "org.codehaus.groovy", "groovy-nio").versionRef("groovy")
            library("commons-lang3", "org.apache.commons", "commons-lang3").version {
                strictly("[3.8, 4.0[")
                prefer("3.9")
            }
            bundle("groovy", listOf("groovy-core", "groovy-json", "groovy-nio"))
        }
    }
}
settings.gradle
dependencyResolutionManagement {
    versionCatalogs {
        libs {
            version('groovy', '3.0.5')
            version('checkstyle', '8.37')
            library('groovy-core', 'org.codehaus.groovy', 'groovy').versionRef('groovy')
            library('groovy-json', 'org.codehaus.groovy', 'groovy-json').versionRef('groovy')
            library('groovy-nio', 'org.codehaus.groovy', 'groovy-nio').versionRef('groovy')
            library('commons-lang3', 'org.apache.commons', 'commons-lang3').version {
                strictly '[3.8, 4.0['
                prefer '3.9'
            }
            bundle('groovy', ['groovy-core', 'groovy-json', 'groovy-nio'])
        }
    }
}