Using 'from aTask { into aFolderX }' clause in copy task leads to aTask being reconfigured by this clause

Having a project with this build script:

apply plugin: 'base'

task copyA(type: Copy) {
    from 'data/a'
    into "$buildDir/a"
}

task copyB(type: Copy) {
    from 'data/b'
    into "$buildDir/b"
}

task copyC(type: Copy) {
    from 'data/c'
    into "$buildDir/c"

    from('data/a') {
        into "xa"
    }

    from copyA
    
    from copyB {
        into "xb" 
    }
}

when I invoke gradle clean copyC I get the following output:

├── build
│   ├── a
│   │   └── file-a.txt
│   └── c
│       ├── file-a.txt
│       ├── file-b.txt
│       ├── file-c.txt
│       └── xa
│           └── file-a.txt
└── xb
    └── file-b.txt

But I would expect this:

├── build
│   ├── a
│   │   └── file-a.txt
│   ├── b
│   │   └── file-b.txt       // <-- by copyB
│   └── c
│       ├── file-a.txt
│       ├── file-b.txt
│       ├── file-c.txt
│       └── xa
│           └── file-a.txt
│       └── xb               // <-- by copyC, 'from copyB { into ... }' clause
│           └── file-b.txt

I have found that using ‘into’ clause with ‘from TASK’ leads to reconfigured ‘outer’ task which is IMHO a bug (or at least an unwanted side-effect)

What do you think?

M.

P.S.: tested on Gradle 2.8 and 3.0

I think you’re getting caught by over use of groovy shortcuts.

from copyB {
    ...
}

Is interrupted as

from( copyB {...} )

Which is changing the configuration of copyB.
This should work better

from( copyB ) {
    ...
}