Skip to content

Commit 6f0f38b

Browse files
authored
feat: support for loops with generates (#2151)
1 parent a9de239 commit 6f0f38b

File tree

11 files changed

+113
-3
lines changed

11 files changed

+113
-3
lines changed

executor_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -759,6 +759,8 @@ func TestForCmds(t *testing.T) {
759759
},
760760
{name: "loop-sources"},
761761
{name: "loop-sources-glob"},
762+
{name: "loop-generates"},
763+
{name: "loop-generates-glob"},
762764
{name: "loop-vars"},
763765
{name: "loop-vars-sh"},
764766
{name: "loop-task"},
@@ -800,6 +802,8 @@ func TestForDeps(t *testing.T) {
800802
},
801803
{name: "loop-sources"},
802804
{name: "loop-sources-glob"},
805+
{name: "loop-generates"},
806+
{name: "loop-generates-glob"},
803807
{name: "loop-vars"},
804808
{name: "loop-vars-sh"},
805809
{name: "loop-task"},

testdata/for/cmds/Taskfile.yml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,23 @@ tasks:
5757
- for: sources
5858
cmd: cat "{{.ITEM}}"
5959

60+
# Loop over the task's generates
61+
loop-generates:
62+
generates:
63+
- foo.txt
64+
- bar.txt
65+
cmds:
66+
- for: generates
67+
cmd: cat "{{.ITEM}}"
68+
69+
# Loop over the task's generates when globbed
70+
loop-generates-glob:
71+
generates:
72+
- "*.txt"
73+
cmds:
74+
- for: generates
75+
cmd: cat "{{.ITEM}}"
76+
6077
# Loop over the contents of a variable
6178
loop-vars:
6279
vars:
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
bar
2+
foo
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
bar
2+
foo

testdata/for/deps/Taskfile.yml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,27 @@ tasks:
6969
vars:
7070
FILE: "{{.ITEM}}"
7171

72+
# Loop over the task's generates
73+
loop-generates:
74+
generates:
75+
- foo.txt
76+
- bar.txt
77+
deps:
78+
- for: generates
79+
task: cat
80+
vars:
81+
FILE: "{{.ITEM}}"
82+
83+
# Loop over the task's generates when globbed
84+
loop-generates-glob:
85+
generates:
86+
- "*.txt"
87+
deps:
88+
- for: generates
89+
task: cat
90+
vars:
91+
FILE: "{{.ITEM}}"
92+
7293
# Loop over the contents of a variable
7394
loop-vars:
7495
vars:
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
bar
2+
foo
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
bar
2+
foo

variables.go

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ func (e *Executor) compiledTask(call *Call, evaluateShVars bool) (*ast.Task, err
153153
continue
154154
}
155155
if cmd.For != nil {
156-
list, keys, err := itemsFromFor(cmd.For, new.Dir, new.Sources, vars, origTask.Location, cache)
156+
list, keys, err := itemsFromFor(cmd.For, new.Dir, new.Sources, new.Generates, vars, origTask.Location, cache)
157157
if err != nil {
158158
return nil, err
159159
}
@@ -200,7 +200,7 @@ func (e *Executor) compiledTask(call *Call, evaluateShVars bool) (*ast.Task, err
200200
continue
201201
}
202202
if dep.For != nil {
203-
list, keys, err := itemsFromFor(dep.For, new.Dir, new.Sources, vars, origTask.Location, cache)
203+
list, keys, err := itemsFromFor(dep.For, new.Dir, new.Sources, new.Generates, vars, origTask.Location, cache)
204204
if err != nil {
205205
return nil, err
206206
}
@@ -270,6 +270,7 @@ func itemsFromFor(
270270
f *ast.For,
271271
dir string,
272272
sources []*ast.Glob,
273+
generates []*ast.Glob,
273274
vars *ast.Vars,
274275
location *ast.Location,
275276
cache *templater.Cache,
@@ -304,6 +305,20 @@ func itemsFromFor(
304305
}
305306
values = asAnySlice(glist)
306307
}
308+
// Get the list from the task generates
309+
if f.From == "generates" {
310+
glist, err := fingerprint.Globs(dir, generates)
311+
if err != nil {
312+
return nil, nil, err
313+
}
314+
// Make the paths relative to the task dir
315+
for i, v := range glist {
316+
if glist[i], err = filepath.Rel(dir, v); err != nil {
317+
return nil, nil, err
318+
}
319+
}
320+
values = asAnySlice(glist)
321+
}
307322
// Get the list from a variable and split it up
308323
if f.Var != "" {
309324
if vars != nil {

website/docs/reference/schema.mdx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,9 @@ it is defined as a string, you can give it any of the following values:
199199
- `sources` - Will run the command for each source file defined on the task.
200200
(Glob patterns will be resolved, so `*.go` will run for every Go file that
201201
matches).
202+
- `generates` - Will run the command for each file defined in the task's generates
203+
list. (Glob patterns will be resolved, so `*.txt` will run for every text file
204+
that matches).
202205

203206
If it is defined as a list of strings, the command will be run for each value.
204207

website/docs/usage.mdx

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1483,6 +1483,48 @@ tasks:
14831483
cmd: cat {{joinPath .MY_DIR .ITEM}}
14841484
```
14851485

1486+
### Looping over your task's generates
1487+
1488+
Similar to sources, you can also loop over the generates of your task:
1489+
1490+
```yaml
1491+
version: '3'
1492+
1493+
tasks:
1494+
default:
1495+
generates:
1496+
- foo.txt
1497+
- bar.txt
1498+
cmds:
1499+
- for: generates
1500+
cmd: cat {{ .ITEM }}
1501+
```
1502+
1503+
This will also work if you use globbing syntax in your generates. For example, if
1504+
you specify a generate for `*.txt`, the loop will iterate over all files that
1505+
match that glob.
1506+
1507+
Generate paths will always be returned as paths relative to the task directory. If
1508+
you need to convert this to an absolute path, you can use the built-in
1509+
`joinPath` function. There are some [special variables](/reference/templating/#special-variables)
1510+
that you may find useful for this.
1511+
1512+
```yaml
1513+
version: '3'
1514+
1515+
tasks:
1516+
default:
1517+
vars:
1518+
MY_DIR: /path/to/dir
1519+
dir: '{{.MY_DIR}}'
1520+
generates:
1521+
- foo.txt
1522+
- bar.txt
1523+
cmds:
1524+
- for: generates
1525+
cmd: cat {{joinPath .MY_DIR .ITEM}}
1526+
```
1527+
14861528
### Looping over variables
14871529

14881530
To loop over the contents of a variable, you simply need to specify the variable

0 commit comments

Comments
 (0)