Gradle copy creates an empty file

I have a multi-project gradle build that copies some source files from the parent project into the build directory and then attempts to overwrite a token in one of the copied files. Everything runs OK but the file ends up being empty. Here’s the file snippet with the template to replace:

---
# file: clients.yaml
#properties shared by all client machines

jmeter_version: "${jmeterVersion}"

Here’s snippet of gradle.properties:

jmeterVersion=3.0

And here are two tasks that suppose to do the trick

/** This task copies files from pdo-shared */
task copyFromCommonProject(type:Copy, dependsOn: configurations.commonProjectContent){
    from configurations.commonProjectContent.collect{ zipTree(it) }
    into "$buildDir"
    /*doLast {
        updateAnsibleTokens.execute()
    }*/
}

task updateAnsibleTokens(type: Copy, dependsOn: copyFromCommonProject) {
   from "$buildDir/commons/ansible/group_vars/clients.yml"
   into "$buildDir/commons/ansible/group_vars/"
   expand(jmeterVersion: "$jmeterVersion")
}

I run this from the parent project as gradle clean :tpcds-benchmark:updateAnsibleTokens

First tasks copies all the files where and as expected it’s the 2nd task that does not work

Please notice commented out doLast section. I tried to run these two tasks as gradle clean :tpcds-benchmark:copyFromCommonProject by uncommenting doLast section and removing dependsOn: copyFromCommonProject from the 2nd task

In both instances client.yml ends up completely empty

P.S. Even if I disable expand(jmeterVersion: “$jmeterVersion”) line I will get an empty file. With some more tests it seems that copying a file on itself will generate an empty file so perhaps I’m just doing it wrong. The same code I have will work if I only change the destination directory

This is a repost from Stackoverflow

Basically I had to reread this manual section to understand the lifecycle better.

Following my original example here’s 2 tasks that will work as intended. The problem as I started to suspect was that attempt to copy and modify client.yml was happening in the configuration cycle before the actual copying from the source was happening. Adding << for the 2nd task ensured that the modification was happening in the execution cycle after the original file was copied

/** This task copies files from pdo-shared */
task copyFromCommonProject(type:Copy, dependsOn: configurations.commonProjectContent){
    from configurations.commonProjectContent.collect{ zipTree(it) }
    into "$buildDir"
}

task updateAnsibleTokens(type: Copy, dependsOn: copyFromCommonProject) << {
   from "$buildDir/commons/ansible/group_vars/clients.yml"
   into "$buildDir/commons/ansible/group_vars/"
   expand(jmeterVersion: "$jmeterVersion")
}