mirror of
https://github.com/go-task/task.git
synced 2025-04-18 12:04:04 +03:00
feat: support for loops with generates (#2151)
This commit is contained in:
parent
a9de239e38
commit
6f0f38b8d9
@ -759,6 +759,8 @@ func TestForCmds(t *testing.T) {
|
||||
},
|
||||
{name: "loop-sources"},
|
||||
{name: "loop-sources-glob"},
|
||||
{name: "loop-generates"},
|
||||
{name: "loop-generates-glob"},
|
||||
{name: "loop-vars"},
|
||||
{name: "loop-vars-sh"},
|
||||
{name: "loop-task"},
|
||||
@ -800,6 +802,8 @@ func TestForDeps(t *testing.T) {
|
||||
},
|
||||
{name: "loop-sources"},
|
||||
{name: "loop-sources-glob"},
|
||||
{name: "loop-generates"},
|
||||
{name: "loop-generates-glob"},
|
||||
{name: "loop-vars"},
|
||||
{name: "loop-vars-sh"},
|
||||
{name: "loop-task"},
|
||||
|
17
testdata/for/cmds/Taskfile.yml
vendored
17
testdata/for/cmds/Taskfile.yml
vendored
@ -57,6 +57,23 @@ tasks:
|
||||
- for: sources
|
||||
cmd: cat "{{.ITEM}}"
|
||||
|
||||
# Loop over the task's generates
|
||||
loop-generates:
|
||||
generates:
|
||||
- foo.txt
|
||||
- bar.txt
|
||||
cmds:
|
||||
- for: generates
|
||||
cmd: cat "{{.ITEM}}"
|
||||
|
||||
# Loop over the task's generates when globbed
|
||||
loop-generates-glob:
|
||||
generates:
|
||||
- "*.txt"
|
||||
cmds:
|
||||
- for: generates
|
||||
cmd: cat "{{.ITEM}}"
|
||||
|
||||
# Loop over the contents of a variable
|
||||
loop-vars:
|
||||
vars:
|
||||
|
2
testdata/for/cmds/testdata/TestForCmds-loop-generates-glob.golden
vendored
Normal file
2
testdata/for/cmds/testdata/TestForCmds-loop-generates-glob.golden
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
bar
|
||||
foo
|
2
testdata/for/cmds/testdata/TestForCmds-loop-generates.golden
vendored
Normal file
2
testdata/for/cmds/testdata/TestForCmds-loop-generates.golden
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
bar
|
||||
foo
|
21
testdata/for/deps/Taskfile.yml
vendored
21
testdata/for/deps/Taskfile.yml
vendored
@ -69,6 +69,27 @@ tasks:
|
||||
vars:
|
||||
FILE: "{{.ITEM}}"
|
||||
|
||||
# Loop over the task's generates
|
||||
loop-generates:
|
||||
generates:
|
||||
- foo.txt
|
||||
- bar.txt
|
||||
deps:
|
||||
- for: generates
|
||||
task: cat
|
||||
vars:
|
||||
FILE: "{{.ITEM}}"
|
||||
|
||||
# Loop over the task's generates when globbed
|
||||
loop-generates-glob:
|
||||
generates:
|
||||
- "*.txt"
|
||||
deps:
|
||||
- for: generates
|
||||
task: cat
|
||||
vars:
|
||||
FILE: "{{.ITEM}}"
|
||||
|
||||
# Loop over the contents of a variable
|
||||
loop-vars:
|
||||
vars:
|
||||
|
2
testdata/for/deps/testdata/TestForDeps-loop-generates-glob.golden
vendored
Normal file
2
testdata/for/deps/testdata/TestForDeps-loop-generates-glob.golden
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
bar
|
||||
foo
|
2
testdata/for/deps/testdata/TestForDeps-loop-generates.golden
vendored
Normal file
2
testdata/for/deps/testdata/TestForDeps-loop-generates.golden
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
bar
|
||||
foo
|
19
variables.go
19
variables.go
@ -153,7 +153,7 @@ func (e *Executor) compiledTask(call *Call, evaluateShVars bool) (*ast.Task, err
|
||||
continue
|
||||
}
|
||||
if cmd.For != nil {
|
||||
list, keys, err := itemsFromFor(cmd.For, new.Dir, new.Sources, vars, origTask.Location, cache)
|
||||
list, keys, err := itemsFromFor(cmd.For, new.Dir, new.Sources, new.Generates, vars, origTask.Location, cache)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -200,7 +200,7 @@ func (e *Executor) compiledTask(call *Call, evaluateShVars bool) (*ast.Task, err
|
||||
continue
|
||||
}
|
||||
if dep.For != nil {
|
||||
list, keys, err := itemsFromFor(dep.For, new.Dir, new.Sources, vars, origTask.Location, cache)
|
||||
list, keys, err := itemsFromFor(dep.For, new.Dir, new.Sources, new.Generates, vars, origTask.Location, cache)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -270,6 +270,7 @@ func itemsFromFor(
|
||||
f *ast.For,
|
||||
dir string,
|
||||
sources []*ast.Glob,
|
||||
generates []*ast.Glob,
|
||||
vars *ast.Vars,
|
||||
location *ast.Location,
|
||||
cache *templater.Cache,
|
||||
@ -304,6 +305,20 @@ func itemsFromFor(
|
||||
}
|
||||
values = asAnySlice(glist)
|
||||
}
|
||||
// Get the list from the task generates
|
||||
if f.From == "generates" {
|
||||
glist, err := fingerprint.Globs(dir, generates)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
// Make the paths relative to the task dir
|
||||
for i, v := range glist {
|
||||
if glist[i], err = filepath.Rel(dir, v); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
}
|
||||
values = asAnySlice(glist)
|
||||
}
|
||||
// Get the list from a variable and split it up
|
||||
if f.Var != "" {
|
||||
if vars != nil {
|
||||
|
@ -199,6 +199,9 @@ it is defined as a string, you can give it any of the following values:
|
||||
- `sources` - Will run the command for each source file defined on the task.
|
||||
(Glob patterns will be resolved, so `*.go` will run for every Go file that
|
||||
matches).
|
||||
- `generates` - Will run the command for each file defined in the task's generates
|
||||
list. (Glob patterns will be resolved, so `*.txt` will run for every text file
|
||||
that matches).
|
||||
|
||||
If it is defined as a list of strings, the command will be run for each value.
|
||||
|
||||
|
@ -1483,6 +1483,48 @@ tasks:
|
||||
cmd: cat {{joinPath .MY_DIR .ITEM}}
|
||||
```
|
||||
|
||||
### Looping over your task's generates
|
||||
|
||||
Similar to sources, you can also loop over the generates of your task:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
default:
|
||||
generates:
|
||||
- foo.txt
|
||||
- bar.txt
|
||||
cmds:
|
||||
- for: generates
|
||||
cmd: cat {{ .ITEM }}
|
||||
```
|
||||
|
||||
This will also work if you use globbing syntax in your generates. For example, if
|
||||
you specify a generate for `*.txt`, the loop will iterate over all files that
|
||||
match that glob.
|
||||
|
||||
Generate paths will always be returned as paths relative to the task directory. If
|
||||
you need to convert this to an absolute path, you can use the built-in
|
||||
`joinPath` function. There are some [special variables](/reference/templating/#special-variables)
|
||||
that you may find useful for this.
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
default:
|
||||
vars:
|
||||
MY_DIR: /path/to/dir
|
||||
dir: '{{.MY_DIR}}'
|
||||
generates:
|
||||
- foo.txt
|
||||
- bar.txt
|
||||
cmds:
|
||||
- for: generates
|
||||
cmd: cat {{joinPath .MY_DIR .ITEM}}
|
||||
```
|
||||
|
||||
### Looping over variables
|
||||
|
||||
To loop over the contents of a variable, you simply need to specify the variable
|
||||
|
@ -475,7 +475,7 @@
|
||||
"for_attribute": {
|
||||
"description": "The task attribute to iterate over",
|
||||
"type": "string",
|
||||
"enum": ["sources"]
|
||||
"enum": ["sources", "generates"]
|
||||
},
|
||||
"for_var": {
|
||||
"description": "Which variables to iterate over. The variable will be split using any whitespace character by default. This can be changed by using the `split` attribute.",
|
||||
|
Loading…
x
Reference in New Issue
Block a user