`Reason: Task ':plantUml' uses this output of task...
# community-support
d
Reason: Task ':plantUml' uses this output of task ':graphqlGenerateSDL' without declaring an explicit or implicit dependency. This can lead to incorrect results being produced, depending on what order the tasks are executed.
Hello! I’m trying to execute a task “plantUml” after i run the “build” task. It’s not in any way dependent on the build task, I just want to make sure it’s executed whenever you run a build. My configuration looks like this
Copy code
tasks.withType<PlantumlTask> {
    source("src")
    fileFormat.set("SVG")
    includePattern.set("**/*.puml")
    outputDirectory.set(file("src/main/resources/docs/puml"))
}
tasks.named("build") {
    finalizedBy("plantUml")
}
I’ve also tried adding
dependsOn
and/or
mustRunAfter
on the plantUml task but still get the same error message. Any pointers?
n
You should be more specific/careful about your inputs and outputs. By setting the
source
for the PlantUml task to
src
you're implicitly depending on all tasks that write to that folder. By defining your output to also write to the
src
folder, your task now sees its own outputs as an input as well 🤷 It's best to write to the build folder whenever you can.
d
Even if I write to another folder than src it’s the same problem so not sure how to deal with this
I’ve had the same code for a year or so and it has been working fine but the error started to appear just recently 🤷
n
Do your
puml
files need to be in the
src
folder? because now you depend on every single task that writes to the
src
folder (in this case, apparently the
graphqlGenerateSDL
task does so) implicitly.
👍 1
In general you should avoid having overlapping inputs and outputs, unless those are truly dependent on eachother.
1
Perhaps instead of
source("src")
with an include pattern that traverses the entire tree, you could be more specific? e.g.
source("src/plantuml")
d
No, they don’t need to be in
src
. But we use it to document flows and I like having them close to the code that handles those flows. Maybe we need to revisit that. Thanks for your help 🙂
👍 1
v
In general you should avoid having overlapping inputs and outputs, unless those are truly dependent on eachother.
please scratch the second half. Two tasks should never ever have overlapping outputs, no matter what reason. This always just leads to quirks, problems, and race conditions, especially with up-to-date checks or much worse if any involved task is cacheable where you then get poisoned cache entries. And imho no task should ever write to
src
or any other checked in folder too, but always to something under
layout.buildDirectory
that is dedicated for that single task. 🙂
👍 2
Similarly, it is most often not a good idea to configure task inputs as paths. If you for example want to operate on all sources, get the sources from the source set and wire the properly. If setup correctly, then you for example also have proper dependencies on tasks that generate code like
graphqlGenerateSDL
probably does, making sure the tasks are run where necessary, you do not get that error, and not potentially see stale or missing files.
n
please scratch the second half.
yeah, I worded the 2nd part confusingly and too general. What I meant was: "The overlap should only ever be input of one is the output of another. But that's mostly defined by referencing the task outputs of one task in the inputs of the other."
d
And imho no task should ever write to
src
or any other checked in folder too, but always to something under
layout.buildDirectory
that is dedicated for that single task.
So I shouldn’t use grade at all to generate files that I want to check in? In this scenario we’re rendering images that are part of the repositories documentation. I’ve now moved them out from
src
to
docs
but when reading this I guess that’s not a good idea either…
t
You could, but you should arrange them in such a way that they're never part of a task tree that also reads from there. Fwiw, I do have codegen tasks depending on external resources (a database) that writes to
src
, that I'll then check in, and will be compiled by other tasks; but I never run that codegen task in the same build than the task that compiles them. So your problem might be that you run it at the end of all your builds: what if you only run the plantUml task?
👍 1
v
So I shouldn’t use grade at all to generate files that I want to check in? In this scenario we’re rendering images that are part of the repositories documentation. I’ve now moved them out from
src
to
docs
but when reading this I guess that’s not a good idea either…
DISCLAIMER: Be aware, that is only my personal opinion No build result should ever be checked into source control, no matter which tool you use. If you intend to check in those files, generating directly to
src
is fine of course. Especially if the task is more an ad-hoc "build me these files I want to check in an update" kind of task, but not a task that is part of the normal build process. But imho if Gradle can generate those files, they should not be checked in, but built as part of the build process. (Of course any rule has its exceptions, if generation is super expensive like generating from a DB as @Thomas Broyer mentioned, then it might be ok to generate and commit the result, but then imho as a manual tool task like I and Thomas mentioned, but not as part of a normal build process)
👍 2
1