I have a project where Gradle is not copying all test resources to the output dir, and I don't know if I am doing something wrong or if this is a bug in Gradle. I managed to create a simplified test case; the directory structure is as follows:
gradle/ # (contains Gradle wrapper files)
src/
hello/
Hello.java
tests/
hello/
hello.txt
foo/
bar.txt
build.gradle
gradlew
gradle.bat
The contents of build.gradle are as follows:
apply plugin: 'java'
sourceSets {
main {
java.srcDirs = ['src']
resources.srcDirs = ['src']
resources.excludes = ['**/*.java']
}
test {
java.srcDirs = ['tests']
resources.srcDirs = ['tests']
resources.excludes = ['**/*.java']
}
}
task staging (type: Copy) {
from processResources
from processTestResources { include 'foo/' } // Offending line
into "${buildDir}/staging"
}
task run (type: JavaExec) {
dependsOn staging
// [...]
}
When I run:
./gradlew processTestResources # or just ./gradlew test
Only the resources from tests/foo are copied to the output folder. The resources from tests/hello are not copied.
However, if I comment out the line marked as "Offending line" in the staging task, then all resources are copied.
Is this the expected behaviour? Looks like Gradle is trying to calculate which resources are needed, and sees that only tests/foo are necessary for the staging
task. But I am not running the staging
task; I should be able to run the processTestResources
or test
tasks and have all test resources copied to the output folder.
Is this a bug in Gradle?
Update:
Here's a link to the relevant issue in GH (closed as invalid since this is not really a bug, as explained in the accepted answer).
CodePudding user response:
The issue is the way Groovy interprets the "offending line":
Without parenthesis, Groovy interprets everything after from
as the argument.
And so it fetches the reference to the processTestResources
task, applies the configuration closure to it, and then passes the result to from
.
So the end result is that you configured in-line the processTestResources
instead of configuring the from
.
Adding parenthesis changes the meaning by clearly indicating that the result of calling from
with a task is what is to be configured:
from(processTestResources) { include 'foo/' }