mirror of
https://github.com/go-task/task.git
synced 2024-12-12 10:45:49 +02:00
feat: iterators
This commit is contained in:
parent
dd55d6e96b
commit
5ff80ea475
8
help.go
8
help.go
@ -132,16 +132,10 @@ func (e *Executor) ListTaskNames(allTasks bool) error {
|
|||||||
if e.TaskSorter == nil {
|
if e.TaskSorter == nil {
|
||||||
e.TaskSorter = sort.AlphaNumericWithRootTasksFirst
|
e.TaskSorter = sort.AlphaNumericWithRootTasksFirst
|
||||||
}
|
}
|
||||||
keys := e.Taskfile.Tasks.Keys()
|
|
||||||
e.TaskSorter(keys, nil)
|
|
||||||
|
|
||||||
// Create a list of task names
|
// Create a list of task names
|
||||||
taskNames := make([]string, 0, e.Taskfile.Tasks.Len())
|
taskNames := make([]string, 0, e.Taskfile.Tasks.Len())
|
||||||
for _, key := range keys {
|
for task := range e.Taskfile.Tasks.Values(e.TaskSorter) {
|
||||||
task, ok := e.Taskfile.Tasks.Get(key)
|
|
||||||
if !ok {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if (allTasks || task.Desc != "") && !task.Internal {
|
if (allTasks || task.Desc != "") && !task.Internal {
|
||||||
taskNames = append(taskNames, strings.TrimRight(task.Task, ":"))
|
taskNames = append(taskNames, strings.TrimRight(task.Task, ":"))
|
||||||
for _, alias := range task.Aliases {
|
for _, alias := range task.Aliases {
|
||||||
|
@ -104,30 +104,42 @@ func (c *Compiler) getVariables(t *ast.Task, call *ast.Call, evaluateShVars bool
|
|||||||
taskRangeFunc = getRangeFunc(dir)
|
taskRangeFunc = getRangeFunc(dir)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := c.TaskfileEnv.Range(rangeFunc); err != nil {
|
for k, v := range c.TaskfileEnv.All() {
|
||||||
return nil, err
|
if err := rangeFunc(k, v); err != nil {
|
||||||
}
|
|
||||||
if err := c.TaskfileVars.Range(rangeFunc); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if t != nil {
|
|
||||||
if err := t.IncludeVars.Range(rangeFunc); err != nil {
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if err := t.IncludedTaskfileVars.Range(taskRangeFunc); err != nil {
|
}
|
||||||
|
for k, v := range c.TaskfileVars.All() {
|
||||||
|
if err := rangeFunc(k, v); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if t != nil {
|
||||||
|
for k, v := range t.IncludeVars.All() {
|
||||||
|
if err := rangeFunc(k, v); 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 {
|
if t == nil || call == nil {
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := call.Vars.Range(rangeFunc); err != nil {
|
for k, v := range call.Vars.All() {
|
||||||
return nil, err
|
if err := rangeFunc(k, v); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if err := t.Vars.Range(taskRangeFunc); err != nil {
|
for k, v := range t.Vars.All() {
|
||||||
return nil, err
|
if err := taskRangeFunc(k, v); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result, nil
|
return result, nil
|
||||||
|
@ -141,10 +141,9 @@ func ReplaceVarsWithExtra(vars *ast.Vars, cache *Cache, extra map[string]any) *a
|
|||||||
}
|
}
|
||||||
|
|
||||||
var newVars ast.Vars
|
var newVars ast.Vars
|
||||||
_ = vars.Range(func(k string, v ast.Var) error {
|
for k, v := range vars.All() {
|
||||||
newVars.Set(k, ReplaceVarWithExtra(v, cache, extra))
|
newVars.Set(k, ReplaceVarWithExtra(v, cache, extra))
|
||||||
return nil
|
}
|
||||||
})
|
|
||||||
|
|
||||||
return &newVars
|
return &newVars
|
||||||
}
|
}
|
||||||
|
20
setup.go
20
setup.go
@ -92,12 +92,9 @@ func (e *Executor) setupFuzzyModel() {
|
|||||||
model.SetThreshold(1) // because we want to build grammar based on every task name
|
model.SetThreshold(1) // because we want to build grammar based on every task name
|
||||||
|
|
||||||
var words []string
|
var words []string
|
||||||
for _, taskName := range e.Taskfile.Tasks.Keys() {
|
for name, task := range e.Taskfile.Tasks.All(nil) {
|
||||||
words = append(words, taskName)
|
words = append(words, name)
|
||||||
|
words = slices.Concat(words, task.Aliases)
|
||||||
for _, task := range e.Taskfile.Tasks.Values() {
|
|
||||||
words = slices.Concat(words, task.Aliases)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
model.Train(words)
|
model.Train(words)
|
||||||
@ -212,12 +209,11 @@ func (e *Executor) readDotEnvFiles() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = env.Range(func(key string, value ast.Var) error {
|
for k, v := range env.All() {
|
||||||
if _, ok := e.Taskfile.Env.Get(key); !ok {
|
if _, ok := e.Taskfile.Env.Get(k); !ok {
|
||||||
e.Taskfile.Env.Set(key, value)
|
e.Taskfile.Env.Set(k, v)
|
||||||
}
|
}
|
||||||
return nil
|
}
|
||||||
})
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -235,7 +231,7 @@ func (e *Executor) setupConcurrencyState() {
|
|||||||
|
|
||||||
e.taskCallCount = make(map[string]*int32, e.Taskfile.Tasks.Len())
|
e.taskCallCount = make(map[string]*int32, e.Taskfile.Tasks.Len())
|
||||||
e.mkdirMutexMap = make(map[string]*sync.Mutex, 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.taskCallCount[k] = new(int32)
|
||||||
e.mkdirMutexMap[k] = &sync.Mutex{}
|
e.mkdirMutexMap[k] = &sync.Mutex{}
|
||||||
}
|
}
|
||||||
|
10
task.go
10
task.go
@ -462,7 +462,7 @@ func (e *Executor) GetTask(call *ast.Call) (*ast.Task, error) {
|
|||||||
// If didn't find one, search for a task with a matching alias
|
// If didn't find one, search for a task with a matching alias
|
||||||
var matchingTask *ast.Task
|
var matchingTask *ast.Task
|
||||||
var aliasedTasks []string
|
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) {
|
if slices.Contains(task.Aliases, call.Task) {
|
||||||
aliasedTasks = append(aliasedTasks, task.Task)
|
aliasedTasks = append(aliasedTasks, task.Task)
|
||||||
matchingTask = task
|
matchingTask = task
|
||||||
@ -502,15 +502,9 @@ func (e *Executor) GetTaskList(filters ...FilterFunc) ([]*ast.Task, error) {
|
|||||||
if e.TaskSorter == nil {
|
if e.TaskSorter == nil {
|
||||||
e.TaskSorter = sort.AlphaNumericWithRootTasksFirst
|
e.TaskSorter = sort.AlphaNumericWithRootTasksFirst
|
||||||
}
|
}
|
||||||
keys := e.Taskfile.Tasks.Keys()
|
|
||||||
e.TaskSorter(keys, nil)
|
|
||||||
|
|
||||||
// Filter tasks based on the given filter functions
|
// Filter tasks based on the given filter functions
|
||||||
for _, key := range keys {
|
for task := range e.Taskfile.Tasks.Values(e.TaskSorter) {
|
||||||
task, ok := e.Taskfile.Tasks.Get(key)
|
|
||||||
if !ok {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
var shouldFilter bool
|
var shouldFilter bool
|
||||||
for _, filter := range filters {
|
for _, filter := range filters {
|
||||||
if filter(task) {
|
if filter(task) {
|
||||||
|
@ -116,14 +116,14 @@ func (tfg *TaskfileGraph) Merge() (*Taskfile, error) {
|
|||||||
return nil, err
|
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 {
|
if task == nil {
|
||||||
task = &Task{}
|
task = &Task{}
|
||||||
rootVertex.Taskfile.Tasks.Set(name, task)
|
rootVertex.Taskfile.Tasks.Set(name, task)
|
||||||
}
|
}
|
||||||
task.Task = name
|
task.Task = name
|
||||||
return nil
|
}
|
||||||
})
|
|
||||||
|
|
||||||
return rootVertex.Taskfile, nil
|
return rootVertex.Taskfile, nil
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,13 @@
|
|||||||
package ast
|
package ast
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"iter"
|
||||||
|
|
||||||
"github.com/elliotchance/orderedmap/v2"
|
"github.com/elliotchance/orderedmap/v2"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
|
|
||||||
"github.com/go-task/task/v3/errors"
|
"github.com/go-task/task/v3/errors"
|
||||||
|
"github.com/go-task/task/v3/internal/sort"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Include represents information about included taskfiles
|
// Include represents information about included taskfiles
|
||||||
@ -61,16 +64,34 @@ func (includes *Includes) Set(key string, value *Include) bool {
|
|||||||
return includes.om.Set(key, value)
|
return includes.om.Set(key, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (includes *Includes) Range(f func(k string, v *Include) error) error {
|
// All returns an iterator that loops over all task key-value pairs.
|
||||||
|
func (includes *Includes) All() iter.Seq2[string, *Include] {
|
||||||
if includes == nil || includes.om == nil {
|
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() {
|
return includes.om.Iterator()
|
||||||
if err := f(pair.Key, pair.Value); err != nil {
|
}
|
||||||
return err
|
|
||||||
|
// Keys returns an iterator that loops over all task keys.
|
||||||
|
func (includes *Includes) Keys(sorter sort.Sorter) iter.Seq[string] {
|
||||||
|
return func(yield func(string) bool) {
|
||||||
|
for k := range includes.All() {
|
||||||
|
if !yield(k) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Values returns an iterator that loops over all task values.
|
||||||
|
func (includes *Includes) Values(sorter sort.Sorter) iter.Seq[*Include] {
|
||||||
|
return func(yield func(*Include) bool) {
|
||||||
|
for _, v := range includes.All() {
|
||||||
|
if !yield(v) {
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnmarshalYAML implements the yaml.Unmarshaler interface.
|
// UnmarshalYAML implements the yaml.Unmarshaler interface.
|
||||||
|
@ -1,11 +1,14 @@
|
|||||||
package ast
|
package ast
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"iter"
|
||||||
|
|
||||||
"github.com/elliotchance/orderedmap/v2"
|
"github.com/elliotchance/orderedmap/v2"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
|
|
||||||
"github.com/go-task/task/v3/errors"
|
"github.com/go-task/task/v3/errors"
|
||||||
"github.com/go-task/task/v3/internal/deepcopy"
|
"github.com/go-task/task/v3/internal/deepcopy"
|
||||||
|
"github.com/go-task/task/v3/internal/sort"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Matrix struct {
|
type Matrix struct {
|
||||||
@ -48,16 +51,31 @@ func (matrix *Matrix) Set(key string, value []any) bool {
|
|||||||
return matrix.om.Set(key, value)
|
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.
|
||||||
if matrix == nil || matrix.om == nil {
|
func (matrix *Matrix) All() iter.Seq2[string, []any] {
|
||||||
return nil
|
return matrix.om.Iterator()
|
||||||
}
|
}
|
||||||
for pair := matrix.om.Front(); pair != nil; pair = pair.Next() {
|
|
||||||
if err := f(pair.Key, pair.Value); err != nil {
|
// Keys returns an iterator that loops over all task keys.
|
||||||
return err
|
func (matrix *Matrix) Keys(sorter sort.Sorter) iter.Seq[string] {
|
||||||
|
return func(yield func(string) bool) {
|
||||||
|
for k := range matrix.All() {
|
||||||
|
if !yield(k) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Values returns an iterator that loops over all task values.
|
||||||
|
func (matrix *Matrix) Values(sorter sort.Sorter) iter.Seq[[]any] {
|
||||||
|
return func(yield func([]any) bool) {
|
||||||
|
for _, v := range matrix.All() {
|
||||||
|
if !yield(v) {
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (matrix *Matrix) DeepCopy() *Matrix {
|
func (matrix *Matrix) DeepCopy() *Matrix {
|
||||||
|
@ -2,6 +2,7 @@ package ast
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"iter"
|
||||||
"slices"
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@ -10,6 +11,7 @@ import (
|
|||||||
|
|
||||||
"github.com/go-task/task/v3/errors"
|
"github.com/go-task/task/v3/errors"
|
||||||
"github.com/go-task/task/v3/internal/filepathext"
|
"github.com/go-task/task/v3/internal/filepathext"
|
||||||
|
"github.com/go-task/task/v3/internal/sort"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Tasks represents a group of tasks
|
// Tasks represents a group of tasks
|
||||||
@ -53,38 +55,47 @@ func (tasks *Tasks) Set(key string, value *Task) bool {
|
|||||||
return tasks.om.Set(key, value)
|
return tasks.om.Set(key, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tasks *Tasks) Range(f func(k string, v *Task) error) error {
|
// All returns an iterator that loops over all task key-value pairs in the order
|
||||||
if tasks == nil || tasks.om == nil {
|
// specified by the sorter.
|
||||||
return nil
|
func (t *Tasks) All(sorter sort.Sorter) iter.Seq2[string, *Task] {
|
||||||
|
if t == nil || t.om == nil {
|
||||||
|
return func(yield func(string, *Task) bool) {}
|
||||||
}
|
}
|
||||||
for pair := tasks.om.Front(); pair != nil; pair = pair.Next() {
|
if sorter == nil {
|
||||||
if err := f(pair.Key, pair.Value); err != nil {
|
return t.om.Iterator()
|
||||||
return err
|
}
|
||||||
|
return func(yield func(string, *Task) bool) {
|
||||||
|
for _, key := range sorter(t.om.Keys(), nil) {
|
||||||
|
el := t.om.GetElement(key)
|
||||||
|
if !yield(el.Key, el.Value) {
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tasks *Tasks) Keys() []string {
|
// Keys returns an iterator that loops over all task keys in the order specified
|
||||||
if tasks == nil {
|
// by the sorter.
|
||||||
return nil
|
func (t *Tasks) Keys(sorter sort.Sorter) iter.Seq[string] {
|
||||||
|
return func(yield func(string) bool) {
|
||||||
|
for k := range t.All(sorter) {
|
||||||
|
if !yield(k) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
var keys []string
|
|
||||||
for pair := tasks.om.Front(); pair != nil; pair = pair.Next() {
|
|
||||||
keys = append(keys, pair.Key)
|
|
||||||
}
|
|
||||||
return keys
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tasks *Tasks) Values() []*Task {
|
// Values returns an iterator that loops over all task values in the order
|
||||||
if tasks == nil {
|
// specified by the sorter.
|
||||||
return nil
|
func (t *Tasks) Values(sorter sort.Sorter) iter.Seq[*Task] {
|
||||||
|
return func(yield func(*Task) bool) {
|
||||||
|
for _, v := range t.All(sorter) {
|
||||||
|
if !yield(v) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
var values []*Task
|
|
||||||
for pair := tasks.om.Front(); pair != nil; pair = pair.Next() {
|
|
||||||
values = append(values, pair.Value)
|
|
||||||
}
|
|
||||||
return values
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type MatchingTask struct {
|
type MatchingTask struct {
|
||||||
@ -104,20 +115,19 @@ func (t *Tasks) FindMatchingTasks(call *Call) []*MatchingTask {
|
|||||||
}
|
}
|
||||||
// Attempt a wildcard match
|
// Attempt a wildcard match
|
||||||
// For now, we can just nil check the task before each loop
|
// For now, we can just nil check the task before each loop
|
||||||
_ = t.Range(func(key string, value *Task) error {
|
for _, value := range t.All(nil) {
|
||||||
if match, wildcards := value.WildcardMatch(call.Task); match {
|
if match, wildcards := value.WildcardMatch(call.Task); match {
|
||||||
matchingTasks = append(matchingTasks, &MatchingTask{
|
matchingTasks = append(matchingTasks, &MatchingTask{
|
||||||
Task: value,
|
Task: value,
|
||||||
Wildcards: wildcards,
|
Wildcards: wildcards,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return nil
|
}
|
||||||
})
|
|
||||||
return matchingTasks
|
return matchingTasks
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t1 *Tasks) Merge(t2 *Tasks, include *Include, includedTaskfileVars *Vars) error {
|
func (t1 *Tasks) Merge(t2 *Tasks, include *Include, includedTaskfileVars *Vars) error {
|
||||||
err := t2.Range(func(name string, v *Task) error {
|
for name, v := range t2.All(nil) {
|
||||||
// We do a deep copy of the task struct here to ensure that no data can
|
// We do a deep copy of the task struct here to ensure that no data can
|
||||||
// be changed elsewhere once the taskfile is merged.
|
// be changed elsewhere once the taskfile is merged.
|
||||||
task := v.DeepCopy()
|
task := v.DeepCopy()
|
||||||
@ -177,9 +187,7 @@ func (t1 *Tasks) Merge(t2 *Tasks, include *Include, includedTaskfileVars *Vars)
|
|||||||
}
|
}
|
||||||
// Add the task to the merged taskfile
|
// Add the task to the merged taskfile
|
||||||
t1.Set(taskName, task)
|
t1.Set(taskName, task)
|
||||||
|
}
|
||||||
return nil
|
|
||||||
})
|
|
||||||
|
|
||||||
// If the included Taskfile has a default task, is not flattened and the
|
// If the included Taskfile has a default task, is not flattened and the
|
||||||
// parent namespace has no task with a matching name, we can add an alias so
|
// parent namespace has no task with a matching name, we can add an alias so
|
||||||
@ -197,7 +205,7 @@ func (t1 *Tasks) Merge(t2 *Tasks, include *Include, includedTaskfileVars *Vars)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return err
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Tasks) UnmarshalYAML(node *yaml.Node) error {
|
func (t *Tasks) UnmarshalYAML(node *yaml.Node) error {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package ast
|
package ast
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"iter"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/elliotchance/orderedmap/v2"
|
"github.com/elliotchance/orderedmap/v2"
|
||||||
@ -9,6 +10,7 @@ import (
|
|||||||
"github.com/go-task/task/v3/errors"
|
"github.com/go-task/task/v3/errors"
|
||||||
"github.com/go-task/task/v3/internal/deepcopy"
|
"github.com/go-task/task/v3/internal/deepcopy"
|
||||||
"github.com/go-task/task/v3/internal/experiments"
|
"github.com/go-task/task/v3/internal/experiments"
|
||||||
|
"github.com/go-task/task/v3/internal/sort"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Vars is a string[string] variables map.
|
// Vars is a string[string] variables map.
|
||||||
@ -52,32 +54,50 @@ func (vs *Vars) Set(key string, value Var) bool {
|
|||||||
return vs.om.Set(key, value)
|
return vs.om.Set(key, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (vs *Vars) Range(f func(k string, v Var) error) error {
|
// All returns an iterator that loops over all task key-value pairs.
|
||||||
|
func (vs *Vars) All() iter.Seq2[string, Var] {
|
||||||
if vs == nil || vs.om == nil {
|
if vs == nil || vs.om == nil {
|
||||||
return nil
|
return func(yield func(string, Var) bool) {}
|
||||||
}
|
}
|
||||||
for pair := vs.om.Front(); pair != nil; pair = pair.Next() {
|
return vs.om.Iterator()
|
||||||
if err := f(pair.Key, pair.Value); err != nil {
|
}
|
||||||
return err
|
|
||||||
|
// Keys returns an iterator that loops over all task keys.
|
||||||
|
func (vs *Vars) Keys(sorter sort.Sorter) iter.Seq[string] {
|
||||||
|
return func(yield func(string) bool) {
|
||||||
|
for k := range vs.All() {
|
||||||
|
if !yield(k) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Values returns an iterator that loops over all task values.
|
||||||
|
func (vs *Vars) Values(sorter sort.Sorter) iter.Seq[Var] {
|
||||||
|
return func(yield func(Var) bool) {
|
||||||
|
for _, v := range vs.All() {
|
||||||
|
if !yield(v) {
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToCacheMap converts Vars to a map containing only the static
|
// ToCacheMap converts Vars to a map containing only the static
|
||||||
// variables
|
// variables
|
||||||
func (vs *Vars) ToCacheMap() (m map[string]any) {
|
func (vs *Vars) ToCacheMap() (m map[string]any) {
|
||||||
m = make(map[string]any, vs.Len())
|
m = make(map[string]any, vs.Len())
|
||||||
for pair := vs.om.Front(); pair != nil; pair = pair.Next() {
|
for k, v := range vs.All() {
|
||||||
if pair.Value.Sh != "" {
|
if v.Sh != "" {
|
||||||
// Dynamic variable is not yet resolved; trigger
|
// Dynamic variable is not yet resolved; trigger
|
||||||
// <no value> to be used in templates.
|
// <no value> to be used in templates.
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if pair.Value.Live != nil {
|
if v.Live != nil {
|
||||||
m[pair.Key] = pair.Value.Live
|
m[k] = v.Live
|
||||||
} else {
|
} else {
|
||||||
m[pair.Key] = pair.Value.Value
|
m[k] = v.Value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
|
@ -97,7 +97,7 @@ func (r *Reader) include(node Node) error {
|
|||||||
var g errgroup.Group
|
var g errgroup.Group
|
||||||
|
|
||||||
// Loop over each included taskfile
|
// Loop over each included taskfile
|
||||||
_ = vertex.Taskfile.Includes.Range(func(namespace string, include *ast.Include) error {
|
for _, include := range vertex.Taskfile.Includes.All() {
|
||||||
vars := compiler.GetEnviron()
|
vars := compiler.GetEnviron()
|
||||||
vars.Merge(vertex.Taskfile.Vars, nil)
|
vars.Merge(vertex.Taskfile.Vars, nil)
|
||||||
// Start a goroutine to process each included Taskfile
|
// Start a goroutine to process each included Taskfile
|
||||||
@ -173,8 +173,7 @@ func (r *Reader) include(node Node) error {
|
|||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
})
|
})
|
||||||
return nil
|
}
|
||||||
})
|
|
||||||
|
|
||||||
// Wait for all the go routines to finish
|
// Wait for all the go routines to finish
|
||||||
return g.Wait()
|
return g.Wait()
|
||||||
@ -282,7 +281,7 @@ func (r *Reader) readNode(node Node) (*ast.Taskfile, error) {
|
|||||||
|
|
||||||
// Set the taskfile/task's locations
|
// Set the taskfile/task's locations
|
||||||
tf.Location = node.Location()
|
tf.Location = node.Location()
|
||||||
for _, task := range tf.Tasks.Values() {
|
for task := range tf.Tasks.Values(nil) {
|
||||||
// If the task is not defined, create a new one
|
// If the task is not defined, create a new one
|
||||||
if task == nil {
|
if task == nil {
|
||||||
task = &ast.Task{}
|
task = &ast.Task{}
|
||||||
|
17
variables.go
17
variables.go
@ -109,21 +109,17 @@ func (e *Executor) compiledTask(call *ast.Call, evaluateShVars bool) (*ast.Task,
|
|||||||
new.Env.Merge(templater.ReplaceVars(dotenvEnvs, cache), nil)
|
new.Env.Merge(templater.ReplaceVars(dotenvEnvs, cache), nil)
|
||||||
new.Env.Merge(templater.ReplaceVars(origTask.Env, cache), nil)
|
new.Env.Merge(templater.ReplaceVars(origTask.Env, cache), nil)
|
||||||
if evaluateShVars {
|
if evaluateShVars {
|
||||||
err = new.Env.Range(func(k string, v ast.Var) error {
|
for k, v := range new.Env.All() {
|
||||||
// If the variable is not dynamic, we can set it and return
|
// If the variable is not dynamic, we can set it and return
|
||||||
if v.Value != nil || v.Sh == "" {
|
if v.Value != nil || v.Sh == "" {
|
||||||
new.Env.Set(k, ast.Var{Value: v.Value})
|
new.Env.Set(k, ast.Var{Value: v.Value})
|
||||||
return nil
|
continue
|
||||||
}
|
}
|
||||||
static, err := e.Compiler.HandleDynamicVar(v, new.Dir)
|
static, err := e.Compiler.HandleDynamicVar(v, new.Dir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
new.Env.Set(k, ast.Var{Value: static})
|
new.Env.Set(k, ast.Var{Value: static})
|
||||||
return nil
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -300,7 +296,7 @@ func itemsFromFor(
|
|||||||
// If the variable is dynamic, then it hasn't been resolved yet
|
// If the variable is dynamic, then it hasn't been resolved yet
|
||||||
// and we can't use it as a list. This happens when fast compiling a task
|
// and we can't use it as a list. This happens when fast compiling a task
|
||||||
// for use in --list or --list-all etc.
|
// for use in --list or --list-all etc.
|
||||||
if ok && v.Sh == "" {
|
if ok && v.Value != nil && v.Sh == "" {
|
||||||
switch value := v.Value.(type) {
|
switch value := v.Value.(type) {
|
||||||
case string:
|
case string:
|
||||||
if f.Split != "" {
|
if f.Split != "" {
|
||||||
@ -337,7 +333,7 @@ func product(inputMap *ast.Matrix) []map[string]any {
|
|||||||
result := []map[string]any{{}}
|
result := []map[string]any{{}}
|
||||||
|
|
||||||
// Iterate over each slice in the slices
|
// Iterate over each slice in the slices
|
||||||
_ = inputMap.Range(func(key string, slice []any) error {
|
for key, slice := range inputMap.All() {
|
||||||
var newResult []map[string]any
|
var newResult []map[string]any
|
||||||
|
|
||||||
// For each combination in the current result
|
// For each combination in the current result
|
||||||
@ -357,8 +353,7 @@ func product(inputMap *ast.Matrix) []map[string]any {
|
|||||||
|
|
||||||
// Update result with the new combinations
|
// Update result with the new combinations
|
||||||
result = newResult
|
result = newResult
|
||||||
return nil
|
}
|
||||||
})
|
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user