You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
dir does not create a directory in some cases #1001
dir is documented to create a directory if it does not exist, but that not happens there. If directory "does-not-exist" does not exist, that task fails with:
task: Command "cat ../exist.txt" failed: chdir /<...>/does-not-exist: no such file or directory
So it tries to change directory to "does-not-exist" without creating it.
Unfortunately, the fact that dir accepts variables means that the code that resolves variables (the compiler), runs before the code that creates the directory. If we were to change it so that the mkdir code runs first, your dynamic variable would work (as the directory would exist prior to you trying to compile it). However, it would break dir for anybody using it with a variable (This is probably quite common).
The only possible solution I can think of, would be to create the dirbefore compilation if there are no variables, and after compilation if there are variables. We would then have to create an error if the user tries to use dir with a dynamically defined variable.
The area of code around variables and how/when they are resolved is quite complex, so I wouldn't expect any significant changes on this for now.
I think resolving variables should not change the directory, right? So it does not matter when variables are resolved relative to directory creation. What matters is that mkdir should be called before chdir.
We use Taskfile to have some abstraction over Unix variants and Windows. The latter has mkdir command, but the flags are different. Given the Taskfile provides dir option almost makes it a cross-platform equivalent.
Nope, not the one that is wanted. I don't really think it can be solved. Its kind of stupid, vars have to be evaluated before the task can run (and create its directory), so that templates can be evaluated, at which point the dir is known. But the varsattempt to run in whatever the task dir evaluates too - don't be tricked, its not so easy to know what that will be.
@AlekSi@andreynering it could be possible to mitigate the problem; if, when evaluating the vars the task dir does not exist, then fall back to the special variable TASKFILE_DIR. The dynamic vars would then run, but in some cases, not where you think.
task.dir cannot be reliably known until after a task is compiled.
Therefore, dynamic vars of a task will not work with relative paths if the task has a configured task.dir.
@AlekSi so the situation here is that task is working as designed. The problem could possibly be mitigated, but not solved.
So, your options at the moment are:
design your tasks with that behaviour in mind. For example use absolute paths in these dynamic vars for such cases.
use the latest version of task which has versions of linux commands that run on windows, so you can design cross-platform tasks.
The "obvious" solution is this:
At the beginning, before attempting to run a task, template the task.dir without evaluating SH commands. If it evaluates then create the task.dir.
Evaluate the vars and compile the task.
Run the task.
If you task uses a templated value for task.dir ... then the directory would not be created before point 2 ... and you will get confused.
Now, rather than have something that does not work in a clear way (see highlighted statement above), you get a more complicated mix of behaviour. The outcome of that is something to ruminate over.
Activity
pd93 commentedon Feb 13, 2023
Unfortunately, the fact that
diraccepts variables means that the code that resolves variables (the compiler), runs before the code that creates the directory. If we were to change it so that themkdircode runs first, your dynamic variable would work (as the directory would exist prior to you trying to compile it). However, it would breakdirfor anybody using it with a variable (This is probably quite common).The only possible solution I can think of, would be to create the
dirbefore compilation if there are no variables, and after compilation if there are variables. We would then have to create an error if the user tries to usedirwith a dynamically defined variable.The area of code around variables and how/when they are resolved is quite complex, so I wouldn't expect any significant changes on this for now.
AlekSi commentedon Mar 7, 2023
I think resolving variables should not change the directory, right? So it does not matter when variables are resolved relative to directory creation. What matters is that
mkdirshould be called beforechdir.richard-hajek commentedon Apr 23, 2023
Admittedly, just calling
mkdirinbefore eachchdirmight make sense? idkAlekSi commentedon Apr 30, 2023
We use Taskfile to have some abstraction over Unix variants and Windows. The latter has
mkdircommand, but the flags are different. Given the Taskfile providesdiroption almost makes it a cross-platform equivalent.trulede commentedon Dec 8, 2025
This problem is likely resolved with the latest versions of Task. Please try them, and if not better, reopen this issue.
AlekSi commentedon Dec 9, 2025
It is not resolved. And only maintainers can reopen the issue:
trulede commentedon Feb 19, 2026
This is the problem with fixing this:
where do you think TEST will cat from? some/dir/../exist.txt?
Nope, not the one that is wanted. I don't really think it can be solved. Its kind of stupid,
varshave to be evaluated before the task can run (and create its directory), so that templates can be evaluated, at which point thediris known. But thevarsattempt to run in whatever the taskdirevaluates too - don't be tricked, its not so easy to know what that will be.@AlekSi @andreynering it could be possible to mitigate the problem; if, when evaluating the
varsthe taskdirdoes not exist, then fall back to the special variable TASKFILE_DIR. The dynamic vars would then run, but in some cases, not where you think.trulede commentedon Mar 19, 2026
task.dir cannot be reliably known until after a task is compiled.
Therefore, dynamic vars of a task will not work with relative paths if the task has a configured task.dir.
@AlekSi so the situation here is that task is working as designed. The problem could possibly be mitigated, but not solved.
So, your options at the moment are:
The "obvious" solution is this:
If you task uses a templated value for task.dir ... then the directory would not be created before point 2 ... and you will get confused.
Now, rather than have something that does not work in a clear way (see highlighted statement above), you get a more complicated mix of behaviour. The outcome of that is something to ruminate over.
The place for the "fix" would be here:
task/task.go
Line 76 in 19d8fae
The task.dir is created here, so something similar would be needed at the aforementioned location:
task/task.go
Line 263 in 19d8fae
I think its reasonable. Feel free to write a PR.
AlekSi commentedon Mar 19, 2026
Personally, I ended up dropping Windows :D
AlekSi commentedon Mar 19, 2026
Huh? Is it documented somewhere?
fix(compiler): create task.dir before running dynamic (sh:) vars