Como faço para que as extensões Gradle avaliem preguiçosamente propriedades que são definidas dinamicamente por tarefas?

Eu sou muito novo em trabalhar com Gradle e estou tentando desenvolver um plugin que ajude a gerenciar a numeração de versões. Este plugin define uma tarefa que define oproject.version propriedade do projeto ao qual é aplicado.

O que estou tentando fazer é fazer com que essa propriedade seja definida no início de cada compilação Gradle. UsandoA resposta de Peter para outra pergunta sobre Gradle, Consegui executar minha tarefa antes de qualquer outra adicionandogradle.startParameter.taskNames = [":setProjectVersionNumber"] + gradle.startParameter.taskNames dentro do meu pluginapply método.

No entanto, outros plugins (principalmente 'publicação Maven') dependem da versão especificada durante a fase de configuração:

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

O que eu gostaria de saber é se existe uma maneira de fazer a avaliação de propriedades comoversion nessas extensões o mais preguiçoso possível - de modo que elas não sejam avaliadas até que uma tarefa que dependa delas seja chamada, que nesse caso pode ser:publishToMavenLocal.

Abaixo está um SSCCE que demonstra o que espero alcançar:

// 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"
}

Se você pode fornecer uma maneira de fazerext.version igual1.2.3 no exemplo acima, acredito que você resolveu meu problema.

Se isso estiver pedindo muito, talvez seja possível fazer meu plug-in gerar a string de versão no momento da configuração, em vez do tempo de execução. Seria bom saber se eu poderia fazer dessa maneira, no entanto.

EDITAR

Em um ramo experimental, tentei mover toda a lógica de atribuição de cadeia de versão para a fase de configuração (fazendo tudo acontecer durante a aplicação do plug-in e não durante a execução da tarefa), mas não acredito que isso funcione, pois a extensão do plug-in não ainda foi processado e a tentativa de se referir às propriedades definidas nele falhou.

EDIT 2

Quebrando a lógica de atribuição de cadeia de versão em umproject.afterEvaluate o fechamento parece ter funcionado:

@Override
public void apply(Project project) {
    logger = project.logger
    project.extensions.create(EXTENSION_NAME, SemVerPluginExtension)

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

Em um projeto simulado, eu implementobuild.gradle do seguinte modo:

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"
        }
    }
}

Por alguma razão, isso parece funcionar. Embora a lógica de atribuição de cadeia de versão esteja envolvida em um fechamento 'afterEvaluate' e a atribuição de versão de publicação de teste não seja, a primeira ainda ocorre antes da segunda:

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.

Estou deixando esta questão em aberto e sem solução, pois ainda gostaria de saber se é possível fazê-lo da maneira que pretendia originalmente. Além disso, eu apreciaria qualquer explicação sobre por que a versão da publicação é atribuída após a versão do projeto ser definida e se posso depender disso sempre, ou se isso está acontecendo agora por acidente.

questionAnswers(1)

yourAnswerToTheQuestion