fix: resolve templated task dir before running dynamic variables - #2944
fix: resolve templated task dir before running dynamic variables#2944semx wants to merge 1 commit into
Conversation
The task dir was templated against the variables gathered so far, which
at that point only held the environment and the special variables. A dir
like '{{.DIRECTORY}}', where DIRECTORY comes from the Taskfile vars,
expanded to an empty string, so the task dynamic variables silently ran
in the Taskfile dir instead of the task one.
Resolve the dir after the Taskfile vars have been added to the result.
The commands themselves already ran in the right dir, only the dynamic
variables were affected.
Signed-off-by: semx <7532921+semx@users.noreply.github.com>
|
Is this any different than PR #2813 ? |
|
Different problem — I built both branches and ran them against each other's case. Same Taskfile, one task with a literal
#2813 skips templated dirs on purpose — They compose, though. With both applied both cases pass — the only merge conflict is in So no objection from me if #2813 lands first; I'll rebase and drop the conflicting hunk. |
|
Thanks @trulede — fair concern, compiler changes deserve caution. On blast radius: the change doesn't alter what the compiler does, only when it templates On #2813 as a base: it targets a different failure (a |
There was a problem hiding this comment.
Pull request overview
This PR fixes the ordering bug where a task’s dir: was templated before Taskfile vars: were added to the variables set, causing sh: (dynamic) variables to be evaluated from the wrong working directory when dir: depends on Taskfile variables.
Changes:
- Move task
dir:templating/resolution inCompiler.getVariablesto occur after Taskfile env/vars (and include vars) are added, and right before evaluating task-scoped dynamic variables. - Add a focused regression test fixture and test case to ensure dynamic variables run in a templated task directory without being masked by the dynamic var cache behavior.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
compiler.go |
Defers resolving the task dir: until the variable set is sufficiently populated, ensuring dynamic vars run in the intended directory. |
task_test.go |
Adds a dedicated regression test for dynamic variables evaluated in a templated dir:. |
testdata/dir/templated_dir/Taskfile.yml |
New fixture reproducing the templated-dir: dynamic variable directory issue in isolation. |
testdata/dir/templated_dir/subdirectory/.gitignore |
Ignores generated .txt outputs produced by the new fixture. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Fixes the task
dirbeing templated too early, which made dynamic variables run in the wrong directory.The problem
getVariablesresolves the task dir with the variables collected so far, but at that pointresultonly holds the environment and the special variables. The Taskfile vars are added a few lines below. So a dir like'{{.DIRECTORY}}', whereDIRECTORYcomes from the Taskfilevars:, expands to an empty string and the task dynamic variables run in the Taskfile dir instead of the task dir.The commands themselves are unaffected — they already run in the right directory. Only the
sh:variables see the wrong one.Reproducer
The same dir works when
DIRECTORYcomes from the environment (DIRECTORY=subdirectory task templated-dir), because environment variables are already inresultwhen the dir is resolved. That is what pointed at the ordering.The fix
Resolve the dir after the Taskfile env and vars have been added to the result, right before the first use of
taskRangeFunc. The order in which variables are added is unchanged, only the point where the dir is computed moves down.Note on the existing test
TestDynamicVariablesShouldRunOnTheTaskDircovers a templated dir already (from_interpolated_dir), but it passes onmainfor the wrong reason: every task in that fixture runs the samebasename "$(pwd)"command, and the dynamic variable cache is keyed by the command alone, so the templated-dir task reuses a value another task computed insubdirectory. The new fixture uses a single task so the cache cannot mask the result.That cache is a separate issue (#2928) with fixes already proposed, so this PR leaves it alone.