`.task` directory generation should respect `dir` attribute
Description
Problem
Including a taskfile which contains any task with generates: breaks the checksum check depending on from which taskfile the task was run.
Example
Consider following structure:
.
./docs
./docs/some-source-files/*.md
./docs/Taskfile.docs.yml
./Taskfile.main.yml
The Taskfile.docs.yml:
version: '3'
tasks:
pdf:
desc: "Compile source files to PDF"
sources:
- "./some-source-files/*.md"
generates:
- "Docs.pdf"
cmds:
- <some command that generates Docs.pdf from source markdown files>
silent: false
I want to make pdf task available from the root directory. Taskfile.main.yml:
version: '3'
includes:
docs_generation:
taskfile: "./docs/Taskfile.docs.yml"
dir: "./docs"
aliases: [dg]
tasks:
some_other_tasks:
Problem reproduction
cd ./docs && task pdf produces a .task directory with a checksum name pdf in ./docs/.task/checksum/pdf
However, task dg:pdf generates .task directory in root directory, with different name: ./.task/checksum/docs_generation-pdf
Expectations
If I include a pdf task from docs generation in main taskfile, I explicitly set dir: "./docs" so that Task should be run from within that directory. I would expect the .task directory to be also created/checked from within that directory.
This also means that the docs generation will be run even if it's up-to-date, because some other user run it from different taskfile than me. (Yes, I want to commit the checksums because I also commit the generated PDF).
Tried solutions
Setting TASK_TEMP_DIR=./docs/.task task dg:pdf + adding label: pdf to the pdf task solves this. However, what if I want to have multiple inclusions, not only from docs folder, where the included task has generates:?
I would have to type separately TASK_TEMP_DIR=./where-target-taskfile-is-located/.task everytime based on which included task I'm about to run. I believe this is not intented.
You might try this wrapping technique:
version: '3'
tasks:
pdf:
desc: "Compile source files to PDF"
dir: '{{.TASKFILE_DIR}}' # I think this is correct
cmds:
- task pdf_real
pdf_real:
silent: true
sources:
- "./some-source-files/*.md"
generates:
- Docs.pdf
cmds:
- touch Docs.pdf
Hmm, this indeed works and solves the issue.
But I don't quite understand it. The dir is specified for the pdf (my original pdf, not your new pdf) in the Taskfile.main.yml. Would you be able to explain the logic behind it? Is the behavior intended? Should it be like this?
In your example, if I change - task pdf_real to - task: pdf_real, I can again replicate this and create two different .task/checksum based on where I run this task from.
You want to the .task folder for that task to be in the same location, no matter how it is imported/called. One way to achieve that is to always run that particular task in a separate call to task. Task starts in that folder, creates the .task folder, runs the task, which does the conversion. Its exactly what you wanted.
The temp dir (.task) is always relative to the root taskfile. So with many different taskfile based projects importing the same taskfile, you cannot achieve what you want directly. Therefore a wrapper is the solution.
Thanks for the explanation.
The temp dir (.task) is always relative to the root taskfile.
Is this intended feature though? From the docs, I can't find any other use case for .task folder other than checksum/timestamp checking. And having temp dir always relative to the root taskfile makes this checking inconsistent. Having a .task folder right next to the imported/included taskfile (the one that actually has the task with generates:) makes much more sense to me.
Its a matter of perspective. You have a project (or sub-project) that you want to build from many many other projects. Task is used to build a project (singular). The imports mechanism is designed to bring other tasks, not taskfiles, into a project. This is a different thing than you are expecting.
But OK. Only a small problem.
I gave you one idea already, but I have another. Don't depend on Task to track the checksum of your file, rather, do it yourself! Write a task that generates the PDF, calculates its checksum, and stores that next to the PDF file (in another file). Next, add some commands before that in your task, to compare your PDF files checksum against the checksum stored in that additional file and then only generate the PDF if the checksums do not match.
That is what task is doing, so if you do that for your use case, then you have another solution.
I think your use case is valid, it makes sense to do that. So one of those ideas will work for you.