Up-to-date check on Copy does not detect changed input

I have the following build.gradle

def copyFrom1 = fileTree(dir: 'source')
def copyFrom2 = copyFrom1.files

task foo(type: Copy) {
  into 'dest'
  from copyFrom1 // or use copyFrom2

and the following in ‘source’


I execute the script with either copying from copyFrom1 or copyFrom2. For this simple example I modify build.gradle, in my actual project copyFromN is the result of a method call that can returns both cases.

There is a different behaviour in the two cases. With copyFrom1 the directory structure is reproduced in ‘dest’ and you get


with copyFrom2 the structure is ‘flatten’ and you get


(This behaviour surprised me but I assume that is working as designed. If not this is the bug, not the up-to-date check.)

The up-to-date check does not see a difference between these two cases. If you run with copyFrom1 and then again (leaving ‘dest’ as is) with copyFrom2 Gradle says foo is up-to-date. This is clearly wrong since a different result was expected.

I think this topic would be helpful for you.