Skip to content

Commit

Permalink
feat: iterators
Browse files Browse the repository at this point in the history
  • Loading branch information
pd93 committed Jan 26, 2025
1 parent 9dbd04a commit a9ca5c6
Show file tree
Hide file tree
Showing 12 changed files with 154 additions and 129 deletions.
8 changes: 1 addition & 7 deletions help.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,16 +132,10 @@ func (e *Executor) ListTaskNames(allTasks bool) error {
if e.TaskSorter == nil {
e.TaskSorter = sort.AlphaNumericWithRootTasksFirst
}
keys := e.Taskfile.Tasks.Keys()
e.TaskSorter(keys, nil)

// Create a list of task names
taskNames := make([]string, 0, e.Taskfile.Tasks.Len())
for _, key := range keys {
task, ok := e.Taskfile.Tasks.Get(key)
if !ok {
continue
}
for task := range e.Taskfile.Tasks.Values(e.TaskSorter) {
if (allTasks || task.Desc != "") && !task.Internal {
taskNames = append(taskNames, strings.TrimRight(task.Task, ":"))
for _, alias := range task.Aliases {
Expand Down
36 changes: 24 additions & 12 deletions internal/compiler/compiler.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,30 +103,42 @@ func (c *Compiler) getVariables(t *ast.Task, call *ast.Call, evaluateShVars bool
taskRangeFunc = getRangeFunc(dir)
}

if err := c.TaskfileEnv.Range(rangeFunc); err != nil {
return nil, err
for k, v := range c.TaskfileEnv.All() {
if err := rangeFunc(k, v); err != nil {
return nil, err
}
}
if err := c.TaskfileVars.Range(rangeFunc); err != nil {
return nil, err
for k, v := range c.TaskfileVars.All() {
if err := rangeFunc(k, v); err != nil {
return nil, err
}
}
if t != nil {
if err := t.IncludeVars.Range(rangeFunc); err != nil {
return nil, err
for k, v := range t.IncludeVars.All() {
if err := rangeFunc(k, v); err != nil {
return nil, err
}
}
if err := t.IncludedTaskfileVars.Range(taskRangeFunc); err != nil {
return nil, err
for k, v := range t.IncludedTaskfileVars.All() {
if err := taskRangeFunc(k, v); err != nil {
return nil, err
}
}
}

if t == nil || call == nil {
return result, nil
}

if err := call.Vars.Range(rangeFunc); err != nil {
return nil, err
for k, v := range call.Vars.All() {
if err := rangeFunc(k, v); err != nil {
return nil, err
}
}
if err := t.Vars.Range(taskRangeFunc); err != nil {
return nil, err
for k, v := range t.Vars.All() {
if err := taskRangeFunc(k, v); err != nil {
return nil, err
}
}

return result, nil
Expand Down
5 changes: 2 additions & 3 deletions internal/templater/templater.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,10 +141,9 @@ func ReplaceVarsWithExtra(vars *ast.Vars, cache *Cache, extra map[string]any) *a
}

newVars := ast.NewVars()
_ = vars.Range(func(k string, v ast.Var) error {
for k, v := range vars.All() {
newVars.Set(k, ReplaceVarWithExtra(v, cache, extra))
return nil
})
}

return newVars
}
20 changes: 8 additions & 12 deletions setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,12 +92,9 @@ func (e *Executor) setupFuzzyModel() {
model.SetThreshold(1) // because we want to build grammar based on every task name

var words []string
for _, taskName := range e.Taskfile.Tasks.Keys() {
words = append(words, taskName)

for _, task := range e.Taskfile.Tasks.Values() {
words = slices.Concat(words, task.Aliases)
}
for name, task := range e.Taskfile.Tasks.All(nil) {
words = append(words, name)
words = slices.Concat(words, task.Aliases)
}

model.Train(words)
Expand Down Expand Up @@ -212,12 +209,11 @@ func (e *Executor) readDotEnvFiles() error {
return err
}

err = env.Range(func(key string, value ast.Var) error {
if _, ok := e.Taskfile.Env.Get(key); !ok {
e.Taskfile.Env.Set(key, value)
for k, v := range env.All() {
if _, ok := e.Taskfile.Env.Get(k); !ok {
e.Taskfile.Env.Set(k, v)
}
return nil
})
}
return err
}

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

e.taskCallCount = make(map[string]*int32, e.Taskfile.Tasks.Len())
e.mkdirMutexMap = make(map[string]*sync.Mutex, e.Taskfile.Tasks.Len())
for _, k := range e.Taskfile.Tasks.Keys() {
for k := range e.Taskfile.Tasks.Keys(nil) {
e.taskCallCount[k] = new(int32)
e.mkdirMutexMap[k] = &sync.Mutex{}
}
Expand Down
10 changes: 2 additions & 8 deletions task.go
Original file line number Diff line number Diff line change
Expand Up @@ -470,7 +470,7 @@ func (e *Executor) GetTask(call *ast.Call) (*ast.Task, error) {
// If didn't find one, search for a task with a matching alias
var matchingTask *ast.Task
var aliasedTasks []string
for _, task := range e.Taskfile.Tasks.Values() {
for task := range e.Taskfile.Tasks.Values(nil) {
if slices.Contains(task.Aliases, call.Task) {
aliasedTasks = append(aliasedTasks, task.Task)
matchingTask = task
Expand Down Expand Up @@ -510,15 +510,9 @@ func (e *Executor) GetTaskList(filters ...FilterFunc) ([]*ast.Task, error) {
if e.TaskSorter == nil {
e.TaskSorter = sort.AlphaNumericWithRootTasksFirst
}
keys := e.Taskfile.Tasks.Keys()
e.TaskSorter(keys, nil)

// Filter tasks based on the given filter functions
for _, key := range keys {
task, ok := e.Taskfile.Tasks.Get(key)
if !ok {
continue
}
for task := range e.Taskfile.Tasks.Values(e.TaskSorter) {
var shouldFilter bool
for _, filter := range filters {
if filter(task) {
Expand Down
6 changes: 3 additions & 3 deletions taskfile/ast/graph.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,14 +116,14 @@ func (tfg *TaskfileGraph) Merge() (*Taskfile, error) {
return nil, err
}

_ = rootVertex.Taskfile.Tasks.Range(func(name string, task *Task) error {
// TODO: I don't think this is necessary anymore
for name, task := range rootVertex.Taskfile.Tasks.All(nil) {
if task == nil {
task = &Task{}
rootVertex.Taskfile.Tasks.Set(name, task)
}
task.Task = name
return nil
})
}

return rootVertex.Taskfile, nil
}
27 changes: 20 additions & 7 deletions taskfile/ast/include.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package ast

import (
"iter"
"sync"

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

// All returns an iterator that loops over all task key-value pairs.
// Range calls the provided function for each include in the map. The function
// receives the include's key and value as arguments. If the function returns
// an error, the iteration stops and the error is returned.
func (includes *Includes) Range(f func(k string, v *Include) error) error {
func (includes *Includes) All() iter.Seq2[string, *Include] {
if includes == nil || includes.om == nil {
return nil
return func(yield func(string, *Include) bool) {}
}
for pair := includes.om.Front(); pair != nil; pair = pair.Next() {
if err := f(pair.Key, pair.Value); err != nil {
return err
}
return includes.om.AllFromFront()
}

// Keys returns an iterator that loops over all task keys.
func (includes *Includes) Keys() iter.Seq[string] {
if includes == nil || includes.om == nil {
return func(yield func(string) bool) {}
}
return includes.om.Keys()
}

// Values returns an iterator that loops over all task values.
func (includes *Includes) Values() iter.Seq[*Include] {
if includes == nil || includes.om == nil {
return func(yield func(*Include) bool) {}
}
return nil
return includes.om.Values()
}

// UnmarshalYAML implements the yaml.Unmarshaler interface.
Expand Down
28 changes: 21 additions & 7 deletions taskfile/ast/matrix.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package ast

import (
"iter"

"github.com/elliotchance/orderedmap/v3"
"gopkg.in/yaml.v3"

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

func (matrix *Matrix) Range(f func(k string, v []any) error) error {
// All returns an iterator that loops over all task key-value pairs.
func (matrix *Matrix) All() iter.Seq2[string, []any] {
if matrix == nil || matrix.om == nil {
return nil
return func(yield func(string, []any) bool) {}
}
for pair := matrix.om.Front(); pair != nil; pair = pair.Next() {
if err := f(pair.Key, pair.Value); err != nil {
return err
}
return matrix.om.AllFromFront()
}

// Keys returns an iterator that loops over all task keys.
func (matrix *Matrix) Keys() iter.Seq[string] {
if matrix == nil || matrix.om == nil {
return func(yield func(string) bool) {}
}
return matrix.om.Keys()
}

// Values returns an iterator that loops over all task values.
func (matrix *Matrix) Values() iter.Seq[[]any] {
if matrix == nil || matrix.om == nil {
return func(yield func([]any) bool) {}
}
return nil
return matrix.om.Values()
}

func (matrix *Matrix) DeepCopy() *Matrix {
Expand Down
Loading

0 comments on commit a9ca5c6

Please sign in to comment.