Lazy evaluation for copy spec filter properties

As threads from the old forum are locked and do not allow new replies, let me continue on this thread that is about how to achieve lazy evaluation of replacement properties for file content filtering in a copy task.

To be more precise, what I want to achieve is lazy evaluation of a property’s value. To illustrate this, this is an example using the GString closure trick:

processResources.filesMatching('*.txt') {
   filter(ReplaceTokens, tokens: [ version: "${ -> configurations.implementation.dependencies.find { it.name == 'quarks-bom' }.version ?: 'unknown' }" ])
}

Unfortunately, that does not work. It results in a ClassCastException as the implementation of ReplaceTokens expects values of type String.

Note that I’m configuring an existing GradleTask processResources.

Coming back to that rather old thread, is there another solution meanwhile, other than creating and using a DeferredReplaceTokens class as it has been outlined in the thread?

You can implement your own Transformer<String, String>.

processResources {
   inputs.files configurations.implementation
   def myTransformer = { in -> in.replace('$version', dependencies.configurations.implementation.find {...})}
   filesMatching('*.txt') {
     filter(myTransformer)
   }
}

See CopySpec.filter(transformer)

Thanks @Lance. Meanwhile I’ve found yet another solution using the expand method. The thing here is that one can use GString expressions for values in the map (which is what I needed):

processResources.filesMatching('*.txt') {
   expand([ version: "${ -> configurations.implementation.dependencies.find { it.name == 'quarks-bom' }.version ?: 'unknown' }" ])
}

The difference is that instead of Ant style tokens of the form @version@ interpolation expressions of the form ${version} need to be used inside the files.