Gradle 如何集中渐变生成设置?

Gradle 如何集中渐变生成设置?,gradle,build.gradle,gradle-plugin,gradle-kotlin-dsl,Gradle,Build.gradle,Gradle Plugin,Gradle Kotlin Dsl,假设我正在使用Gradle插件,并在build.Gradle.kts中使用以下代码来确定项目版本: // If release branch, return after incrementing patch version. // Else, return $lastTag-SNAPSHOT. val projectVersion: String by lazy { val versionDetails: groovy.lang.Closure<VersionDetails>

假设我正在使用Gradle插件,并在
build.Gradle.kts
中使用以下代码来确定项目版本:

// If release branch, return after incrementing patch version.
// Else, return $lastTag-SNAPSHOT.
val projectVersion: String by lazy {
    val versionDetails: groovy.lang.Closure<VersionDetails> by extra
    with(versionDetails()) {
        if (!lastTag.matches("^(?:(?:\\d+\\.){2}\\d+)\$".toRegex())) {
            throw GradleException("Tag '$lastTag' doesn't match 'MAJOR.MINOR.PATCH' format")
        }
        // If it detached state, get branch name from GitLab CI env var
        val branch = branchName ?: System.getenv("CI_COMMIT_REF_NAME")
        if (branch?.startsWith("release/") == true) {
            val tokens = lastTag.split('.')
            "${tokens[0]}.${tokens[1]}.${tokens[2].toInt() + commitDistance}"
        } else "$lastTag-SNAPSHOT"
    }
}
//如果发布分支,则在增加补丁版本后返回。
//否则,返回$lastTag快照。
val projectVersion:由lazy生成的字符串{
val versionDetails:groovy.lang.Closure by extra
使用(versionDetails()){
如果(!lastTag.matches(“^(?:(?:\\d+\\){2}\\d+\$”.toRegex())){
抛出GradleException(“标记“$lastTag”与“MAJOR.MINOR.PATCH”格式不匹配”)
}
//如果它处于分离状态,则从GitLab CI env var获取分支名称
val branch=branchName?:System.getenv(“CI提交\引用\名称”)
if(branch?.startsWith(“release/”)==true){
val tokens=lastTag.split('.'))
“${tokens[0]}.${tokens[1]}.${tokens[2].toInt()+CommitInstance}”
}else“$lastTag快照”
}
}
这是可行的,但代码在所有项目中都是重复的,除了极少数项目外,很难维护

这只是一个例子,同样适用于在公司/团队中采用某些约定的其他Gradle任务,例如创建
Dockerfile

集中这些代码以便所有项目都可以使用它们的好方法是什么?请注意,这样的代码通常不是独立存在的,而是依赖于Gradle插件

集中这些代码以便所有项目都可以使用它们的好方法是什么

您需要创建一个用于保存项目约定的

如果在本地安装了Gradle,则可以使用创建骨架插件项目。本地安装Gradle后,只需在新项目目录中运行
Gradle init
,然后按照提示创建插件项目

作为一个具体的例子(假设您像前面提到的那样生成了一个插件项目),要应用您的版本控制约定,插件可以是:

// Plugin's build.gradle.kts
dependencies {
    // Add dependency for plugin, GAV can be found on the plugins page:
    // https://plugins.gradle.org/plugin/com.palantir.git-version
    implementation("com.palantir.gradle.gitversion:gradle-git-version:0.12.3")
}
import com.palantir.gradle.gitversion.VersionDetails
import groovy.lang.Closure
import org.gradle.api.GradleException
import org.gradle.api.Plugin
import org.gradle.api.Project

class VersioningConventionsPlugin : Plugin<Project> {

    override fun apply(project: Project) {
        // Apply plugin to project as you would in the main Gradle build file.
        project.pluginManager.apply("com.palantir.git-version")

        // Configure version conventions
        val projectVersion: String by lazy {

            // Gradle generates some Kotlin DSL code on the fly, in a plugin implementation we don't have that.
            // So we must convert the DSL to the Gradle API.
            val versionDetails: Closure<VersionDetails> = project.extensions.extraProperties.get("versionDetails") as Closure<VersionDetails>

            with(versionDetails.call()) {
                if (!lastTag.matches("^(?:(?:\\d+\\.){2}\\d+)\$".toRegex())) {
                    throw GradleException("Tag '$lastTag' doesn't match 'MAJOR.MINOR.PATCH' format")
                }
                val branch = branchName ?: System.getenv("CI_COMMIT_REF_NAME")
                if (branch?.startsWith("release/") == true) {
                    val tokens = lastTag.split('.')
                    "${tokens[0]}.${tokens[1]}.${tokens[2].toInt() + commitDistance}"
                } else "$lastTag-SNAPSHOT"
            }
        }

        // Set the version as an extra property on the project
        // Accessible via extra["projectVersion"]
        project.extensions.extraProperties["projectVersion"] = projectVersion
    }
}
那么版本控制约定插件可以是:

// Plugin's build.gradle.kts
dependencies {
    // Add dependency for plugin, GAV can be found on the plugins page:
    // https://plugins.gradle.org/plugin/com.palantir.git-version
    implementation("com.palantir.gradle.gitversion:gradle-git-version:0.12.3")
}
import com.palantir.gradle.gitversion.VersionDetails
import groovy.lang.Closure
import org.gradle.api.GradleException
import org.gradle.api.Plugin
import org.gradle.api.Project

class VersioningConventionsPlugin : Plugin<Project> {

    override fun apply(project: Project) {
        // Apply plugin to project as you would in the main Gradle build file.
        project.pluginManager.apply("com.palantir.git-version")

        // Configure version conventions
        val projectVersion: String by lazy {

            // Gradle generates some Kotlin DSL code on the fly, in a plugin implementation we don't have that.
            // So we must convert the DSL to the Gradle API.
            val versionDetails: Closure<VersionDetails> = project.extensions.extraProperties.get("versionDetails") as Closure<VersionDetails>

            with(versionDetails.call()) {
                if (!lastTag.matches("^(?:(?:\\d+\\.){2}\\d+)\$".toRegex())) {
                    throw GradleException("Tag '$lastTag' doesn't match 'MAJOR.MINOR.PATCH' format")
                }
                val branch = branchName ?: System.getenv("CI_COMMIT_REF_NAME")
                if (branch?.startsWith("release/") == true) {
                    val tokens = lastTag.split('.')
                    "${tokens[0]}.${tokens[1]}.${tokens[2].toInt() + commitDistance}"
                } else "$lastTag-SNAPSHOT"
            }
        }

        // Set the version as an extra property on the project
        // Accessible via extra["projectVersion"]
        project.extensions.extraProperties["projectVersion"] = projectVersion
    }
}
导入com.palantir.gradle.gitversion.VersionDetails
导入groovy.lang.Closure
导入org.gradle.api.GradleException
导入org.gradle.api.Plugin
导入org.gradle.api.Project
类VersioningConventionsPlugin:插件{
覆盖应用(项目:项目){
//将插件应用到项目中,就像在主Gradle构建文件中一样。
project.pluginManager.apply(“com.palantir.git版本”)
//配置版本约定
val projectVersion:由lazy生成的字符串{
//Gradle会动态生成一些Kotlin DSL代码,在插件实现中,我们没有这样的代码。
//因此,我们必须将DSL转换为GradleAPI。
val versionDetails:Closure=project.extensions.extraProperties.get(“versionDetails”)作为闭包
使用(versionDetails.call()){
如果(!lastTag.matches(“^(?:(?:\\d+\\){2}\\d+\$”.toRegex())){
抛出GradleException(“标记“$lastTag”与“MAJOR.MINOR.PATCH”格式不匹配”)
}
val branch=branchName?:System.getenv(“CI提交\引用\名称”)
if(branch?.startsWith(“release/”)==true){
val tokens=lastTag.split('.'))
“${tokens[0]}.${tokens[1]}.${tokens[2].toInt()+CommitInstance}”
}else“$lastTag快照”
}
}
//将版本设置为项目的额外属性
//可通过extra[“projectVersion”]访问
project.extensions.extraProperties[“projectVersion”]=projectVersion
}
}
我给出了一个Kotlin示例,因为您的示例使用了Kotlin DSL。一旦完成了约定插件的开发工作,就可以发布到存储库,如。如果是公司内部插件,则将其发布到内部插件或类似插件


有关发布的更多详细信息,请参阅插件的文档。Gradle插件可以像任何其他工件/JAR一样发布。

我的当前团队将构建的所有(公共)部分作为Gradle插件进行维护,该插件应用于团队的所有项目。Gradle插件可以包含与构建文件本身几乎相同的内容,从属性和任务声明到应用整个其他插件。我认为这也可能是这种情况下的一种选择——从版本处理开始,并在必要时扩展required@RolandKreuzer我知道Gradle插件声明了新任务,但没有新属性;我也不清楚Gradle插件如何过渡地应用其他插件。在删除专有信息后,您是否可以发布一个带有您所引用插件片段的答案?因此,应用所示插件的项目将可以访问其构建文件中的变量
projectVersion
?或者它仅在
版本约定plugin
中可用?最后,你是从哪里想到这种“衍生”插件的,你能参考一些文档吗?正确。至于这个想法,你说你想把逻辑集中到一个地方。这是我在回答中链接的Gradle插件文档的第一行:Gradle插件打包了可重用的构建逻辑,可以在许多不同的项目和构建中使用。对不起,你是说下游项目中是否有
projectVersion
可用?我用一个词回答:正确。但是为了扩展,在上面的示例中,我在
extra
属性上设置了
projectVersion
。因此,它适用于任何应用插件的项目。