Hi! I am in need of guidance for the development o...
# plugin-development
d
Hi! I am in need of guidance for the development of a task in my Gradle plugin. I developed a documentation tool that uses a custom Kotlin script to define and generate a document. This Kotlin script can itself further reference markdown files that are included in said generated document. I am trying to put that generation process in a Gradle task. The initial script input path is known and easy to put as an
@InputFile
input, and I use an
@OutputDirectory
for the location where the document is generated. However, I need to execute the input Kotlin script to determine the other markdown input files, which is already half of the generation process. I understand that I shouldn't/cannot modify the tasks input during the task execution of a
DefaultTask
(any task?). Don't I have any other choice than to do twice the script execution, once at task configuration to determine all the input paths (which can be scattered in the project, so cannot use an
@InputDirectory
) and once more at task execution to do the generation itself?
s
You could also specify more coarse-grained inputs, such as marking all possibly used paths as the input. (Like when in Java you mark an entire library as an input/dependency even if you only use a single class out of it.)
1
d
@Sergej Koščejev so you mean, for instance, use as inputs all the markdown files and image files in the project directory despite they might not be included in that particular generated document? That would mean all my document generation tasks would be re-executed whenever any markdown or image file is modified, right?
s
Yes. It’s a tradeoff.
d
OK, I see. Thank you for you answer!
v
Or somehow reuse the result from the first run in the second run. Or restructure your files so that you are able to identify the input files without running anything. Or have a "used-files.txt" besides the main file that must list all used files and fail at execution time if any are missing. Or make the consumer declare the input files in their build script and then again check at execution time that only declared inputs are used. Or make your task untracked, so that it simply always executes and is never up to date or cacheable.
d
So I am leaning towards putting the extra effort to separate all the script-execution and source markdown files parsing from the document generation itself. It would introduce an intermediate representation from which I can extract the all source file dependencies. However this would put all the script execution and source markdown files parsing into Gradle's configuration phase. Do you think this is bad practice?
v
I'd say it depends on how long this takes. If it is done quite fast, it might be ok. If it takes significant time, it might be bad. On the other hand, if done right, it should also be only done when the task is also going to be executed, so the time is spent either way, and when using configuration cache, this could then be saved when the cache is reused, as long as you do not something like writing the intermediate state to a file during configuration phase or something like that. So, it mainly depends on the gory details and exact situation. Sometimes it might be better to just consider too many files as input as Sergej suggested. Sometimes it might be better to just always execute the task. Sometimes it might be better to spend the time or refactoring to be able to specify the concrete inputs, especially if execution time is really significantly high. All a question of which tradeoffs you make.
m
It would introduce an intermediate representation from which I can extract the all source file dependencies.
Quick note: make sure not to put absolute paths in there if you don’t want to break build caching
☝️ 1