Home > Back-end >  Gradle not copying all test resources to output dir
Gradle not copying all test resources to output dir

Time:10-06

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/' } 
  • Related