How can I add a directory to a sourceSet but only for a specific task?

Some documentGeneration task needs to have ‘srcTest’ in its sourceSet. But putting it in the main gradle sourceSet for the sub project is not working. It will break other build tasks.

So how can I add ‘srcTest’ to the list of sourceSets resources for only a specific task?

You’ll need to provide more information.

  1. What type of task is ‘documentGeneration’ 2. What behaviour are you expecting? 3. What behaviour are you experiencing?

documentGeneration is a java task that runs after a system test has been performed. This java program which is executed needs the srctest directory on the classpath. So i’ve put it (as sourceSet) in my main build.gradle for all subprojects in order for the docGen task to run properly. But I need this srctest dir only included for a certain project where this docGen task is defined.

Problem for including srctest for all subprojects is that it is now included twice (once as a source dir, and once as a test-source). The sonar analysis task cannot handle this. So basically I’m trying to work around a sonar problem.

Hope this will help you to help me…

I don’t understand sorry. Perhaps sharing some code will help.

Sorry for the very short explanation. Hope to be more clear now. It concerns a multi project build.

The Java type Gradle task called buildTestDocumentation needs to have a resource directory (‘srctest’) on it’s runtime classpath, but from one of it’s dependencies (project called TRI). Therefore, I added the ‘srctest’ directory as a source entry for all sub projects, like this:

main/build.gradle:
...
subprojects {
 sourceSets {
  main {
   java {
    srcDir 'src'
    srcDir 'srcgenerated'
   }
   resources {
    srcDir 'src'
                                 srcDir 'srctest'
  // WANT TO HAVE THIS FOR project TRI for THE buildTestDoc task only
   }
  }
      test {
   java {
    srcDir 'srctest'
   }
   resources {
    srcDir 'srctest'
    }
  }
}
....

But this is a little bit bombastic for having the srctest resource of a dependency on the classpath for a Java task:

apply plugin: 'java'
task buildTestDocumentation(dependsOn: 'build', type: JavaExec) {
    main = 'com.example.testrunner.BuildTestDocumentation'
    classpath = sourceSets.main.runtimeClasspath // FIXME: Need to have TRI/srctest on classpath as well
    args './build', project.version, 'anotherParam'
 }

Problem with the above setup is that the srctest directory is included twice. Most Gradle tasks don’t have a problem with this, but the sonar task does. It complains about a wrong source encoding which is a result of including the srctest directory twice. Basically, the line that includes ‘srctest’ for the main java sourceSet should not be there.

So I looked a little further and created a solution in the depended project TRI. When I add the sourceSet there under the constraint that buildTestDocumentation must be on the taskGraph, then I can solve my problem, like this: /TRI/build.gradle:

gradle.taskGraph.whenReady {taskGraph ->
    if (taskGraph.hasTask(':TestRunner:buildTestDocumentation')) {
        sourceSets {
            main {
                resources {
                    srcDir 'srctest'
                }
            }
        }
    }
}

Hope this gives the idea and the guidance for anyone running into this same problem

I’d consider doing something like this:

task buildTestDocumentation(dependsOn: 'build', type: JavaExec) {
    main = 'com.example.testrunner.BuildTestDocumentation'
    classpath = sourceSets.main.runtimeClasspath + files("srctest")
    args './build', project.version, 'anotherParam'
 }

That is, modifying the configuration just for that task.

Thanks Luke,

I already tried that. But this will add ‘srctest’ of the current project to the classPath. And I need ‘srctest’ of a dependency project to be added to the classpath. It would be very much easier to copy the missing files to the current project. But that’s a pattern I don’t like. Copying files all over the place is bad. You may ask youself if creating a solution like I did is worse than copying a file, but that’s a completely different solution.