Как я могу заставить расширения Gradle лениво оценивать свойства, которые задаются динамически задачами?
Я довольно новичок в работе с Gradle и пытаюсь разработать плагин, который поможет управлять нумерацией версий. Этот плагин определяет задачу, которая устанавливаетproject.version
свойство проекта, к которому он применяется.
Я пытаюсь сделать так, чтобы это свойство устанавливалось в начале каждой сборки Gradle. С помощьюОтвет Питера на другой вопрос 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.
Я оставляю этот вопрос открытым и нерешенным, так как я все еще хотел бы знать, возможно ли сделать это так, как я планировал. Кроме того, я был бы признателен за любые объяснения того, почему версия публикации назначается после установки версии проекта, и могу ли я зависеть от того, всегда ли это так, или это происходит просто случайно.