diff --git a/internal/compiler/v2/compiler_v2.go b/internal/compiler/v2/compiler_v2.go index 97610a7f..ee511d21 100644 --- a/internal/compiler/v2/compiler_v2.go +++ b/internal/compiler/v2/compiler_v2.go @@ -72,11 +72,22 @@ func (vr *varResolver) merge(vars *taskfile.Vars) { } tr := templater.Templater{Vars: vr.vars} _ = vars.Range(func(k string, v taskfile.Var) error { - v = taskfile.Var{ - Value: tr.Replace(v.Value), - Sh: tr.Replace(v.Sh), + // Replace values + newVar := taskfile.Var{} + switch value := v.Value.(type) { + case string: + newVar.Value = tr.Replace(value) + default: + newVar.Value = value } - static, err := vr.c.HandleDynamicVar(v, "") + newVar.Sh = tr.Replace(v.Sh) + // If the variable is not dynamic, we can set it and return + if newVar.Value != nil || newVar.Sh == "" { + vr.vars.Set(k, taskfile.Var{Value: newVar.Value}) + return nil + } + // If the variable is dynamic, we need to resolve it first + static, err := vr.c.HandleDynamicVar(newVar, "") if err != nil { vr.err = err return err @@ -88,10 +99,6 @@ func (vr *varResolver) merge(vars *taskfile.Vars) { } func (c *CompilerV2) HandleDynamicVar(v taskfile.Var, _ string) (string, error) { - if v.Value != "" || v.Sh == "" { - return v.Value, nil - } - c.muDynamicCache.Lock() defer c.muDynamicCache.Unlock() diff --git a/internal/compiler/v3/compiler_v3.go b/internal/compiler/v3/compiler_v3.go index bc5a86d1..c66ec2b2 100644 --- a/internal/compiler/v3/compiler_v3.go +++ b/internal/compiler/v3/compiler_v3.go @@ -58,21 +58,26 @@ func (c *CompilerV3) getVariables(t *taskfile.Task, call *taskfile.Call, evaluat getRangeFunc := func(dir string) func(k string, v taskfile.Var) error { return func(k string, v taskfile.Var) error { tr := templater.Templater{Vars: result, RemoveNoValue: true} - - if !evaluateShVars { - result.Set(k, taskfile.Var{Value: tr.Replace(v.Value)}) - return nil - } - - v = taskfile.Var{ - Value: tr.Replace(v.Value), - Sh: tr.Replace(v.Sh), - Dir: v.Dir, + // Replace values + newVar := taskfile.Var{} + switch value := v.Value.(type) { + case string: + newVar.Value = tr.Replace(value) + default: + newVar.Value = value } + newVar.Sh = tr.Replace(v.Sh) + newVar.Dir = v.Dir if err := tr.Err(); err != nil { return err } - static, err := c.HandleDynamicVar(v, dir) + // If the variable is not dynamic, we can set it and return + if !evaluateShVars || newVar.Value != nil || newVar.Sh == "" { + result.Set(k, taskfile.Var{Value: newVar.Value}) + return nil + } + // If the variable is dynamic, we need to resolve it first + static, err := c.HandleDynamicVar(newVar, dir) if err != nil { return err } @@ -125,10 +130,6 @@ func (c *CompilerV3) getVariables(t *taskfile.Task, call *taskfile.Call, evaluat } func (c *CompilerV3) HandleDynamicVar(v taskfile.Var, dir string) (string, error) { - if v.Value != "" || v.Sh == "" { - return v.Value, nil - } - c.muDynamicCache.Lock() defer c.muDynamicCache.Unlock() diff --git a/internal/templater/templater.go b/internal/templater/templater.go index 5094c66e..c40a6a31 100644 --- a/internal/templater/templater.go +++ b/internal/templater/templater.go @@ -108,17 +108,20 @@ func (r *Templater) replaceVars(vars *taskfile.Vars, extra map[string]any) *task return nil } - var new taskfile.Vars + var newVars taskfile.Vars _ = vars.Range(func(k string, v taskfile.Var) error { - new.Set(k, taskfile.Var{ - Value: r.ReplaceWithExtra(v.Value, extra), - Live: v.Live, - Sh: r.ReplaceWithExtra(v.Sh, extra), - }) + var newVar taskfile.Var + switch value := v.Value.(type) { + case string: + newVar.Value = r.ReplaceWithExtra(value, extra) + } + newVar.Live = v.Live + newVar.Sh = r.ReplaceWithExtra(v.Sh, extra) + newVars.Set(k, newVar) return nil }) - return &new + return &newVars } func (r *Templater) Err() error { diff --git a/taskfile/var.go b/taskfile/var.go index f601604f..46ec2c4d 100644 --- a/taskfile/var.go +++ b/taskfile/var.go @@ -71,7 +71,7 @@ func (vs *Vars) DeepCopy() *Vars { // Var represents either a static or dynamic variable. type Var struct { - Value string + Value any Live any Sh string Dir string diff --git a/variables.go b/variables.go index e1c7a737..093f682d 100644 --- a/variables.go +++ b/variables.go @@ -108,6 +108,11 @@ func (e *Executor) compiledTask(call taskfile.Call, evaluateShVars bool) (*taskf new.Env.Merge(r.ReplaceVars(origTask.Env)) if evaluateShVars { err = new.Env.Range(func(k string, v taskfile.Var) error { + // If the variable is not dynamic, we can set it and return + if v.Value != nil || v.Sh == "" { + new.Env.Set(k, taskfile.Var{Value: v.Value}) + return nil + } static, err := e.Compiler.HandleDynamicVar(v, new.Dir) if err != nil { return err @@ -149,10 +154,13 @@ func (e *Executor) compiledTask(call taskfile.Call, evaluateShVars bool) (*taskf if cmd.For.Var != "" { if vars != nil { v := vars.Get(cmd.For.Var) - if cmd.For.Split != "" { - list = strings.Split(v.Value, cmd.For.Split) - } else { - list = strings.Fields(v.Value) + switch value := v.Value.(type) { + case string: + if cmd.For.Split != "" { + list = strings.Split(value, cmd.For.Split) + } else { + list = strings.Fields(value) + } } } }