mirror of
				https://github.com/go-task/task.git
				synced 2025-10-30 23:58:01 +02:00 
			
		
		
		
	Update minimum go version (#1758)
* feat: update minimum version to 1.22 * refactor: use int range iterator * refactor: loop variables * refactor: replace slicesext.FirstNonZero with cmp.Or * refactor: use slices.Concat instead of append * fix: unused param * fix: linting
This commit is contained in:
		
							
								
								
									
										4
									
								
								.github/workflows/lint.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.github/workflows/lint.yml
									
									
									
									
										vendored
									
									
								
							| @@ -13,7 +13,7 @@ jobs: | ||||
|     name: Lint | ||||
|     strategy: | ||||
|       matrix: | ||||
|         go-version: [1.21.x, 1.22.x] | ||||
|         go-version: [1.22.x, 1.23.x] | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - uses: actions/setup-go@v5 | ||||
| @@ -25,7 +25,7 @@ jobs: | ||||
|       - name: golangci-lint | ||||
|         uses: golangci/golangci-lint-action@v6 | ||||
|         with: | ||||
|           version: v1.55.2 | ||||
|           version: v1.60.1 | ||||
|  | ||||
|   lint-jsonschema: | ||||
|     runs-on: ubuntu-latest | ||||
|   | ||||
							
								
								
									
										2
									
								
								.github/workflows/release.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/release.yml
									
									
									
									
										vendored
									
									
								
							| @@ -15,7 +15,7 @@ jobs: | ||||
|       - name: Set up Go | ||||
|         uses: actions/setup-go@v5 | ||||
|         with: | ||||
|           go-version: 1.21.x | ||||
|           go-version: 1.22.x | ||||
|  | ||||
|       - name: Run GoReleaser | ||||
|         uses: goreleaser/goreleaser-action@v2 | ||||
|   | ||||
							
								
								
									
										2
									
								
								.github/workflows/test.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/test.yml
									
									
									
									
										vendored
									
									
								
							| @@ -13,7 +13,7 @@ jobs: | ||||
|     name: Test | ||||
|     strategy: | ||||
|       matrix: | ||||
|         go-version: [1.21.x, 1.22.x] | ||||
|         go-version: [1.22.x, 1.23.x] | ||||
|         platform: [ubuntu-latest, macos-latest, windows-latest] | ||||
|     runs-on: ${{matrix.platform}} | ||||
|     steps: | ||||
|   | ||||
							
								
								
									
										2
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								go.mod
									
									
									
									
									
								
							| @@ -1,6 +1,6 @@ | ||||
| module github.com/go-task/task/v3 | ||||
|  | ||||
| go 1.21.0 | ||||
| go 1.22.0 | ||||
|  | ||||
| require ( | ||||
| 	github.com/Ladicle/tabwriter v1.0.0 | ||||
|   | ||||
							
								
								
									
										4
									
								
								hash.go
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								hash.go
									
									
									
									
									
								
							| @@ -1,15 +1,15 @@ | ||||
| package task | ||||
|  | ||||
| import ( | ||||
| 	"cmp" | ||||
| 	"fmt" | ||||
|  | ||||
| 	"github.com/go-task/task/v3/internal/hash" | ||||
| 	"github.com/go-task/task/v3/internal/slicesext" | ||||
| 	"github.com/go-task/task/v3/taskfile/ast" | ||||
| ) | ||||
|  | ||||
| func (e *Executor) GetHash(t *ast.Task) (string, error) { | ||||
| 	r := slicesext.FirstNonZero(t.Run, e.Taskfile.Run) | ||||
| 	r := cmp.Or(t.Run, e.Taskfile.Run) | ||||
| 	var h hash.HashFunc | ||||
| 	switch r { | ||||
| 	case "always": | ||||
|   | ||||
							
								
								
									
										28
									
								
								help.go
									
									
									
									
									
								
							
							
						
						
									
										28
									
								
								help.go
									
									
									
									
									
								
							| @@ -160,23 +160,21 @@ func (e *Executor) ToEditorOutput(tasks []*ast.Task, noStatus bool) (*editors.Ta | ||||
| 	} | ||||
| 	var g errgroup.Group | ||||
| 	for i := range tasks { | ||||
| 		task := tasks[i] | ||||
| 		j := i | ||||
| 		aliases := []string{} | ||||
| 		if len(task.Aliases) > 0 { | ||||
| 			aliases = task.Aliases | ||||
| 		if len(tasks[i].Aliases) > 0 { | ||||
| 			aliases = tasks[i].Aliases | ||||
| 		} | ||||
| 		g.Go(func() error { | ||||
| 			o.Tasks[j] = editors.Task{ | ||||
| 				Name:     task.Name(), | ||||
| 				Desc:     task.Desc, | ||||
| 				Summary:  task.Summary, | ||||
| 			o.Tasks[i] = editors.Task{ | ||||
| 				Name:     tasks[i].Name(), | ||||
| 				Desc:     tasks[i].Desc, | ||||
| 				Summary:  tasks[i].Summary, | ||||
| 				Aliases:  aliases, | ||||
| 				UpToDate: false, | ||||
| 				Location: &editors.Location{ | ||||
| 					Line:     task.Location.Line, | ||||
| 					Column:   task.Location.Column, | ||||
| 					Taskfile: task.Location.Taskfile, | ||||
| 					Line:     tasks[i].Location.Line, | ||||
| 					Column:   tasks[i].Location.Column, | ||||
| 					Taskfile: tasks[i].Location.Taskfile, | ||||
| 				}, | ||||
| 			} | ||||
|  | ||||
| @@ -186,10 +184,10 @@ func (e *Executor) ToEditorOutput(tasks []*ast.Task, noStatus bool) (*editors.Ta | ||||
|  | ||||
| 			// Get the fingerprinting method to use | ||||
| 			method := e.Taskfile.Method | ||||
| 			if task.Method != "" { | ||||
| 				method = task.Method | ||||
| 			if tasks[i].Method != "" { | ||||
| 				method = tasks[i].Method | ||||
| 			} | ||||
| 			upToDate, err := fingerprint.IsTaskUpToDate(context.Background(), task, | ||||
| 			upToDate, err := fingerprint.IsTaskUpToDate(context.Background(), tasks[i], | ||||
| 				fingerprint.WithMethod(method), | ||||
| 				fingerprint.WithTempDir(e.TempDir.Fingerprint), | ||||
| 				fingerprint.WithDry(e.Dry), | ||||
| @@ -199,7 +197,7 @@ func (e *Executor) ToEditorOutput(tasks []*ast.Task, noStatus bool) (*editors.Ta | ||||
| 				return err | ||||
| 			} | ||||
|  | ||||
| 			o.Tasks[j].UpToDate = upToDate | ||||
| 			o.Tasks[i].UpToDate = upToDate | ||||
|  | ||||
| 			return nil | ||||
| 		}) | ||||
|   | ||||
| @@ -85,7 +85,7 @@ func TraverseStringsFunc[T any](v T, fn func(v string) (string, error)) (T, erro | ||||
|  | ||||
| 		case reflect.Struct: | ||||
| 			// Loop over each field and call traverseFunc recursively | ||||
| 			for i := 0; i < v.NumField(); i += 1 { | ||||
| 			for i := range v.NumField() { | ||||
| 				if err := traverseFunc(copy.Field(i), v.Field(i)); err != nil { | ||||
| 					return err | ||||
| 				} | ||||
| @@ -95,7 +95,7 @@ func TraverseStringsFunc[T any](v T, fn func(v string) (string, error)) (T, erro | ||||
| 			// Create an empty copy from the original value's type | ||||
| 			copy.Set(reflect.MakeSlice(v.Type(), v.Len(), v.Cap())) | ||||
| 			// Loop over each element and call traverseFunc recursively | ||||
| 			for i := 0; i < v.Len(); i += 1 { | ||||
| 			for i := range v.Len() { | ||||
| 				if err := traverseFunc(copy.Index(i), v.Index(i)); err != nil { | ||||
| 					return err | ||||
| 				} | ||||
|   | ||||
| @@ -89,7 +89,7 @@ func envColor(env string, defaultColor color.Attribute) []color.Attribute { | ||||
| 	// Otherwise, split by semicolons (ANSI color codes) and use them as is. | ||||
| 	attributeStrs := strings.Split(override, ",") | ||||
| 	if len(attributeStrs) == 3 { | ||||
| 		attributeStrs = append([]string{"38", "2"}, attributeStrs...) | ||||
| 		attributeStrs = slices.Concat([]string{"38", "2"}, attributeStrs) | ||||
| 	} else { | ||||
| 		attributeStrs = strings.Split(override, ";") | ||||
| 	} | ||||
|   | ||||
| @@ -18,13 +18,3 @@ func UniqueJoin[T cmp.Ordered](ss ...[]T) []T { | ||||
| 	slices.Sort(r) | ||||
| 	return slices.Compact(r) | ||||
| } | ||||
|  | ||||
| func FirstNonZero[T comparable](values ...T) T { | ||||
| 	var zero T | ||||
| 	for _, v := range values { | ||||
| 		if v != zero { | ||||
| 			return v | ||||
| 		} | ||||
| 	} | ||||
| 	return zero | ||||
| } | ||||
|   | ||||
| @@ -1,13 +1,11 @@ | ||||
| package task | ||||
|  | ||||
| import ( | ||||
| 	"context" | ||||
|  | ||||
| 	"github.com/go-task/task/v3/errors" | ||||
| 	"github.com/go-task/task/v3/taskfile/ast" | ||||
| ) | ||||
|  | ||||
| func (e *Executor) areTaskRequiredVarsSet(ctx context.Context, t *ast.Task, call *ast.Call) error { | ||||
| func (e *Executor) areTaskRequiredVarsSet(t *ast.Task, call *ast.Call) error { | ||||
| 	if t.Requires == nil || len(t.Requires.Vars) == 0 { | ||||
| 		return nil | ||||
| 	} | ||||
|   | ||||
							
								
								
									
										3
									
								
								setup.go
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								setup.go
									
									
									
									
									
								
							| @@ -5,6 +5,7 @@ import ( | ||||
| 	"fmt" | ||||
| 	"os" | ||||
| 	"path/filepath" | ||||
| 	"slices" | ||||
| 	"strings" | ||||
| 	"sync" | ||||
|  | ||||
| @@ -95,7 +96,7 @@ func (e *Executor) setupFuzzyModel() { | ||||
| 		words = append(words, taskName) | ||||
|  | ||||
| 		for _, task := range e.Taskfile.Tasks.Values() { | ||||
| 			words = append(words, task.Aliases...) | ||||
| 			words = slices.Concat(words, task.Aliases) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
|   | ||||
							
								
								
									
										15
									
								
								signals.go
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								signals.go
									
									
									
									
									
								
							| @@ -8,24 +8,25 @@ import ( | ||||
| 	"github.com/go-task/task/v3/internal/logger" | ||||
| ) | ||||
|  | ||||
| const interruptSignalsCount = 3 | ||||
|  | ||||
| // NOTE(@andreynering): This function intercepts SIGINT and SIGTERM signals | ||||
| // so the Task process is not killed immediately and processes running have | ||||
| // time to do cleanup work. | ||||
| func (e *Executor) InterceptInterruptSignals() { | ||||
| 	ch := make(chan os.Signal, 3) | ||||
| 	ch := make(chan os.Signal, interruptSignalsCount) | ||||
| 	signal.Notify(ch, os.Interrupt, syscall.SIGTERM) | ||||
|  | ||||
| 	go func() { | ||||
| 		for i := 1; i <= 3; i++ { | ||||
| 		for i := range interruptSignalsCount { | ||||
| 			sig := <-ch | ||||
|  | ||||
| 			if i < 3 { | ||||
| 				e.Logger.Outf(logger.Yellow, "task: Signal received: %q\n", sig) | ||||
| 				continue | ||||
| 			if i+1 >= interruptSignalsCount { | ||||
| 				e.Logger.Errf(logger.Red, "task: Signal received for the third time: %q. Forcing shutdown\n", sig) | ||||
| 				os.Exit(1) | ||||
| 			} | ||||
|  | ||||
| 			e.Logger.Errf(logger.Red, "task: Signal received for the third time: %q. Forcing shutdown\n", sig) | ||||
| 			os.Exit(1) | ||||
| 			e.Logger.Outf(logger.Yellow, "task: Signal received: %q\n", sig) | ||||
| 		} | ||||
| 	}() | ||||
| } | ||||
|   | ||||
| @@ -20,9 +20,7 @@ import ( | ||||
| 	"time" | ||||
| ) | ||||
|  | ||||
| var ( | ||||
| 	SLEEPIT, _ = filepath.Abs("./bin/sleepit") | ||||
| ) | ||||
| var SLEEPIT, _ = filepath.Abs("./bin/sleepit") | ||||
|  | ||||
| func TestSignalSentToProcessGroup(t *testing.T) { | ||||
| 	task, err := getTaskPath() | ||||
| @@ -147,7 +145,7 @@ func TestSignalSentToProcessGroup(t *testing.T) { | ||||
| 			// where the negative PID means the corresponding process group. Note that | ||||
| 			// this negative PID works only as long as the caller of the kill(2) system | ||||
| 			// call has a different PID, which is the case for this test. | ||||
| 			for i := 1; i <= tc.sendSigs; i++ { | ||||
| 			for range tc.sendSigs - 1 { | ||||
| 				if err := syscall.Kill(-sut.Process.Pid, syscall.SIGINT); err != nil { | ||||
| 					t.Fatalf("sending INT signal to the process group: %v", err) | ||||
| 				} | ||||
|   | ||||
							
								
								
									
										8
									
								
								task.go
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								task.go
									
									
									
									
									
								
							| @@ -200,7 +200,7 @@ func (e *Executor) RunTask(ctx context.Context, call *ast.Call) error { | ||||
| 				return err | ||||
| 			} | ||||
|  | ||||
| 			if err := e.areTaskRequiredVarsSet(ctx, t, call); err != nil { | ||||
| 			if err := e.areTaskRequiredVarsSet(t, call); err != nil { | ||||
| 				return err | ||||
| 			} | ||||
|  | ||||
| @@ -494,14 +494,12 @@ func (e *Executor) GetTaskList(filters ...FilterFunc) ([]*ast.Task, error) { | ||||
|  | ||||
| 	// Compile the list of tasks | ||||
| 	for i := range tasks { | ||||
| 		idx := i | ||||
| 		task := tasks[idx] | ||||
| 		g.Go(func() error { | ||||
| 			compiledTask, err := e.FastCompiledTask(&ast.Call{Task: task.Task}) | ||||
| 			compiledTask, err := e.FastCompiledTask(&ast.Call{Task: tasks[i].Task}) | ||||
| 			if err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 			tasks[idx] = compiledTask | ||||
| 			tasks[i] = compiledTask | ||||
| 			return nil | ||||
| 		}) | ||||
| 	} | ||||
|   | ||||
| @@ -825,7 +825,8 @@ func TestListDescInterpolation(t *testing.T) { | ||||
| 		t.Error(err) | ||||
| 	} | ||||
|  | ||||
| 	assert.Contains(t, buff.String(), "bar") | ||||
| 	assert.Contains(t, buff.String(), "foo-var") | ||||
| 	assert.Contains(t, buff.String(), "bar-var") | ||||
| } | ||||
|  | ||||
| func TestStatusVariables(t *testing.T) { | ||||
|   | ||||
| @@ -2,6 +2,7 @@ package ast | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"slices" | ||||
| 	"strings" | ||||
|  | ||||
| 	"gopkg.in/yaml.v3" | ||||
| @@ -111,7 +112,7 @@ func (t1 *Tasks) Merge(t2 Tasks, include *Include, includedTaskfileVars *Vars) { | ||||
| 	if t2.Get("default") != nil && t1.Get(include.Namespace) == nil { | ||||
| 		defaultTaskName := fmt.Sprintf("%s:default", include.Namespace) | ||||
| 		t1.Get(defaultTaskName).Aliases = append(t1.Get(defaultTaskName).Aliases, include.Namespace) | ||||
| 		t1.Get(defaultTaskName).Aliases = append(t1.Get(defaultTaskName).Aliases, include.Aliases...) | ||||
| 		t1.Get(defaultTaskName).Aliases = slices.Concat(t1.Get(defaultTaskName).Aliases, include.Aliases) | ||||
| 	} | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -1,8 +1,12 @@ | ||||
| version: '3' | ||||
|  | ||||
| vars: | ||||
|   FOO: bar | ||||
|   FOO: foo | ||||
|   BAR: bar | ||||
|  | ||||
| tasks: | ||||
|   foo: | ||||
|     desc: "task has desc with {{.FOO}} var" | ||||
|     desc: "task has desc with {{.FOO}}-var" | ||||
|  | ||||
|   bar: | ||||
|     desc: "task has desc with {{.BAR}}-var" | ||||
|   | ||||
| @@ -266,7 +266,7 @@ func itemsFromFor( | ||||
| 	var keys []string // The list of keys to loop over (only if looping over a map) | ||||
| 	var values []any  // The list of values to loop over | ||||
| 	// Get the list from the explicit for list | ||||
| 	if f.List != nil && len(f.List) > 0 { | ||||
| 	if len(f.List) > 0 { | ||||
| 		values = f.List | ||||
| 	} | ||||
| 	// Get the list from the task sources | ||||
|   | ||||
		Reference in New Issue
	
	Block a user