gpt4 book ai didi

gradle - 如何让 Gradle 扩展懒惰地评估由任务动态设置的属性?

转载 作者:行者123 更新时间:2023-12-04 08:48:35 24 4
gpt4 key购买 nike

我对使用 Gradle 还很陌生,我正在尝试开发一个有助于管理版本编号的插件。这个插件定义了一个设置 project.version 的任务。它应用到的项目的属性。

我想要做的是让它在每个 Gradle 构建开始时设置此属性。使用 Peter's answer to another Gradle question ,通过添加 gradle.startParameter.taskNames = [":setProjectVersionNumber"] + gradle.startParameter.taskNames,我设法让我的任务在任何其他任务之前执行。在我的插件 apply 中方法。

但是,其他插件(特别是“Maven-publish”)依赖于在配置阶段指定的版本:

publishing {
publications {
somePublication(MavenPublication) {
version = project.version
}
}
}

我想知道的是,是否有一种方法可以对 version 之类的属性进行评估。在这些扩展中尽可能地懒惰——这样在依赖它们的任务被调用之前它们不会被评估,在这种情况下可能是 :publishToMavenLocal .

下面是一个 SSCCE,它展示了我希望实现的目标:
// This would be included within the plugin
class SetProjectVersionNumber extends DefaultTask {

@TaskAction
void start() {
// This will set project.version during execution phase
project.version = "1.2.3"
logger.info "Set project version number: $project.version"
}
}

task setProjectVersionNumber(type: SetProjectVersionNumber)

// Imagine this block being replaced by a maven 'publishing' block (or something similar)
ext {
version = project.version

// This will print 'unspecified', as it's evaluated during configuration phase
println "In extension, setting version=$project.version"
}

如果你能提供一个制作方法 ext.version等于 1.2.3在上面的例子中,我相信你已经解决了我的问题。

如果这要求太多,我可能会让我的插件在配置时而不是执行时生成版本字符串。不过,很高兴知道我是否可以这样做。

编辑

在一个实验分支中,我尝试将所有版本字符串分配逻辑移动到配置阶段(通过在插件应用程序而不是在任务执行期间全部发生),但我不相信这会起作用,因为插件扩展没有尚未处理并尝试引用其中定义的属性失败。

编辑 2

将版本字符串分配逻辑包装在 project.afterEvaluate 中关闭似乎有效:
@Override
public void apply(Project project) {
logger = project.logger
project.extensions.create(EXTENSION_NAME, SemVerPluginExtension)

project.afterEvaluate {
setVersionProjectNumber(project)
addTasks(project)
}
}

在一个模拟项目中,我实现了 build.gradle如下:
apply plugin: 'semver'
apply plugin: 'maven-publish'

group = 'temp'

buildscript {
repositories {
mavenLocal()
jcenter()
}
dependencies {
classpath 'com.github.tagc:semver-plugin:0.2.2'
}
}

semver {
versionFilePath = 'version.properties'
}

publishing {
publications {
testPublication(MavenPublication) {
version = project.version
assert version
println "Set publication version to $version"
}
}
}

出于某种原因,这似乎有效。尽管版本字符串分配逻辑包含在 'afterEvaluate' 闭包中并且测试发布版本分配不是,但前者仍然发生在后者之前:
Compiling build file '/Users/davidfallah/Documents/semver/TestSemver2/build.gradle' using StatementExtractingScriptTransformer.
Compiling build file '/Users/davidfallah/Documents/semver/TestSemver2/build.gradle' using BuildScriptTransformer.
VERSION FILE PATH=version.properties
Current Git branch: develop
Set project version to 0.2.1-SNAPSHOT
Set publication version to 0.2.1-SNAPSHOT
All projects evaluated.

我将这个问题悬而未决,因为我仍然想知道是否可以按照我最初的意图来做。此外,我希望您能解释一下为什么在设置项目版本后分配发布版本,以及我是否可以依赖于始终如此,或者这是否只是偶然发生。

最佳答案

您可以使用 lazy instantiation of GStrings在运行时评估属性:

project.tasks.create("example_task", Exec.class, {
commandLine 'echo', "${-> project.someproperty}"
})

请注意,您必须使用引号而不是撇号 - "${...}"有效,但 '${...}'才不是。

关于gradle - 如何让 Gradle 扩展懒惰地评估由任务动态设置的属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27682676/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com