diff --git a/internal/templater/templater.go b/internal/templater/templater.go index 2e12cbb89e..d85df79700 100644 --- a/internal/templater/templater.go +++ b/internal/templater/templater.go @@ -141,3 +141,11 @@ func ReplaceVarsWithExtra(vars *ast.Vars, cache *Cache, extra map[string]any) *a return &newVars } + +// MergeCacheMap merges a map into the cache +func (vs *Cache) MergeCacheMap(m map[string]any) { + for k, v := range m { + vs.cacheMap[k] = v + } + vs.Vars.MergeCacheMap(vs.cacheMap) +} diff --git a/task_test.go b/task_test.go index c2f3dc97b5..d7d2302ea1 100644 --- a/task_test.go +++ b/task_test.go @@ -1571,6 +1571,26 @@ func TestTaskDotenvWithBrackets(t *testing.T) { }, } tt.Run(t) + + tt2 := fileContentTest{ + Dir: "testdata/dotenv_task/default", + Target: "dotenv", + TrimSpace: true, + Files: map[string]string{ + "dotenv-called.txt": "foo", + }, + } + tt2.Run(t) + + tt3 := fileContentTest{ + Dir: "testdata/dotenv_task/default", + Target: "dotenv", + TrimSpace: true, + Files: map[string]string{ + "dotenv-called-2.txt": "foo", + }, + } + tt3.Run(t) } func TestTaskDotenvFail(t *testing.T) { diff --git a/taskfile/ast/var.go b/taskfile/ast/var.go index 9ea1b56654..953559d444 100644 --- a/taskfile/ast/var.go +++ b/taskfile/ast/var.go @@ -36,6 +36,14 @@ func (vs *Vars) ToCacheMap() (m map[string]any) { return } +// FromCacheMap converts a map containing only the static variables +// to Vars +func (vs *Vars) MergeCacheMap(m map[string]any) { + for k, v := range m { + vs.Set(k, Var{Value: v}) + } +} + // Wrapper around OrderedMap.Set to ensure we don't get nil pointer errors func (vs *Vars) Range(f func(k string, v Var) error) error { if vs == nil { diff --git a/testdata/dotenv_task/default/Taskfile.yml b/testdata/dotenv_task/default/Taskfile.yml index d9f761df66..4e9f906c2f 100644 --- a/testdata/dotenv_task/default/Taskfile.yml +++ b/testdata/dotenv_task/default/Taskfile.yml @@ -9,6 +9,14 @@ tasks: cmds: - echo "$FOO" > dotenv.txt - echo "{{.FOO}}" > dotenv-2.txt + - task: dotenv_called + vars: + FOO: "{{.FOO}}" + + dotenv_called: + cmds: + - echo "$FOO" > dotenv-called.txt + - echo "{{.FOO}}" > dotenv-called-2.txt dotenv-overridden-by-env: dotenv: ['.env'] diff --git a/variables.go b/variables.go index 13d5e58b44..bad5dae040 100644 --- a/variables.go +++ b/variables.go @@ -107,6 +107,7 @@ func (e *Executor) compiledTask(call *ast.Call, evaluateShVars bool) (*ast.Task, new.Env.Merge(templater.ReplaceVars(e.Taskfile.Env, cache), nil) new.Env.Merge(templater.ReplaceVars(dotenvEnvs, cache), nil) new.Env.Merge(templater.ReplaceVars(origTask.Env, cache), nil) + new.Env.Merge(templater.ReplaceVars(call.Vars, cache), nil) if evaluateShVars { err = new.Env.Range(func(k string, v ast.Var) error { // If the variable is not dynamic, we can set it and return @@ -126,6 +127,8 @@ func (e *Executor) compiledTask(call *ast.Call, evaluateShVars bool) (*ast.Task, } } envCache := new.Env.ToCacheMap() + // merge envCache with cache + cache.MergeCacheMap(envCache) if len(origTask.Cmds) > 0 { new.Cmds = make([]*ast.Cmd, 0, len(origTask.Cmds)) @@ -162,7 +165,7 @@ func (e *Executor) compiledTask(call *ast.Call, evaluateShVars bool) (*ast.Task, continue } newCmd := cmd.DeepCopy() - newCmd.Cmd = templater.ReplaceWithExtra(cmd.Cmd, cache, envCache) + newCmd.Cmd = templater.Replace(cmd.Cmd, cache) newCmd.Task = templater.Replace(cmd.Task, cache) newCmd.Vars = templater.ReplaceVars(cmd.Vars, cache) new.Cmds = append(new.Cmds, newCmd)