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

zpf6vheq  于 2023-02-04  发布在  其他
关注(0)|答案(2)|浏览(192)

问题

我设置了各种不同的存储库/项目(即app1app2app3),这些存储库/项目都依赖于base包中的共享功能。
这些项目还使用各种其他第三方依赖项(例如app1app3使用spring,它们都使用kotlinx-serialization).我想同步所有第三方依赖项的版本,这样使用我的基础包的任何项目都使用相同版本的每个第三方依赖项.然而,我不想给不使用新依赖项的项目引入新依赖项(例如app2不使用spring)

解决方案尝试

对于,我已经能够在gradle platform的帮助下解决这个问题,它完全符合我的需要-我在基础包中指定版本,然后将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")
    }
}

这可以正常工作,并将插件以正确的版本应用到我的主项目中。然而,这有2个主要问题:
a)现在每个项目都应用了spring插件,包括app2(它不使用spring)。
b)我有很多插件要管理,不知道如何获得其中大多数插件的长实现字符串。我通过查找https://plugins.gradle.org/上的插件ID,然后查看 * legacy plugin application * 部分找到了"org.springframework.boot:spring-boot-gradle-plugin:3.0.2",听起来我走错了路。

    • 我只想在一个中心位置管理多个项目/repos的插件和库的版本**-这感觉像是一个相当基本的用例--为什么这么难呢?
lymnna71

lymnna711#

为此,我在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"))
}

注意,插件版本在构建脚本中被省略了,因为它已经在设置文件中指定了,还要注意,在设置脚本中访问属性的方法与构建脚本中略有不同。

fae0ux8s

fae0ux8s2#

a)现在每个项目都应用了spring插件,包括app2(它不使用spring)。
避免应用太多插件确实更好-这就是Gradle鼓励对插件做出React的原因。

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") {

        }
    }
}

如果您想以类型安全的方式访问插件或插件的扩展,使用类会很方便。
您可以通过以下方式找到插件的类

  • 在源代码中查找实现Plugin<Project>的类,
  • implementationClass的插件构建配置中,
  • 或者在发布的插件JAR中-在META-INF/gradle-plugins目录中将有一个包含implementationClass的文件。

这对版本对齐问题没有帮助--但我认为这是值得一提的!
B)我有很多插件要管理,不知道如何获得其中大多数插件的长实现字符串。我通过查找https://plugins.gradle.org/上的插件ID,然后查看 legacy plugin application 部分找到了"org.springframework.boot:spring-boot-gradle-plugin:3.0.2",听起来我走错了路。
你在正确的轨道上与“长实现字符串”,因为你叫它。我会提到这些作为'Maven坐标'的插件。

Gradle插件Maven坐标

KotlinJVM插件的 * 插件id* 是org.jetbrains.kotlin.jvm,但是 *Maven坐标 * 是org.jetbrains.kotlin:kotlin-gradle-plugin:1.8.0

“legacy”部分指的是如何使用apply(plugin = "...")语法应用插件,新方法使用plugin {}块,但在幕后,两种方法仍然使用插件的Maven坐标。
如果您将这些Maven坐标(以及版本)添加到您的Java Platform中,那么您就可以将平台导入到您的项目中。

定义插件版本

定义插件的方法有很多,所以我只描述其中一种,碰巧它与使用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
}

相关问题