簡體   English   中英

gradle插件的版本管理如何封裝?

[英]How do I encapsulate version management for gradle plugins?

問題

我設置了各種不同的回購/項目(即app1app2app3 ),它們都依賴於我的base package 中的共享功能。

這些項目還使用了各種其他第三方依賴項(即app1app3使用 spring,它們都使用kotlinx-serialization )。 我想同步所有第三方依賴的版本,這樣任何使用我的基礎 package 的項目都使用相同版本的每個第三方依賴。 但是,我不想為不使用它們的項目引入新的依賴項(即app2不使用spring)

解決方案嘗試

對於圖書館,我已經能夠在 gradle platform的幫助下解決這個問題,這正是我想要的 - 我在我的基礎 package 中指定版本,然后將該platform作為依賴項添加到我的項目中,然后可以簡單地添加依賴項按名稱(即implementation("org.springframework.boot:some-package") )無需指定版本號,因為它使用我的platform提供的值。

但是,對於插件,我無法做到這一點。 許多庫都帶有插件,插件自然應該與庫的版本相同。 我嘗試了各種方法,包括編寫一個獨立的插件,但都沒有奏效。

當前最佳創意

我將implementation("org.springframework.boot:spring-boot-gradle-plugin:3.0.2")添加到我的獨立插件的依賴項中。 然后,我將以下代碼添加到我的獨立插件中:

class BasePlugin : Plugin<Project> {
    override fun apply(target: Project) {
        target.plugins.apply("org.springframework.boot")
    }
}

這有效並將插件以正確的版本應用於我的主項目。 但是,這有兩個主要問題:

a) 現在每個項目都應用spring插件,包括app2 (沒有使用spring)。

b) 我有很多插件要管理,但不知道如何為其中的大多數獲取長實現字符串。 我通過在https://plugins.gradle.org/上查找插件 ID,然后查看遺留插件應用程序部分,找到了"org.springframework.boot:spring-boot-gradle-plugin:3.0.2" ,聽起來我走錯了路。

我只想在一個中心位置管理多個項目/存儲庫的插件和庫的版本——這感覺像是一個相當基本的用例——為什么這么難?

為此,我在gradle.properties文件中使用了版本號。 自從引入了Gradle版本目錄,我的做法可能有點落伍了,不過還是分享一下吧。 它基於這樣一個事實,即可以通過從屬性文件中讀取值來在settings.gradle.kts中管理插件版本。

gradle.properties

springBootVersion=3.0.2

settings.gradle.kts

pluginManagement {
    val springBootVersion: String by settings

    plugins {
        id("org.springframework.boot") version springBootVersion
    }
}

最后在build.gradle.kts中:

plugins {
    id("org.springframework.boot")
}

dependencies {
    val springBootVersion: String by project
    implementation(platform("org.springframework.boot:spring-boot-dependencies:$springBootVersion"))
}

請注意,構建腳本中省略了插件版本,因為它已在設置文件中指定。 另請注意,設置腳本中訪問屬性的方法與構建腳本中的略有不同。

a) 現在每個項目都應用spring插件,包括app2 (沒有使用spring)。

避免應用太多插件確實更好——這就是為什么 Gradle 鼓勵對插件做出反應

import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.kotlin.dsl.*
import org.springframework.boot.gradle.plugin.SpringBootPlugin

class BasePlugin : Plugin<Project> {
    override fun apply(target: Project) {
        // don't apply
        //target.plugins.apply("org.springframework.boot")

        // instead, react!
        target.plugins.withType<SpringBootPlugin>().configureEach {
            // this configuration will only trigger if the project applies both
            // BasePlugin *and* the Spring Boot pluging
        }

        // you can also react based on the plugin ID
        target.pluginManager.withPlugin("org.springframework.boot") {

        }
    }
}

如果您想以類型安全的方式訪問插件或插件的擴展,使用 class 會很方便。

您可以通過以下方式找到插件的 class

  • 查看實現Plugin<Project>的 class 的源代碼,
  • 在插件的implementationClass構建配置中,
  • 或者在已發布的插件 JAR 中 - 在META-INF/gradle-plugins目錄中將有一個具有implementationClass的文件。

這對您的版本 alignment 問題沒有幫助 - 但我認為值得一提!

b) 我有很多插件要管理,但不知道如何為其中的大多數獲取長實現字符串。 我通過在https://plugins.gradle.org/上查找插件 ID,然后查看遺留插件應用程序部分,找到了"org.springframework.boot:spring-boot-gradle-plugin:3.0.2" ,聽起來我走錯了路。

您所說的“長實施字符串”走在正確的軌道上。 我將這些稱為插件的“Maven 坐標”。

Gradle 插件 Maven 坐標

Kotlin JVM 插件的插件idorg.jetbrains.kotlin.jvm ,但是Maven坐標org.jetbrains.kotlin:kotlin-gradle-plugin:1.8.0

Kotlin JVM 插件的 Gradle 插件門戶屏幕截圖,展示了如何使用插件 {} 塊應用插件,與“傳統”`apply(plugin = "org.jetbrains.kotlin.jvm")

'legacy' 部分指的是如何應用插件,使用apply(plugin = "...")語法。 新方法使用plugin {}塊,但在幕后,這兩種方法仍然使用插件的 Maven 坐標。

如果您將這些 Maven 坐標(帶版本)添加到您的Java 平台,那么您可以將該平台導入您的項目。 但是哪里?

定義插件版本

定義插件的方式有很多種,這里只介紹一種,巧合的是兼容Java平台定義版本。

如果你熟悉 buildSrc 約定插件,你就會知道他們可以應用插件,但他們不能定義版本。

// ./buildSrc/src/main/kotlin/kotlin-jvm-convention.gradle.kts

plugins {
  kotlin("jvm") version "1.8.0" // error: pre-compiled script plugins can't set plugin versions!
}

相反,必須在 buildSrc 的構建配置中定義插件版本

// ./buildSrc/build.gradle.kts

plugins {
  `kotlin-dsl`
}

dependencies {
  // the Maven coordinates of the Kotlin JVM plugin - including the version
  implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.8.0")
}

這看起來更傳統,所以我希望下一步是干凈的:使用你的 Java 平台!

將 Java 平台應用於 buildSrc

// ./buildSrc/build.gradle.kts

plugins {
  `kotlin-dsl`
}

dependencies {
  // import your Java Platform
  implementation(platform("my.group:my-platform:1.2.3"))

  // no version necessary - it will be supplied by my.group:my-platform
  implementation("org.jetbrains.kotlin:kotlin-gradle-plugin")
}

請注意,如果您的項目是“包含構建”而不是 buildSrc,則同樣的方法也適用。

一旦在./buildSrc/build.gradle.kts中定義了插件版本,您就可以在整個項目中使用它們(無論是在約定插件中還是在子項目中),它們將被對齊。

// ./subproject-alpha/build.gradle.kts

plugins {
  kotlin("jvm") // no version here - it's defined in buildSrc/build.gradle.kts
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM