Skip to content

Commit a9ca5c6

Browse files
committed
feat: iterators
1 parent 9dbd04a commit a9ca5c6

File tree

12 files changed

+154
-129
lines changed

12 files changed

+154
-129
lines changed

help.go

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -132,16 +132,10 @@ func (e *Executor) ListTaskNames(allTasks bool) error {
132132
if e.TaskSorter == nil {
133133
e.TaskSorter = sort.AlphaNumericWithRootTasksFirst
134134
}
135-
keys := e.Taskfile.Tasks.Keys()
136-
e.TaskSorter(keys, nil)
137135

138136
// Create a list of task names
139137
taskNames := make([]string, 0, e.Taskfile.Tasks.Len())
140-
for _, key := range keys {
141-
task, ok := e.Taskfile.Tasks.Get(key)
142-
if !ok {
143-
continue
144-
}
138+
for task := range e.Taskfile.Tasks.Values(e.TaskSorter) {
145139
if (allTasks || task.Desc != "") && !task.Internal {
146140
taskNames = append(taskNames, strings.TrimRight(task.Task, ":"))
147141
for _, alias := range task.Aliases {

internal/compiler/compiler.go

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -103,30 +103,42 @@ func (c *Compiler) getVariables(t *ast.Task, call *ast.Call, evaluateShVars bool
103103
taskRangeFunc = getRangeFunc(dir)
104104
}
105105

106-
if err := c.TaskfileEnv.Range(rangeFunc); err != nil {
107-
return nil, err
106+
for k, v := range c.TaskfileEnv.All() {
107+
if err := rangeFunc(k, v); err != nil {
108+
return nil, err
109+
}
108110
}
109-
if err := c.TaskfileVars.Range(rangeFunc); err != nil {
110-
return nil, err
111+
for k, v := range c.TaskfileVars.All() {
112+
if err := rangeFunc(k, v); err != nil {
113+
return nil, err
114+
}
111115
}
112116
if t != nil {
113-
if err := t.IncludeVars.Range(rangeFunc); err != nil {
114-
return nil, err
117+
for k, v := range t.IncludeVars.All() {
118+
if err := rangeFunc(k, v); err != nil {
119+
return nil, err
120+
}
115121
}
116-
if err := t.IncludedTaskfileVars.Range(taskRangeFunc); err != nil {
117-
return nil, err
122+
for k, v := range t.IncludedTaskfileVars.All() {
123+
if err := taskRangeFunc(k, v); err != nil {
124+
return nil, err
125+
}
118126
}
119127
}
120128

121129
if t == nil || call == nil {
122130
return result, nil
123131
}
124132

125-
if err := call.Vars.Range(rangeFunc); err != nil {
126-
return nil, err
133+
for k, v := range call.Vars.All() {
134+
if err := rangeFunc(k, v); err != nil {
135+
return nil, err
136+
}
127137
}
128-
if err := t.Vars.Range(taskRangeFunc); err != nil {
129-
return nil, err
138+
for k, v := range t.Vars.All() {
139+
if err := taskRangeFunc(k, v); err != nil {
140+
return nil, err
141+
}
130142
}
131143

132144
return result, nil

internal/templater/templater.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -141,10 +141,9 @@ func ReplaceVarsWithExtra(vars *ast.Vars, cache *Cache, extra map[string]any) *a
141141
}
142142

143143
newVars := ast.NewVars()
144-
_ = vars.Range(func(k string, v ast.Var) error {
144+
for k, v := range vars.All() {
145145
newVars.Set(k, ReplaceVarWithExtra(v, cache, extra))
146-
return nil
147-
})
146+
}
148147

149148
return newVars
150149
}

setup.go

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -92,12 +92,9 @@ func (e *Executor) setupFuzzyModel() {
9292
model.SetThreshold(1) // because we want to build grammar based on every task name
9393

9494
var words []string
95-
for _, taskName := range e.Taskfile.Tasks.Keys() {
96-
words = append(words, taskName)
97-
98-
for _, task := range e.Taskfile.Tasks.Values() {
99-
words = slices.Concat(words, task.Aliases)
100-
}
95+
for name, task := range e.Taskfile.Tasks.All(nil) {
96+
words = append(words, name)
97+
words = slices.Concat(words, task.Aliases)
10198
}
10299

103100
model.Train(words)
@@ -212,12 +209,11 @@ func (e *Executor) readDotEnvFiles() error {
212209
return err
213210
}
214211

215-
err = env.Range(func(key string, value ast.Var) error {
216-
if _, ok := e.Taskfile.Env.Get(key); !ok {
217-
e.Taskfile.Env.Set(key, value)
212+
for k, v := range env.All() {
213+
if _, ok := e.Taskfile.Env.Get(k); !ok {
214+
e.Taskfile.Env.Set(k, v)
218215
}
219-
return nil
220-
})
216+
}
221217
return err
222218
}
223219

@@ -235,7 +231,7 @@ func (e *Executor) setupConcurrencyState() {
235231

236232
e.taskCallCount = make(map[string]*int32, e.Taskfile.Tasks.Len())
237233
e.mkdirMutexMap = make(map[string]*sync.Mutex, e.Taskfile.Tasks.Len())
238-
for _, k := range e.Taskfile.Tasks.Keys() {
234+
for k := range e.Taskfile.Tasks.Keys(nil) {
239235
e.taskCallCount[k] = new(int32)
240236
e.mkdirMutexMap[k] = &sync.Mutex{}
241237
}

task.go

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -470,7 +470,7 @@ func (e *Executor) GetTask(call *ast.Call) (*ast.Task, error) {
470470
// If didn't find one, search for a task with a matching alias
471471
var matchingTask *ast.Task
472472
var aliasedTasks []string
473-
for _, task := range e.Taskfile.Tasks.Values() {
473+
for task := range e.Taskfile.Tasks.Values(nil) {
474474
if slices.Contains(task.Aliases, call.Task) {
475475
aliasedTasks = append(aliasedTasks, task.Task)
476476
matchingTask = task
@@ -510,15 +510,9 @@ func (e *Executor) GetTaskList(filters ...FilterFunc) ([]*ast.Task, error) {
510510
if e.TaskSorter == nil {
511511
e.TaskSorter = sort.AlphaNumericWithRootTasksFirst
512512
}
513-
keys := e.Taskfile.Tasks.Keys()
514-
e.TaskSorter(keys, nil)
515513

516514
// Filter tasks based on the given filter functions
517-
for _, key := range keys {
518-
task, ok := e.Taskfile.Tasks.Get(key)
519-
if !ok {
520-
continue
521-
}
515+
for task := range e.Taskfile.Tasks.Values(e.TaskSorter) {
522516
var shouldFilter bool
523517
for _, filter := range filters {
524518
if filter(task) {

taskfile/ast/graph.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -116,14 +116,14 @@ func (tfg *TaskfileGraph) Merge() (*Taskfile, error) {
116116
return nil, err
117117
}
118118

119-
_ = rootVertex.Taskfile.Tasks.Range(func(name string, task *Task) error {
119+
// TODO: I don't think this is necessary anymore
120+
for name, task := range rootVertex.Taskfile.Tasks.All(nil) {
120121
if task == nil {
121122
task = &Task{}
122123
rootVertex.Taskfile.Tasks.Set(name, task)
123124
}
124125
task.Task = name
125-
return nil
126-
})
126+
}
127127

128128
return rootVertex.Taskfile, nil
129129
}

taskfile/ast/include.go

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package ast
22

33
import (
4+
"iter"
45
"sync"
56

67
"github.com/elliotchance/orderedmap/v3"
@@ -84,19 +85,31 @@ func (includes *Includes) Set(key string, value *Include) bool {
8485
return includes.om.Set(key, value)
8586
}
8687

88+
// All returns an iterator that loops over all task key-value pairs.
8789
// Range calls the provided function for each include in the map. The function
8890
// receives the include's key and value as arguments. If the function returns
8991
// an error, the iteration stops and the error is returned.
90-
func (includes *Includes) Range(f func(k string, v *Include) error) error {
92+
func (includes *Includes) All() iter.Seq2[string, *Include] {
9193
if includes == nil || includes.om == nil {
92-
return nil
94+
return func(yield func(string, *Include) bool) {}
9395
}
94-
for pair := includes.om.Front(); pair != nil; pair = pair.Next() {
95-
if err := f(pair.Key, pair.Value); err != nil {
96-
return err
97-
}
96+
return includes.om.AllFromFront()
97+
}
98+
99+
// Keys returns an iterator that loops over all task keys.
100+
func (includes *Includes) Keys() iter.Seq[string] {
101+
if includes == nil || includes.om == nil {
102+
return func(yield func(string) bool) {}
103+
}
104+
return includes.om.Keys()
105+
}
106+
107+
// Values returns an iterator that loops over all task values.
108+
func (includes *Includes) Values() iter.Seq[*Include] {
109+
if includes == nil || includes.om == nil {
110+
return func(yield func(*Include) bool) {}
98111
}
99-
return nil
112+
return includes.om.Values()
100113
}
101114

102115
// UnmarshalYAML implements the yaml.Unmarshaler interface.

taskfile/ast/matrix.go

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package ast
22

33
import (
4+
"iter"
5+
46
"github.com/elliotchance/orderedmap/v3"
57
"gopkg.in/yaml.v3"
68

@@ -48,16 +50,28 @@ func (matrix *Matrix) Set(key string, value []any) bool {
4850
return matrix.om.Set(key, value)
4951
}
5052

51-
func (matrix *Matrix) Range(f func(k string, v []any) error) error {
53+
// All returns an iterator that loops over all task key-value pairs.
54+
func (matrix *Matrix) All() iter.Seq2[string, []any] {
5255
if matrix == nil || matrix.om == nil {
53-
return nil
56+
return func(yield func(string, []any) bool) {}
5457
}
55-
for pair := matrix.om.Front(); pair != nil; pair = pair.Next() {
56-
if err := f(pair.Key, pair.Value); err != nil {
57-
return err
58-
}
58+
return matrix.om.AllFromFront()
59+
}
60+
61+
// Keys returns an iterator that loops over all task keys.
62+
func (matrix *Matrix) Keys() iter.Seq[string] {
63+
if matrix == nil || matrix.om == nil {
64+
return func(yield func(string) bool) {}
65+
}
66+
return matrix.om.Keys()
67+
}
68+
69+
// Values returns an iterator that loops over all task values.
70+
func (matrix *Matrix) Values() iter.Seq[[]any] {
71+
if matrix == nil || matrix.om == nil {
72+
return func(yield func([]any) bool) {}
5973
}
60-
return nil
74+
return matrix.om.Values()
6175
}
6276

6377
func (matrix *Matrix) DeepCopy() *Matrix {

0 commit comments

Comments
 (0)