mirror of
https://github.com/go-task/task.git
synced 2025-04-11 11:41:56 +02:00
feat: for
This commit is contained in:
parent
7ece04e996
commit
7ff1b1795e
76
docs/static/schema.json
vendored
76
docs/static/schema.json
vendored
@ -207,6 +207,9 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"$ref": "#/definitions/3/task_call"
|
"$ref": "#/definitions/3/task_call"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/3/for_call"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -272,7 +275,9 @@
|
|||||||
"description": "Hides task name and command from output. The command's output will still be redirected to `STDOUT` and `STDERR`.",
|
"description": "Hides task name and command from output. The command's output will still be redirected to `STDOUT` and `STDERR`.",
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"additionalProperties": false,
|
||||||
|
"required": ["task"]
|
||||||
},
|
},
|
||||||
"cmd_call": {
|
"cmd_call": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
@ -318,6 +323,75 @@
|
|||||||
"additionalProperties": false,
|
"additionalProperties": false,
|
||||||
"required": ["cmd"]
|
"required": ["cmd"]
|
||||||
},
|
},
|
||||||
|
"for_call": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"for": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/3/for_list"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/3/for_source"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/3/for_var"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"cmd": {
|
||||||
|
"description": "Command to run",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"task": {
|
||||||
|
"description": "Task to run",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"vars": {
|
||||||
|
"description": "Values passed to the task called",
|
||||||
|
"$ref": "#/definitions/3/vars"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"oneOf": [
|
||||||
|
{"required": ["cmd"]},
|
||||||
|
{"required": ["task"]}
|
||||||
|
],
|
||||||
|
"additionalProperties": false,
|
||||||
|
"required": ["for"]
|
||||||
|
},
|
||||||
|
"for_list": {
|
||||||
|
"description": "List of values to iterate over",
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"for_source": {
|
||||||
|
"description": "List of values to iterate over",
|
||||||
|
"type": "string",
|
||||||
|
"enum": ["source"]
|
||||||
|
},
|
||||||
|
"for_var": {
|
||||||
|
"description": "List of values to iterate over",
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"var": {
|
||||||
|
"description": "Name of the variable to iterate over",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"split": {
|
||||||
|
"description": "String to split the variable on",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"as": {
|
||||||
|
"description": "What the loop variable should be named",
|
||||||
|
"default": "ITEM",
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"additionalProperties": false,
|
||||||
|
"required": ["var"]
|
||||||
|
},
|
||||||
"precondition": {
|
"precondition": {
|
||||||
"anyOf": [
|
"anyOf": [
|
||||||
{
|
{
|
||||||
|
@ -10,7 +10,7 @@ import (
|
|||||||
"github.com/go-task/task/v3/internal/filepathext"
|
"github.com/go-task/task/v3/internal/filepathext"
|
||||||
)
|
)
|
||||||
|
|
||||||
func globs(dir string, globs []string) ([]string, error) {
|
func Globs(dir string, globs []string) ([]string, error) {
|
||||||
files := make([]string, 0)
|
files := make([]string, 0)
|
||||||
for _, g := range globs {
|
for _, g := range globs {
|
||||||
f, err := Glob(dir, g)
|
f, err := Glob(dir, g)
|
||||||
|
@ -84,7 +84,7 @@ func (*ChecksumChecker) Kind() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *ChecksumChecker) checksum(t *taskfile.Task) (string, error) {
|
func (c *ChecksumChecker) checksum(t *taskfile.Task) (string, error) {
|
||||||
sources, err := globs(t.Dir, t.Sources)
|
sources, err := Globs(t.Dir, t.Sources)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
@ -28,11 +28,11 @@ func (checker *TimestampChecker) IsUpToDate(t *taskfile.Task) (bool, error) {
|
|||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
sources, err := globs(t.Dir, t.Sources)
|
sources, err := Globs(t.Dir, t.Sources)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
generates, err := globs(t.Dir, t.Generates)
|
generates, err := Globs(t.Dir, t.Generates)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
@ -90,7 +90,7 @@ func (checker *TimestampChecker) Kind() string {
|
|||||||
|
|
||||||
// Value implements the Checker Interface
|
// Value implements the Checker Interface
|
||||||
func (checker *TimestampChecker) Value(t *taskfile.Task) (any, error) {
|
func (checker *TimestampChecker) Value(t *taskfile.Task) (any, error) {
|
||||||
sources, err := globs(t.Dir, t.Sources)
|
sources, err := Globs(t.Dir, t.Sources)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return time.Now(), err
|
return time.Now(), err
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,8 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"text/template"
|
"text/template"
|
||||||
|
|
||||||
|
"golang.org/x/exp/maps"
|
||||||
|
|
||||||
"github.com/go-task/task/v3/taskfile"
|
"github.com/go-task/task/v3/taskfile"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -25,6 +27,14 @@ func (r *Templater) ResetCache() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *Templater) Replace(str string) string {
|
func (r *Templater) Replace(str string) string {
|
||||||
|
return r.replace(str, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Templater) ReplaceWithExtra(str string, extra map[string]any) string {
|
||||||
|
return r.replace(str, extra)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Templater) replace(str string, extra map[string]any) string {
|
||||||
if r.err != nil || str == "" {
|
if r.err != nil || str == "" {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
@ -40,7 +50,15 @@ func (r *Templater) Replace(str string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var b bytes.Buffer
|
var b bytes.Buffer
|
||||||
if err = templ.Execute(&b, r.cacheMap); err != nil {
|
if extra == nil {
|
||||||
|
err = templ.Execute(&b, r.cacheMap)
|
||||||
|
} else {
|
||||||
|
// Copy the map to avoid modifying the cached map
|
||||||
|
m := maps.Clone(r.cacheMap)
|
||||||
|
maps.Copy(m, extra)
|
||||||
|
err = templ.Execute(&b, m)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
r.err = err
|
r.err = err
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
@ -63,6 +81,14 @@ func (r *Templater) ReplaceSlice(strs []string) []string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *Templater) ReplaceVars(vars *taskfile.Vars) *taskfile.Vars {
|
func (r *Templater) ReplaceVars(vars *taskfile.Vars) *taskfile.Vars {
|
||||||
|
return r.replaceVars(vars, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Templater) ReplaceVarsWithExtra(vars *taskfile.Vars, extra map[string]any) *taskfile.Vars {
|
||||||
|
return r.replaceVars(vars, extra)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Templater) replaceVars(vars *taskfile.Vars, extra map[string]any) *taskfile.Vars {
|
||||||
if r.err != nil || vars.Len() == 0 {
|
if r.err != nil || vars.Len() == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -70,9 +96,9 @@ func (r *Templater) ReplaceVars(vars *taskfile.Vars) *taskfile.Vars {
|
|||||||
var new taskfile.Vars
|
var new taskfile.Vars
|
||||||
_ = vars.Range(func(k string, v taskfile.Var) error {
|
_ = vars.Range(func(k string, v taskfile.Var) error {
|
||||||
new.Set(k, taskfile.Var{
|
new.Set(k, taskfile.Var{
|
||||||
Static: r.Replace(v.Static),
|
Static: r.ReplaceWithExtra(v.Static, extra),
|
||||||
Live: v.Live,
|
Live: v.Live,
|
||||||
Sh: r.Replace(v.Sh),
|
Sh: r.ReplaceWithExtra(v.Sh, extra),
|
||||||
})
|
})
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
56
task_test.go
56
task_test.go
@ -2207,3 +2207,59 @@ func TestForce(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestFor(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
expectedOutput string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "loop-explicit",
|
||||||
|
expectedOutput: "a\nb\nc\n",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "loop-sources",
|
||||||
|
expectedOutput: "bar\nfoo\n",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "loop-sources-glob",
|
||||||
|
expectedOutput: "bar\nfoo\n",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "loop-vars",
|
||||||
|
expectedOutput: "foo\nbar\n",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "loop-vars-sh",
|
||||||
|
expectedOutput: "bar\nfoo\n",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "loop-task",
|
||||||
|
expectedOutput: "foo\nbar\n",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "loop-task-as",
|
||||||
|
expectedOutput: "foo\nbar\n",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "loop-different-tasks",
|
||||||
|
expectedOutput: "1\n2\n3\n",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range tests {
|
||||||
|
t.Run(test.name, func(t *testing.T) {
|
||||||
|
var buff bytes.Buffer
|
||||||
|
e := task.Executor{
|
||||||
|
Dir: "testdata/for",
|
||||||
|
Stdout: &buff,
|
||||||
|
Stderr: &buff,
|
||||||
|
Silent: true,
|
||||||
|
Force: true,
|
||||||
|
}
|
||||||
|
require.NoError(t, e.Setup())
|
||||||
|
require.NoError(t, e.Run(context.Background(), taskfile.Call{Task: test.name, Direct: true}))
|
||||||
|
assert.Equal(t, test.expectedOutput, buff.String())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -11,8 +11,9 @@ import (
|
|||||||
// Cmd is a task command
|
// Cmd is a task command
|
||||||
type Cmd struct {
|
type Cmd struct {
|
||||||
Cmd string
|
Cmd string
|
||||||
Silent bool
|
|
||||||
Task string
|
Task string
|
||||||
|
For *For
|
||||||
|
Silent bool
|
||||||
Set []string
|
Set []string
|
||||||
Shopt []string
|
Shopt []string
|
||||||
Vars *Vars
|
Vars *Vars
|
||||||
@ -27,8 +28,9 @@ func (c *Cmd) DeepCopy() *Cmd {
|
|||||||
}
|
}
|
||||||
return &Cmd{
|
return &Cmd{
|
||||||
Cmd: c.Cmd,
|
Cmd: c.Cmd,
|
||||||
Silent: c.Silent,
|
|
||||||
Task: c.Task,
|
Task: c.Task,
|
||||||
|
For: c.For.DeepCopy(),
|
||||||
|
Silent: c.Silent,
|
||||||
Set: deepcopy.Slice(c.Set),
|
Set: deepcopy.Slice(c.Set),
|
||||||
Shopt: deepcopy.Slice(c.Shopt),
|
Shopt: deepcopy.Slice(c.Shopt),
|
||||||
Vars: c.Vars.DeepCopy(),
|
Vars: c.Vars.DeepCopy(),
|
||||||
@ -54,6 +56,7 @@ func (c *Cmd) UnmarshalYAML(node *yaml.Node) error {
|
|||||||
// A command with additional options
|
// A command with additional options
|
||||||
var cmdStruct struct {
|
var cmdStruct struct {
|
||||||
Cmd string
|
Cmd string
|
||||||
|
For *For
|
||||||
Silent bool
|
Silent bool
|
||||||
Set []string
|
Set []string
|
||||||
Shopt []string
|
Shopt []string
|
||||||
@ -62,6 +65,7 @@ func (c *Cmd) UnmarshalYAML(node *yaml.Node) error {
|
|||||||
}
|
}
|
||||||
if err := node.Decode(&cmdStruct); err == nil && cmdStruct.Cmd != "" {
|
if err := node.Decode(&cmdStruct); err == nil && cmdStruct.Cmd != "" {
|
||||||
c.Cmd = cmdStruct.Cmd
|
c.Cmd = cmdStruct.Cmd
|
||||||
|
c.For = cmdStruct.For
|
||||||
c.Silent = cmdStruct.Silent
|
c.Silent = cmdStruct.Silent
|
||||||
c.Set = cmdStruct.Set
|
c.Set = cmdStruct.Set
|
||||||
c.Shopt = cmdStruct.Shopt
|
c.Shopt = cmdStruct.Shopt
|
||||||
@ -95,10 +99,12 @@ func (c *Cmd) UnmarshalYAML(node *yaml.Node) error {
|
|||||||
var taskCall struct {
|
var taskCall struct {
|
||||||
Task string
|
Task string
|
||||||
Vars *Vars
|
Vars *Vars
|
||||||
|
For *For
|
||||||
}
|
}
|
||||||
if err := node.Decode(&taskCall); err == nil && taskCall.Task != "" {
|
if err := node.Decode(&taskCall); err == nil && taskCall.Task != "" {
|
||||||
c.Task = taskCall.Task
|
c.Task = taskCall.Task
|
||||||
c.Vars = taskCall.Vars
|
c.Vars = taskCall.Vars
|
||||||
|
c.For = taskCall.For
|
||||||
c.Silent = cmdStruct.Silent
|
c.Silent = cmdStruct.Silent
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
68
taskfile/for.go
Normal file
68
taskfile/for.go
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
package taskfile
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"gopkg.in/yaml.v3"
|
||||||
|
|
||||||
|
"github.com/go-task/task/v3/internal/deepcopy"
|
||||||
|
)
|
||||||
|
|
||||||
|
type For struct {
|
||||||
|
From string
|
||||||
|
List []string
|
||||||
|
Var string
|
||||||
|
Split string
|
||||||
|
As string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *For) UnmarshalYAML(node *yaml.Node) error {
|
||||||
|
switch node.Kind {
|
||||||
|
|
||||||
|
case yaml.ScalarNode:
|
||||||
|
var from string
|
||||||
|
if err := node.Decode(&from); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
f.From = from
|
||||||
|
return nil
|
||||||
|
|
||||||
|
case yaml.SequenceNode:
|
||||||
|
var list []string
|
||||||
|
if err := node.Decode(&list); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
f.List = list
|
||||||
|
return nil
|
||||||
|
|
||||||
|
case yaml.MappingNode:
|
||||||
|
var forStruct struct {
|
||||||
|
Var string
|
||||||
|
Split string
|
||||||
|
As string
|
||||||
|
}
|
||||||
|
if err := node.Decode(&forStruct); err == nil && forStruct.Var != "" {
|
||||||
|
f.Var = forStruct.Var
|
||||||
|
f.Split = forStruct.Split
|
||||||
|
f.As = forStruct.As
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Errorf("yaml: line %d: invalid keys in for", node.Line)
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Errorf("yaml: line %d: cannot unmarshal %s into for", node.Line, node.ShortTag())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *For) DeepCopy() *For {
|
||||||
|
if f == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return &For{
|
||||||
|
From: f.From,
|
||||||
|
List: deepcopy.Slice(f.List),
|
||||||
|
Var: f.Var,
|
||||||
|
Split: f.Split,
|
||||||
|
As: f.As,
|
||||||
|
}
|
||||||
|
}
|
93
testdata/for/Taskfile.yml
vendored
Normal file
93
testdata/for/Taskfile.yml
vendored
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
version: "3"
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
# Loop over a list of values
|
||||||
|
loop-explicit:
|
||||||
|
cmds:
|
||||||
|
- for: ["a", "b", "c"]
|
||||||
|
cmd: echo "{{.ITEM}}"
|
||||||
|
|
||||||
|
# Loop over the task's sources
|
||||||
|
loop-sources:
|
||||||
|
sources:
|
||||||
|
- foo.txt
|
||||||
|
- bar.txt
|
||||||
|
cmds:
|
||||||
|
- for: source
|
||||||
|
cmd: cat "{{.ITEM}}"
|
||||||
|
|
||||||
|
# Loop over the task's sources when globbed
|
||||||
|
loop-sources-glob:
|
||||||
|
sources:
|
||||||
|
- "*.txt"
|
||||||
|
cmds:
|
||||||
|
- for: source
|
||||||
|
cmd: cat "{{.ITEM}}"
|
||||||
|
|
||||||
|
# Loop over the contents of a variable
|
||||||
|
loop-vars:
|
||||||
|
vars:
|
||||||
|
FOO: foo.txt,bar.txt
|
||||||
|
cmds:
|
||||||
|
- for:
|
||||||
|
var: FOO
|
||||||
|
split: ","
|
||||||
|
cmd: cat "{{.ITEM}}"
|
||||||
|
|
||||||
|
# Loop over the output of a command (auto splits on " ")
|
||||||
|
loop-vars-sh:
|
||||||
|
vars:
|
||||||
|
FOO:
|
||||||
|
sh: ls *.txt
|
||||||
|
cmds:
|
||||||
|
- for:
|
||||||
|
var: FOO
|
||||||
|
cmd: cat "{{.ITEM}}"
|
||||||
|
|
||||||
|
# Loop over another task
|
||||||
|
loop-task:
|
||||||
|
vars:
|
||||||
|
FOO: foo.txt bar.txt
|
||||||
|
cmds:
|
||||||
|
- for:
|
||||||
|
var: FOO
|
||||||
|
task: looped-task
|
||||||
|
vars:
|
||||||
|
FILE: "{{.ITEM}}"
|
||||||
|
|
||||||
|
# Loop over another task with the variable named differently
|
||||||
|
loop-task-as:
|
||||||
|
vars:
|
||||||
|
FOO: foo.txt bar.txt
|
||||||
|
cmds:
|
||||||
|
- for:
|
||||||
|
var: FOO
|
||||||
|
as: FILE
|
||||||
|
task: looped-task
|
||||||
|
vars:
|
||||||
|
FILE: "{{.FILE}}"
|
||||||
|
|
||||||
|
# Loop over different tasks using the variable
|
||||||
|
loop-different-tasks:
|
||||||
|
vars:
|
||||||
|
FOO: "1 2 3"
|
||||||
|
cmds:
|
||||||
|
- for:
|
||||||
|
var: FOO
|
||||||
|
task: task-{{.ITEM}}
|
||||||
|
|
||||||
|
looped-task:
|
||||||
|
internal: true
|
||||||
|
cmd: cat "{{.FILE}}"
|
||||||
|
|
||||||
|
task-1:
|
||||||
|
internal: true
|
||||||
|
cmd: echo "1"
|
||||||
|
|
||||||
|
task-2:
|
||||||
|
internal: true
|
||||||
|
cmd: echo "2"
|
||||||
|
|
||||||
|
task-3:
|
||||||
|
internal: true
|
||||||
|
cmd: echo "3"
|
1
testdata/for/bar.txt
vendored
Normal file
1
testdata/for/bar.txt
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
bar
|
1
testdata/for/foo.txt
vendored
Normal file
1
testdata/for/foo.txt
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
foo
|
52
variables.go
52
variables.go
@ -124,10 +124,60 @@ func (e *Executor) compiledTask(call taskfile.Call, evaluateShVars bool) (*taskf
|
|||||||
if cmd == nil {
|
if cmd == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
if cmd.For != nil {
|
||||||
|
var list []string
|
||||||
|
// Get the list from the explicit forh list
|
||||||
|
if cmd.For.List != nil && len(cmd.For.List) > 0 {
|
||||||
|
list = cmd.For.List
|
||||||
|
}
|
||||||
|
// Get the list from the task sources
|
||||||
|
if cmd.For.From == "source" {
|
||||||
|
list, err = fingerprint.Globs(new.Dir, new.Sources)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Get the list from a variable and split it up
|
||||||
|
if cmd.For.Var != "" {
|
||||||
|
if vars != nil {
|
||||||
|
v := vars.Get(cmd.For.Var)
|
||||||
|
if cmd.For.Split != "" {
|
||||||
|
list = strings.Split(v.Static, cmd.For.Split)
|
||||||
|
} else {
|
||||||
|
list = strings.Fields(v.Static)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Name the iterator variable
|
||||||
|
var as string
|
||||||
|
if cmd.For.As != "" {
|
||||||
|
as = cmd.For.As
|
||||||
|
} else {
|
||||||
|
as = "ITEM"
|
||||||
|
}
|
||||||
|
// Create a new command for each item in the list
|
||||||
|
for _, loopValue := range list {
|
||||||
|
extra := map[string]any{
|
||||||
|
as: loopValue,
|
||||||
|
}
|
||||||
|
new.Cmds = append(new.Cmds, &taskfile.Cmd{
|
||||||
|
Cmd: r.ReplaceWithExtra(cmd.Cmd, extra),
|
||||||
|
Task: r.ReplaceWithExtra(cmd.Task, extra),
|
||||||
|
Silent: cmd.Silent,
|
||||||
|
Set: cmd.Set,
|
||||||
|
Shopt: cmd.Shopt,
|
||||||
|
Vars: r.ReplaceVarsWithExtra(cmd.Vars, extra),
|
||||||
|
IgnoreError: cmd.IgnoreError,
|
||||||
|
Defer: cmd.Defer,
|
||||||
|
Platforms: cmd.Platforms,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
new.Cmds = append(new.Cmds, &taskfile.Cmd{
|
new.Cmds = append(new.Cmds, &taskfile.Cmd{
|
||||||
Cmd: r.Replace(cmd.Cmd),
|
Cmd: r.Replace(cmd.Cmd),
|
||||||
Silent: cmd.Silent,
|
|
||||||
Task: r.Replace(cmd.Task),
|
Task: r.Replace(cmd.Task),
|
||||||
|
Silent: cmd.Silent,
|
||||||
Set: cmd.Set,
|
Set: cmd.Set,
|
||||||
Shopt: cmd.Shopt,
|
Shopt: cmd.Shopt,
|
||||||
Vars: r.ReplaceVars(cmd.Vars),
|
Vars: r.ReplaceVars(cmd.Vars),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user