mirror of
https://github.com/go-task/task.git
synced 2026-08-29 01:58:56 +02:00
chore: bump minimum Go to 1.26 and adopt 1.26 features (#2920)
This commit is contained in:
2
.github/renovate.json
vendored
2
.github/renovate.json
vendored
@@ -10,7 +10,7 @@
|
||||
"osvVulnerabilityAlerts": true,
|
||||
"postUpdateOptions": ["gomodTidy"],
|
||||
"constraints": {
|
||||
"go": "1.25.10"
|
||||
"go": "1.26.4"
|
||||
},
|
||||
"customManagers": [
|
||||
{
|
||||
|
||||
6
.github/workflows/ci.yml
vendored
6
.github/workflows/ci.yml
vendored
@@ -21,7 +21,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
go-version: [1.25.x, 1.26.x]
|
||||
go-version: [1.26.x, 1.27.x]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: 📥 Checkout
|
||||
@@ -40,7 +40,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
go-version: [1.25.x, 1.26.x]
|
||||
go-version: [1.26.x, 1.27.x]
|
||||
platform: [ubuntu-latest, macos-latest, windows-latest]
|
||||
runs-on: ${{ matrix.platform }}
|
||||
steps:
|
||||
@@ -63,7 +63,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
go-version: [1.25.x, 1.26.x]
|
||||
go-version: [1.26.x, 1.27.x]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: 📥 Checkout
|
||||
|
||||
2
.github/workflows/release-nightly.yml
vendored
2
.github/workflows/release-nightly.yml
vendored
@@ -20,7 +20,7 @@ jobs:
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
|
||||
with:
|
||||
go-version: 1.26.x
|
||||
go-version: 1.27.x
|
||||
|
||||
- name: Run GoReleaser
|
||||
uses: goreleaser/goreleaser-action@f06c13b6b1a9625abc9e6e439d9c05a8f2190e94 # v7
|
||||
|
||||
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
@@ -21,7 +21,7 @@ jobs:
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
|
||||
with:
|
||||
go-version: 1.26.x
|
||||
go-version: 1.27.x
|
||||
|
||||
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
|
||||
with:
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
# Changelog
|
||||
|
||||
## Unreleased
|
||||
|
||||
### 📦 Package API
|
||||
|
||||
- Bumped the minimum Go version to 1.26. Task follows Go's two-latest support
|
||||
window, and is now tested against 1.26 and 1.27. This only affects projects
|
||||
importing Task as a Go module (#2920 by @vmaerten).
|
||||
|
||||
## v3.53.1 - 2026-08-18
|
||||
|
||||
### 🚀 Features
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
//go:build fsbench
|
||||
// +build fsbench
|
||||
|
||||
package task_test
|
||||
|
||||
|
||||
@@ -25,8 +25,7 @@ type (
|
||||
|
||||
func NewTaskfileDecodeError(err error, node *yaml.Node) *TaskfileDecodeError {
|
||||
// If the error is already a DecodeError, return it
|
||||
taskfileInvalidErr := &TaskfileDecodeError{}
|
||||
if errors.As(err, &taskfileInvalidErr) {
|
||||
if taskfileInvalidErr, ok := errors.AsType[*TaskfileDecodeError](err); ok {
|
||||
return taskfileInvalidErr
|
||||
}
|
||||
return &TaskfileDecodeError{
|
||||
@@ -45,8 +44,7 @@ func (err *TaskfileDecodeError) Error() string {
|
||||
fmt.Fprintln(buf, color.RedString("err: %s", err.Message))
|
||||
} else {
|
||||
// Extract the errors from the TypeError
|
||||
te := &yaml.TypeError{}
|
||||
if errors.As(err.Err, &te) {
|
||||
if te, ok := errors.AsType[*yaml.TypeError](err.Err); ok {
|
||||
if len(te.Errors) > 1 {
|
||||
fmt.Fprintln(buf, color.RedString("errs:"))
|
||||
for _, message := range te.Errors {
|
||||
|
||||
@@ -67,6 +67,13 @@ func As(err error, target any) bool {
|
||||
return errors.As(err, target)
|
||||
}
|
||||
|
||||
// AsType wraps the standard errors.AsType function so that we don't need to alias
|
||||
// that package. It returns the first error in err's tree that matches type T, and
|
||||
// whether such an error was found.
|
||||
func AsType[T error](err error) (T, bool) {
|
||||
return errors.AsType[T](err)
|
||||
}
|
||||
|
||||
// Unwrap wraps the standard errors.Unwrap function so that we don't need to alias that package.
|
||||
func Unwrap(err error) error {
|
||||
return errors.Unwrap(err)
|
||||
|
||||
@@ -48,12 +48,10 @@ func (err *TaskRunError) Code() int {
|
||||
}
|
||||
|
||||
func (err *TaskRunError) TaskExitCode() int {
|
||||
var exit interp.ExitStatus
|
||||
if errors.As(err.Err, &exit) {
|
||||
if exit, ok := errors.AsType[interp.ExitStatus](err.Err); ok {
|
||||
return int(exit)
|
||||
}
|
||||
var timeout *TaskTimeoutError
|
||||
if errors.As(err.Err, &timeout) {
|
||||
if _, ok := errors.AsType[*TaskTimeoutError](err.Err); ok {
|
||||
return TimeoutExitCode
|
||||
}
|
||||
return err.Code()
|
||||
|
||||
2
go.mod
2
go.mod
@@ -1,6 +1,6 @@
|
||||
module github.com/go-task/task/v3
|
||||
|
||||
go 1.25.10
|
||||
go 1.26.4
|
||||
|
||||
require (
|
||||
charm.land/bubbles/v2 v2.1.1
|
||||
|
||||
@@ -2,9 +2,11 @@ package fingerprint
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"cmp"
|
||||
"maps"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"slices"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
@@ -95,17 +97,14 @@ func filterGitignored(files map[string]bool, dir string) map[string]bool {
|
||||
|
||||
// Shallow dirs first (lower priority): the matcher scans patterns last to
|
||||
// first, so deeper rules win and can negate shallower ones.
|
||||
dirs := make([]string, 0, len(dirSet))
|
||||
for d := range dirSet {
|
||||
dirs = append(dirs, d)
|
||||
}
|
||||
sort.Slice(dirs, func(i, j int) bool {
|
||||
di := strings.Count(dirs[i], string(filepath.Separator))
|
||||
dj := strings.Count(dirs[j], string(filepath.Separator))
|
||||
if di != dj {
|
||||
return di < dj
|
||||
dirs := slices.Collect(maps.Keys(dirSet))
|
||||
slices.SortFunc(dirs, func(a, b string) int {
|
||||
da := strings.Count(a, string(filepath.Separator))
|
||||
db := strings.Count(b, string(filepath.Separator))
|
||||
if da != db {
|
||||
return cmp.Compare(da, db)
|
||||
}
|
||||
return dirs[i] < dirs[j]
|
||||
return cmp.Compare(a, b)
|
||||
})
|
||||
|
||||
var patterns []gitignore.Pattern
|
||||
|
||||
@@ -3,7 +3,7 @@ package fingerprint
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"slices"
|
||||
|
||||
"github.com/go-task/task/v3/internal/execext"
|
||||
"github.com/go-task/task/v3/internal/filepathext"
|
||||
@@ -65,6 +65,6 @@ func collectKeys(m map[string]bool) []string {
|
||||
keys = append(keys, filepath.ToSlash(k))
|
||||
}
|
||||
}
|
||||
sort.Strings(keys)
|
||||
slices.Sort(keys)
|
||||
return keys
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"io/fs"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"github.com/go-task/task/v3/errors"
|
||||
@@ -74,6 +74,6 @@ func FastRecursiveGlob(pattern string) ([]string, bool, error) {
|
||||
if err != nil {
|
||||
return nil, true, err
|
||||
}
|
||||
sort.Strings(results)
|
||||
slices.Sort(results)
|
||||
return results, true, nil
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package sort
|
||||
|
||||
import (
|
||||
"cmp"
|
||||
"slices"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@@ -29,16 +29,16 @@ func AlphaNumericWithRootTasksFirst(items []string, namespaces []string) []strin
|
||||
if len(namespaces) > 0 {
|
||||
return AlphaNumeric(items, namespaces)
|
||||
}
|
||||
sort.Slice(items, func(i, j int) bool {
|
||||
iContainsColon := strings.Contains(items[i], ":")
|
||||
jContainsColon := strings.Contains(items[j], ":")
|
||||
if iContainsColon == jContainsColon {
|
||||
return items[i] < items[j]
|
||||
slices.SortFunc(items, func(a, b string) int {
|
||||
aContainsColon := strings.Contains(a, ":")
|
||||
bContainsColon := strings.Contains(b, ":")
|
||||
if aContainsColon == bContainsColon {
|
||||
return cmp.Compare(a, b)
|
||||
}
|
||||
if !iContainsColon && jContainsColon {
|
||||
return true
|
||||
if !aContainsColon && bContainsColon {
|
||||
return -1
|
||||
}
|
||||
return false
|
||||
return 1
|
||||
})
|
||||
return items
|
||||
}
|
||||
|
||||
30
mise.lock
30
mise.lock
@@ -1,36 +1,36 @@
|
||||
# @generated - this file is auto-generated by `mise lock` https://mise.jdx.dev/dev-tools/mise-lock.html
|
||||
|
||||
[[tools.go]]
|
||||
version = "1.26.6"
|
||||
version = "1.27.0"
|
||||
backend = "core:go"
|
||||
|
||||
[tools.go."platforms.linux-arm64"]
|
||||
checksum = "sha256:d0507e9e9d7fe012aae570108cbd76c15de879e17130ab8cb90d4d7445cb1f2e"
|
||||
url = "https://dl.google.com/go/go1.26.6.linux-arm64.tar.gz"
|
||||
checksum = "sha256:51798d2c42d0e1c6ed7fd9f48728b4193abac9e8aad6dbac2fe96a81f5909bda"
|
||||
url = "https://dl.google.com/go/go1.27.0.linux-arm64.tar.gz"
|
||||
|
||||
[tools.go."platforms.linux-arm64-musl"]
|
||||
checksum = "sha256:d0507e9e9d7fe012aae570108cbd76c15de879e17130ab8cb90d4d7445cb1f2e"
|
||||
url = "https://dl.google.com/go/go1.26.6.linux-arm64.tar.gz"
|
||||
checksum = "sha256:51798d2c42d0e1c6ed7fd9f48728b4193abac9e8aad6dbac2fe96a81f5909bda"
|
||||
url = "https://dl.google.com/go/go1.27.0.linux-arm64.tar.gz"
|
||||
|
||||
[tools.go."platforms.linux-x64"]
|
||||
checksum = "sha256:708effb774be8237570d0add163225abbdfaf4fca28b2611df167beba4feef89"
|
||||
url = "https://dl.google.com/go/go1.26.6.linux-amd64.tar.gz"
|
||||
checksum = "sha256:675c26c449cbb18fc24b74650de1eabbae6e16f64326fd85a283fb3b58280685"
|
||||
url = "https://dl.google.com/go/go1.27.0.linux-amd64.tar.gz"
|
||||
|
||||
[tools.go."platforms.linux-x64-musl"]
|
||||
checksum = "sha256:708effb774be8237570d0add163225abbdfaf4fca28b2611df167beba4feef89"
|
||||
url = "https://dl.google.com/go/go1.26.6.linux-amd64.tar.gz"
|
||||
checksum = "sha256:675c26c449cbb18fc24b74650de1eabbae6e16f64326fd85a283fb3b58280685"
|
||||
url = "https://dl.google.com/go/go1.27.0.linux-amd64.tar.gz"
|
||||
|
||||
[tools.go."platforms.macos-arm64"]
|
||||
checksum = "sha256:2dc95ce4675829f2df0e86b28bcef3283635902062a5f0580ca659bf570f3204"
|
||||
url = "https://dl.google.com/go/go1.26.6.darwin-arm64.tar.gz"
|
||||
checksum = "sha256:90493b3bbd5e10f91d12153198bf1994fd756399b4fec93b49b0c6e2acdeeb3e"
|
||||
url = "https://dl.google.com/go/go1.27.0.darwin-arm64.tar.gz"
|
||||
|
||||
[tools.go."platforms.macos-x64"]
|
||||
checksum = "sha256:08b65a63f244115121ced6c3b55ad38d801a7442acad5c949a17aad84ae6d684"
|
||||
url = "https://dl.google.com/go/go1.26.6.darwin-amd64.tar.gz"
|
||||
checksum = "sha256:d3314e25496e4381d71a5c51d2907e7af655d199f6780b549f015bd85fef4986"
|
||||
url = "https://dl.google.com/go/go1.27.0.darwin-amd64.tar.gz"
|
||||
|
||||
[tools.go."platforms.windows-x64"]
|
||||
checksum = "sha256:5b6c5b556525810463b5c897b50dc7a82d6a3dc0bfaf55d990a7e9f31d6b2318"
|
||||
url = "https://dl.google.com/go/go1.26.6.windows-amd64.zip"
|
||||
checksum = "sha256:f0c0a0d33ba94f4d2c5dbc887334ce678b21813504ddb3aafcb06e60a5a667c4"
|
||||
url = "https://dl.google.com/go/go1.27.0.windows-amd64.zip"
|
||||
|
||||
[[tools."go:golang.org/x/exp/cmd/gorelease"]]
|
||||
version = "0.0.0-20260603202125-055de637280b"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[tools]
|
||||
# Runtimes
|
||||
go = "1.26.6"
|
||||
go = "1.27.0"
|
||||
node = "24"
|
||||
pnpm = "11.22.0"
|
||||
|
||||
|
||||
3
setup.go
3
setup.go
@@ -59,8 +59,7 @@ func (e *Executor) getRootNode() (taskfile.Node, error) {
|
||||
taskfile.WithCert(e.Cert),
|
||||
taskfile.WithCertKey(e.CertKey),
|
||||
)
|
||||
var taskNotFoundError errors.TaskfileNotFoundError
|
||||
if errors.As(err, &taskNotFoundError) {
|
||||
if taskNotFoundError, ok := errors.AsType[errors.TaskfileNotFoundError](err); ok {
|
||||
taskNotFoundError.AskInit = true
|
||||
return nil, taskNotFoundError
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
//go:build signals
|
||||
// +build signals
|
||||
|
||||
// This file contains tests for signal handling on Unix.
|
||||
// Based on code from https://github.com/marco-m/timeit
|
||||
@@ -154,9 +153,8 @@ func TestSignalSentToProcessGroup(t *testing.T) {
|
||||
|
||||
err := sut.Wait()
|
||||
|
||||
var wantErr *exec.ExitError
|
||||
const wantExitStatus = 201
|
||||
if errors.As(err, &wantErr) {
|
||||
if wantErr, ok := errors.AsType[*exec.ExitError](err); ok {
|
||||
if wantErr.ExitCode() != wantExitStatus {
|
||||
t.Errorf(
|
||||
"waiting for child process: got exit status %v; want %d\n"+
|
||||
@@ -166,7 +164,7 @@ func TestSignalSentToProcessGroup(t *testing.T) {
|
||||
}
|
||||
} else {
|
||||
t.Errorf("waiting for child process: got unexpected error type %v (%T); want (%T)",
|
||||
err, err, wantErr)
|
||||
err, err, (*exec.ExitError)(nil))
|
||||
}
|
||||
|
||||
gotLines := strings.SplitAfter(out.String(), "\n")
|
||||
|
||||
15
task.go
15
task.go
@@ -273,12 +273,9 @@ func (e *Executor) RunTask(ctx context.Context, call *Call) error {
|
||||
|
||||
e.Logger.VerboseErrf(logger.Red, "task: %q failed: %v\n", call.Task, err)
|
||||
|
||||
var exitCode interp.ExitStatus
|
||||
var timeout *errors.TaskTimeoutError
|
||||
switch {
|
||||
case errors.As(err, &exitCode):
|
||||
if exitCode, ok := errors.AsType[interp.ExitStatus](err); ok {
|
||||
deferredExitCode = uint8(exitCode)
|
||||
case errors.As(err, &timeout):
|
||||
} else if _, ok := errors.AsType[*errors.TaskTimeoutError](err); ok {
|
||||
deferredExitCode = errors.TimeoutExitCode
|
||||
}
|
||||
|
||||
@@ -461,9 +458,11 @@ func (e *Executor) runCommand(ctx context.Context, t *ast.Task, call *Call, i in
|
||||
// isCommandFailure reports whether the command failed on its own terms - a
|
||||
// non-zero exit status or its timeout - rather than Task failing to run it.
|
||||
func isCommandFailure(err error) bool {
|
||||
var exitCode interp.ExitStatus
|
||||
var timeout *errors.TaskTimeoutError
|
||||
return errors.As(err, &exitCode) || errors.As(err, &timeout)
|
||||
if _, ok := errors.AsType[interp.ExitStatus](err); ok {
|
||||
return true
|
||||
}
|
||||
_, ok := errors.AsType[*errors.TaskTimeoutError](err)
|
||||
return ok
|
||||
}
|
||||
|
||||
// timedOut reports whether ctx was cancelled by the given timeout rather than by
|
||||
|
||||
@@ -413,8 +413,7 @@ func (r *Reader) readNode(ctx context.Context, node Node) (*ast.Taskfile, error)
|
||||
var tf ast.Taskfile
|
||||
if err := yaml.Unmarshal(b, &tf); err != nil {
|
||||
// Decode the taskfile and add the file info the any errors
|
||||
taskfileDecodeErr := &errors.TaskfileDecodeError{}
|
||||
if errors.As(err, &taskfileDecodeErr) {
|
||||
if taskfileDecodeErr, ok := errors.AsType[*errors.TaskfileDecodeError](err); ok {
|
||||
snippet := NewSnippet(b,
|
||||
WithLine(taskfileDecodeErr.Line),
|
||||
WithColumn(taskfileDecodeErr.Column),
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
//go:build watch
|
||||
// +build watch
|
||||
|
||||
package task_test
|
||||
|
||||
|
||||
Reference in New Issue
Block a user