diff --git a/internal/compiler/compiler.go b/internal/compiler/compiler.go index ee7c4adb..7dcb725e 100644 --- a/internal/compiler/compiler.go +++ b/internal/compiler/compiler.go @@ -67,6 +67,7 @@ func (c *Compiler) getVariables(t *ast.Task, call *ast.Call, evaluateShVars bool newVar.Value = value } newVar.Sh = tr.Replace(v.Sh) + newVar.Ref = v.Ref newVar.Json = tr.Replace(v.Json) newVar.Yaml = tr.Replace(v.Yaml) newVar.Dir = v.Dir diff --git a/internal/templater/templater.go b/internal/templater/templater.go index ac7eb29d..9a123467 100644 --- a/internal/templater/templater.go +++ b/internal/templater/templater.go @@ -113,6 +113,9 @@ func (r *Templater) replaceVars(vars *ast.Vars, extra map[string]any) *ast.Vars } newVar.Live = v.Live newVar.Sh = r.ReplaceWithExtra(v.Sh, extra) + newVar.Ref = v.Ref + newVar.Json = r.ReplaceWithExtra(v.Json, extra) + newVar.Yaml = r.ReplaceWithExtra(v.Yaml, extra) newVars.Set(k, newVar) return nil }) diff --git a/taskfile/ast/var.go b/taskfile/ast/var.go index 69613fb0..5ce8fd6d 100644 --- a/taskfile/ast/var.go +++ b/taskfile/ast/var.go @@ -76,6 +76,7 @@ type Var struct { Value any Live any Sh string + Ref string Json string Yaml string Dir string @@ -107,9 +108,10 @@ func (v *Var) UnmarshalYAML(node *yaml.Node) error { case yaml.MappingNode: key := node.Content[0].Value switch key { - case "sh", "map", "json", "yaml": + case "sh", "ref", "map", "json", "yaml": var m struct { Sh string + Ref string Map any Json string Yaml string @@ -118,12 +120,13 @@ func (v *Var) UnmarshalYAML(node *yaml.Node) error { return err } v.Sh = m.Sh + v.Ref = m.Ref v.Value = m.Map v.Json = m.Json v.Yaml = m.Yaml return nil default: - return fmt.Errorf(`yaml: line %d: %q is not a valid variable type. Try "sh", "map", "json", "yaml" or using a scalar value`, node.Line, key) + return fmt.Errorf(`yaml: line %d: %q is not a valid variable type. Try "sh", "ref", "map", "json", "yaml" or using a scalar value`, node.Line, key) } default: var value any diff --git a/testdata/vars/any2/Taskfile.yml b/testdata/vars/any2/Taskfile.yml index 2d6769ea..bc6fd10c 100644 --- a/testdata/vars/any2/Taskfile.yml +++ b/testdata/vars/any2/Taskfile.yml @@ -11,14 +11,10 @@ tasks: MAP: map: {"name":"Alice","age":30,"children":[{"name":"Bob","age":5},{"name":"Charlie","age":3},{"name":"Diane","age":1}]} cmds: - - >- - echo "{{.MAP.name}} has {{len .MAP.children}} children called - {{- $children := .MAP.children -}} - {{- range $i, $child := $children -}} - {{- if lt $i (sub (len $children) 1)}} {{$child.name -}}, - {{- else}} and {{$child.name -}} - {{- end -}} - {{- end -}}" + - task: print-var + vars: + VAR: + ref: MAP json: vars: @@ -27,14 +23,10 @@ tasks: JSON: json: "{{.JSON_STRING}}" cmds: - - >- - echo "{{.JSON.name}} has {{len .JSON.children}} children called - {{- $children := .JSON.children -}} - {{- range $i, $child := $children -}} - {{- if lt $i (sub (len $children) 1)}} {{$child.name -}}, - {{- else}} and {{$child.name -}} - {{- end -}} - {{- end -}}" + - task: print-var + vars: + VAR: + ref: JSON yaml: vars: @@ -42,10 +34,17 @@ tasks: sh: cat example.yaml YAML: yaml: "{{.YAML_STRING}}" + cmds: + - task: print-var + vars: + VAR: + ref: YAML + + print-var: cmds: - >- - echo "{{.YAML.name}} has {{len .YAML.children}} children called - {{- $children := .YAML.children -}} + echo "{{.VAR.name}} has {{len .VAR.children}} children called + {{- $children := .VAR.children -}} {{- range $i, $child := $children -}} {{- if lt $i (sub (len $children) 1)}} {{$child.name -}}, {{- else}} and {{$child.name -}} diff --git a/variables.go b/variables.go index a0663dc1..78aa7678 100644 --- a/variables.go +++ b/variables.go @@ -211,6 +211,17 @@ func (e *Executor) compiledTask(call ast.Call, evaluateShVars bool) (*ast.Task, newCmd.Cmd = r.Replace(cmd.Cmd) newCmd.Task = r.Replace(cmd.Task) newCmd.Vars = r.ReplaceVars(cmd.Vars) + // Loop over the command's variables and resolve any references to other variables + err := cmd.Vars.Range(func(k string, v ast.Var) error { + if v.Ref != "" { + refVal := vars.Get(v.Ref) + newCmd.Vars.Set(k, refVal) + } + return nil + }) + if err != nil { + return nil, err + } new.Cmds = append(new.Cmds, newCmd) } }