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