Using builtBy of SourceSetOutput in a plugin?

Should I use ‘builtBy’ in a plugin? My concern is that the output directory of the task depends on the project’s ‘buildDir’. I delay the resolution of the path until the task is really executed. So the user can change ‘buildDir’ after the task is created. But the ‘builtBy’ clause of the ‘SourceSetOutput’ would then be out of sync. Is there some way to keep both settings synchronised?

I don’t understand the question/concern. What kind of task are we talking about? How would it affect ‘SourceSetOutput.builtBy’? Can you give a concrete example?

I have a task which generates files which are to be included in a jar. I have a setup similar to the one in the user guide.

In the plugin:

project.sourceSets.all { set ->
    def destDir = "${project.buildDir}/some-task/${set.name}"
      project.task("someTask", type: SomeTask) {
        destinationDir = destDir
    }
      set.output.dir destDir, builtBy: "someTask"
}

However, assume the user changes the definition of ‘buildDir’.

apply plugin: "some-task-containing-plugin"
  buildDir = file("dliub")

Most of gradle proper (java, scala, groovy, etc) will pick-up the change. My plugin won’t. On the other hand: all named plugins do low-level magic and don’t use ‘builtBy’. (The antlr plugin doesn’t neither, but may suffer from a similar issue when setting the output directory for the task AFAICT from the code.) By delaying the access to the project properties I can get the same effect, but I also have to buy into all the low-level handling of classpath adding and ‘classes’ depending ‘builtBy’ does for me.

So, as a public plugin writer, should I stay away from ‘builtBy’?

You can solve the “plugin doesn’t pick up a change to ‘buildDir’” problem by configuring ‘someTask.destinationDir’ using a callback such as ‘gradle.projectsEvaluated’, or by using Gradle’s internal convention mapping mechanism.

If ‘SomeTask’ declares ‘destinationDir’ as an ‘@OutputDirectory’ (which it should), it should be possibly to simplify the last line to ‘set.output.dir someTask’, and evaluate it eagerly.

Ah. Ok! I didn’t know that ‘SourceSetOutput’ cares for the ‘OutputDirectory’. It wasn’t clear for me from the DSL reference or API docs.