我对使用 Gradle 很陌生,我正在尝试开发一个有助于管理版本编号的插件。这个插件定义了一个任务来设置project.version
它所应用的项目的属性。
我要做的是让它在每个 Gradle 构建开始时设置此属性。使用Peter 对另一个 Gradle 问题的回答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.
我将这个问题悬而未决,因为我仍然想知道是否有可能按照我最初的意图去做。此外,我希望能解释一下为什么在设置项目版本之后分配发布版本,以及我是否可以依赖这种情况总是如此,或者这是否只是偶然发生的。