Compare commits

..

66 Commits

Author SHA1 Message Date
Andrey Nering
72e25a25fd v3.45.5 2025-11-11 17:13:39 -03:00
renovate[bot]
a496ee5fcb chore(deps): update all non-major dependencies (#2501)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-11 20:12:27 +00:00
Andrey Nering
ef4292c42f chore(changelog): add entry for #2506 2025-11-11 17:09:17 -03:00
Andrey Nering
dc315efc7f chore(deps): update mvdan.cc/sh/moreinterp with core utils fixes
* Fixes https://github.com/go-task/task/issues/2426
* Ref https://github.com/u-root/u-root/pull/3464
* Ref https://github.com/mvdan/sh/pull/1199
2025-11-11 17:09:17 -03:00
Andrey Nering
a3a3e7fb0b chore(changelog): add entry for #2434 2025-11-11 16:51:53 -03:00
Andrey Nering
ee99849b1d refactor: migrate to the official yaml package (#2434)
The old package is long archived, but the YAML org forked it and will
officially maintain it from now on.

* Old: https://github.com/go-yaml/yaml
* New: https://github.com/yaml/go-yaml
2025-11-11 19:49:37 +00:00
Andrey Nering
bf9dc3f662 chore(changelog): add entry for #2286 2025-11-11 16:43:15 -03:00
Graham Dennis
94f82cbc5a fix: make task failure errors include stack of running tasks (#2286)
Previously if a task was run as a dependency of another task,
the error message simply reported something like:

    exit status 1

It is desirable instead to name the root task and all child tasks in the tree
to the failing task.

After this PR, the error message will read:

    task: Failed to run task "root": task: Failed to run task "failing-task": exit status 1
2025-11-11 16:40:40 -03:00
Valentin Maerten
b14318ed3f chore: changelog for #2494 2025-11-11 20:40:32 +01:00
Valentin Maerten
17757c0c15 fix: better error when a Taskfile does not exist in include (#2494) 2025-11-11 20:37:24 +01:00
Andrey Nering
19f72b7eb0 chore(changelog): add entry for #2418 2025-11-11 15:51:33 -03:00
Timothy Rule
0052ad2309 fix: do not re-evaluate variables for defer: (#2418) 2025-11-11 15:50:01 -03:00
Andrey Nering
af1e755196 chore(changelog): add entry for #2350 2025-11-11 14:42:18 -03:00
Andrey Nering
43074c20f2 refactor: improve code of group output 2025-11-11 14:37:16 -03:00
Timothy Rule
39c86992bd fix: address concurrent group output causing flaky tests (#2350) 2025-11-11 14:36:32 -03:00
Kaj Kowalski
c71241bcbd docs: fix YAML syntax errors in schema and guide documentation (#2500) 2025-11-10 11:00:39 +01:00
renovate[bot]
7c2bb78540 chore(deps): update all non-major dependencies (#2492)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-07 21:21:21 -03:00
Andrey Nering
32e675895a chore(website): update umami domain 2025-11-07 17:48:28 -03:00
Tatsuya Kyushima
786813d95d docs: add fzf-make to "community integrations" (#2393) 2025-11-04 14:32:53 -03:00
Valentin Maerten
f7287c503a docs: dictionary operations example was wrong (#2490) 2025-11-02 19:17:13 +01:00
Valentin Maerten
413574e3ee chore: changelog for #1322, #2053 2025-11-02 17:25:35 +01:00
Valentin Maerten
4b39becf65 chore: changelog for #2460, #2461 2025-11-02 17:25:35 +01:00
Valentin Maerten
15b7e3c69a refactor: VeryFastCompile for Task list (#2053) 2025-11-02 17:25:07 +01:00
Libor Mořkovský
7c93ea8b44 docs: add reference to slim-sprig in the templating page (#2472) 2025-11-02 17:21:17 +01:00
Valentin Maerten
6a7cfa58f9 fix: return taskrc config even if there is an error (#2461) 2025-11-02 17:15:58 +01:00
renovate[bot]
74b93f6eef chore(deps): update all non-major dependencies (#2463)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-02 17:03:54 +01:00
Andrey Nering
88101613c8 docs: add magic.dev as a gold sponsor 2025-10-17 09:56:59 -03:00
Valentin Maerten
599591ad3c chore: changelog for #2437, #2438 2025-10-12 13:30:28 +02:00
Skip Baney
348158a5f6 fix: properly resolve remote entrypoints (#2438) 2025-10-12 13:29:57 +02:00
pancho horrillo
c3e410e95a docs: update Arch and Nix community links (#2454) 2025-10-10 22:33:52 +02:00
Aku Kotkavuo
42bcd5406a docs: link to the known bug with --watch (#2449) 2025-10-10 22:26:40 +02:00
renovate[bot]
ba23aca631 chore(deps): update module github.com/puzpuzpuz/xsync/v3 to v4 (#2168)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-10 22:22:16 +02:00
renovate[bot]
5ef245a4bd chore(deps): update all non-major dependencies (#2448)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-10 22:12:37 +02:00
renovate[bot]
036a60f517 chore(deps): update actions/github-script action to v8 (#2421)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-10 21:55:30 +02:00
renovate[bot]
9c969541a5 chore(deps): update actions/setup-python action to v6 (#2457)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-10 21:35:21 +02:00
renovate[bot]
a52b483dd0 chore(deps): update actions/setup-go action to v6 (#2456)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-10 21:32:17 +02:00
Pete Davison
4e84c6bb76 fix: links to static files 2025-09-23 22:34:43 +00:00
merusso
0f9baf62a1 docs: Update Remote Taskfiles default values (#2430)
* docs: Update Remote Taskfiles default values

This change updates the documentation for [Remote Taskfiles > Configuration](https://taskfile.dev/docs/experiments/remote-taskfiles#configuration) for `timeout` and `cache-expiry` to match the defaults in code.

* docs: Update `cache-expiry` default to 0s

* docs: Update executor.go comment

Fix doc comment to indicate that cache expiry default duration is 0.
2025-09-23 13:10:20 +01:00
renovate[bot]
979ad523ef chore(deps): update mvdan.cc/sh/moreinterp digest to 1714925 (#2435)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-22 09:30:52 -03:00
renovate[bot]
975c07688e chore(deps): update all non-major dependencies (#2436)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-22 09:30:29 -03:00
Andrey Nering
67a02255b5 docs(changelog): add entry for #2431 2025-09-21 16:12:06 -03:00
Andrey Nering
028ae1a660 fix: fix message shown when a taskfile was not found (#2431) 2025-09-21 16:10:06 -03:00
Andrey Nering
68b1d2783d lint: fix lint by passing context 2025-09-21 16:09:51 -03:00
Andrey Nering
12793c350d chore: delete unused file cmd/tmp/main.go 2025-09-21 16:09:51 -03:00
Andrey Nering
8716ab81be docs: remove ga 2025-09-17 18:39:09 -03:00
Andrey Nering
c2a4e4470b docs: update sprig links to our domain 2025-09-17 18:32:49 -03:00
Valentin Maerten
f5a8ec8a0c fix: changelog in website 2025-09-17 17:12:57 +02:00
Valentin Maerten
048d92709a v3.45.4 2025-09-17 17:05:20 +02:00
Valentin Maerten
8dc9637e7a chore: changelog for #2413, #2424, #2425 2025-09-16 19:36:19 +02:00
Valentin Maerten
700bf00107 fix: search for all taskrc work as expected (#2424) 2025-09-16 19:35:31 +02:00
Valentin Maerten
4836d42828 fix: cache expiry in Taskrc was not working (#2423) 2025-09-16 19:35:12 +02:00
Valentin Maerten
5762d5ef8e fix: autocomplete from subfolder works as expected in zsh shell (#2425) 2025-09-16 19:34:57 +02:00
Andrey Nering
9f2fe0da61 docs: github action is not community maintained anymore 2025-09-16 14:01:33 -03:00
renovate[bot]
d1a5771839 chore(deps): update all non-major dependencies (#2420)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-16 14:19:35 +00:00
renovate[bot]
7663abdcde chore(deps): update mvdan.cc/sh/moreinterp digest to b717ad5 (#2409)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-16 11:14:12 -03:00
Valentin Maerten
1e42e1f817 fix: changelog for website 2025-09-16 08:54:06 +02:00
Valentin Maerten
5f7ae5d32e fix: changelog for website 2025-09-16 08:39:03 +02:00
Pete Davison
17db402e4b v3.45.3 2025-09-15 12:59:29 +00:00
Valentin Maerten
f2242958a6 fix: pnpm install in the website's folder 2025-09-15 14:55:55 +02:00
Pete Davison
ea4b695b5a chore: move changelog items back to unreleased 2025-09-15 12:45:35 +00:00
Pete Davison
209c88c341 v3.45.2 2025-09-15 12:40:54 +00:00
Pete Davison
bd94f9f607 fix: set pnpm version 2025-09-15 12:40:12 +00:00
Pete Davison
9f6b78ec84 chore: move changelog items back to unreleased 2025-09-15 12:38:52 +00:00
Pete Davison
fbde227167 v3.45.1 2025-09-15 12:34:34 +00:00
Pete Davison
fc06e92a87 chore: move changelog items back to unreleased 2025-09-15 12:34:11 +00:00
Pete Davison
a0cab3f5ec fix: use go-task/setup-task instead of arduino/setup-task in CI 2025-09-15 12:30:35 +00:00
83 changed files with 1790 additions and 1366 deletions

View File

@@ -8,7 +8,7 @@ jobs:
issue-awaiting-response:
runs-on: ubuntu-latest
steps:
- uses: actions/github-script@v7
- uses: actions/github-script@v8
with:
github-token: ${{secrets.GH_PAT}}
script: |

View File

@@ -8,7 +8,7 @@ jobs:
issue-closed:
runs-on: ubuntu-latest
steps:
- uses: actions/github-script@v7
- uses: actions/github-script@v8
with:
github-token: ${{secrets.GH_PAT}}
script: |

View File

@@ -9,7 +9,7 @@ jobs:
if: github.event.label.name == format('status{0} proposed', ':')
runs-on: ubuntu-latest
steps:
- uses: actions/github-script@v7
- uses: actions/github-script@v8
with:
github-token: ${{secrets.GH_PAT}}
script: |
@@ -23,7 +23,7 @@ jobs:
if: github.event.label.name == format('status{0} draft', ':')
runs-on: ubuntu-latest
steps:
- uses: actions/github-script@v7
- uses: actions/github-script@v8
with:
github-token: ${{secrets.GH_PAT}}
script: |
@@ -37,7 +37,7 @@ jobs:
if: github.event.label.name == format('status{0} candidate', ':')
runs-on: ubuntu-latest
steps:
- uses: actions/github-script@v7
- uses: actions/github-script@v8
with:
github-token: ${{secrets.GH_PAT}}
script: |
@@ -51,7 +51,7 @@ jobs:
if: github.event.label.name == format('status{0} stable', ':')
runs-on: ubuntu-latest
steps:
- uses: actions/github-script@v7
- uses: actions/github-script@v8
with:
github-token: ${{secrets.GH_PAT}}
script: |
@@ -65,7 +65,7 @@ jobs:
if: github.event.label.name == format('status{0} released', ':')
runs-on: ubuntu-latest
steps:
- uses: actions/github-script@v7
- uses: actions/github-script@v8
with:
github-token: ${{secrets.GH_PAT}}
script: |
@@ -85,7 +85,7 @@ jobs:
if: github.event.label.name == format('status{0} abandoned', ':')
runs-on: ubuntu-latest
steps:
- uses: actions/github-script@v7
- uses: actions/github-script@v8
with:
github-token: ${{secrets.GH_PAT}}
script: |
@@ -105,7 +105,7 @@ jobs:
if: github.event.label.name == format('status{0} superseded', ':')
runs-on: ubuntu-latest
steps:
- uses: actions/github-script@v7
- uses: actions/github-script@v8
with:
github-token: ${{secrets.GH_PAT}}
script: |

View File

@@ -8,7 +8,7 @@ jobs:
issue-needs-triage:
runs-on: ubuntu-latest
steps:
- uses: actions/github-script@v7
- uses: actions/github-script@v8
with:
github-token: ${{secrets.GH_PAT}}
script: |

View File

@@ -16,7 +16,7 @@ jobs:
go-version: [1.24.x, 1.25.x]
runs-on: ubuntu-latest
steps:
- uses: actions/setup-go@v5
- uses: actions/setup-go@v6
with:
go-version: ${{matrix.go-version}}
@@ -30,9 +30,9 @@ jobs:
lint-jsonschema:
runs-on: ubuntu-latest
steps:
- uses: actions/setup-python@v5
- uses: actions/setup-python@v6
with:
python-version: 3.13
python-version: 3.14
- uses: actions/checkout@v5

View File

@@ -14,7 +14,7 @@ jobs:
fetch-depth: 0
- name: Set up Go
uses: actions/setup-go@v5
uses: actions/setup-go@v6
with:
go-version: 1.25.x

View File

@@ -15,7 +15,7 @@ jobs:
fetch-depth: 0
- name: Set up Go
uses: actions/setup-go@v5
uses: actions/setup-go@v6
with:
go-version: 1.25.x
@@ -23,16 +23,13 @@ jobs:
run: |
npm config set '//registry.npmjs.org/:_authToken'=${{ secrets.NPM_TOKEN }}
- name: Install Task
uses: arduino/setup-task@v2
uses: go-task/setup-task@v1
- name: Install pnpm
uses: pnpm/action-setup@v4
- name: Install Node.js
uses: actions/setup-node@v4
with:
node-version: '22.x'
cache: 'pnpm'
package_json_file: 'website/package.json'
run_install: 'true'
- name: Run GoReleaser
uses: goreleaser/goreleaser-action@v6

View File

@@ -18,7 +18,7 @@ jobs:
runs-on: ${{matrix.platform}}
steps:
- name: Set up Go ${{matrix.go-version}}
uses: actions/setup-go@v5
uses: actions/setup-go@v6
with:
go-version: ${{matrix.go-version}}
id: go

View File

@@ -1,15 +1,12 @@
{
"yaml.schemas": {
"./website/static/schema.json": [
"Taskfile.yml",
"tmp/**/*.yml"
"./website/src/public/schema.json": [
"Taskfile.yml",
"Taskfile.yaml",
"taskfile.yml",
"taskfile.yaml"
]
},
"search.exclude": {
"**/versioned_docs": true,
"**/versioned_sidesbars": true,
"**/i18n": true
},
"gopls": {
"formatting.local": "github.com/go-task"
},

View File

@@ -1,6 +1,41 @@
# Changelog
## v3.45.0 - 2025-09-15
## v3.45.5 - 2025-11-11
- Fixed bug that made a generic message, instead of an useful one, appear when a
Taskfile could not be found (#2431 by @andreynering).
- Fixed a bug that caused an error when including a Remote Git Taskfile (#2438
by @twelvelabs).
- Fixed issue where `.taskrc.yml` was not returned if reading it failed, and
corrected handling of remote entrypoint Taskfiles (#2460, #2461 by @vmaerten).
- Improved performance of `--list` and `--list-all` by introducing a faster
compilation method that skips source globbing and checksum updates (#1322,
#2053 by @vmaerten).
- Fixed a concurrency bug with `output: group`. This ensures that begin/end
parts won't be mixed up from different tasks (#1208, #2349, #2350 by
@trulede).
- Do not re-evaluate variables for `defer:` (#2244, #2418 by @trulede).
- Improve error message when a Taskfile is not found (#2441, #2494 by @vmaerten).
- Fixed generic error message `exit status 1` when a dependency task failed
(#2286 by @GrahamDennis).
- Fixed YAML library from the unmaintained `gopkg.in/yaml.v3` to the new fork
maintained by the official YAML org (#2171, #2434 by @andreynering).
- On Windows, the built-in version of the `rm` core utils contains a fix related
to the `-f` flag (#2426,
[u-root/u-root#3464](https://github.com/u-root/u-root/pull/3464),
[mvdan/sh#1199](https://github.com/mvdan/sh/pull/1199),
#2506 by @andreynering).
## v3.45.4 - 2025-09-17
- Fixed a bug where `cache-expiry` could not be defined in `.taskrc.yml` (#2423
by @vmaerten).
- Fixed a bug where `.taskrc.yml` files in parent folders were not read
correctly (#2424 by @vmaerten).
- Fixed a bug where autocomplete in subfolders did not work with zsh (#2425 by
@vmaerten).
## v3.45.3 - 2025-09-15
- Task now includes built-in core utilities to greatly improve compatibility on
Windows. This means that your commands that uses `cp`, `mv`, `mkdir` or any
@@ -31,8 +66,8 @@
- Enhanced support for tasks with wildcards: they are now logged correctly, and
wildcard parameters are fully considered during fingerprinting (#1808, #1795
by @vmaerten).
- Fixed panic when a variable was declared as an empty hash (`{}`) (#2416,
#2417 by @trulede).
- Fixed panic when a variable was declared as an empty hash (`{}`) (#2416, #2417
by @trulede).
#### Package API
@@ -49,6 +84,10 @@ more timely. We have already merged a couple of longstanding PRs in our
@pd93, @shrink, @trim21 and all the previous contributors to
[arduino/setup-task](https://github.com/arduino/setup-task/)).
## v3.45.0-v3.45.2 - 2025-09-15
Failed due to an issue with our release process.
## v3.44.1 - 2025-07-23
- Internal tasks will no longer be shown as suggestions since they cannot be

View File

@@ -19,7 +19,12 @@
<tr>
<td align="center" valign="middle">
<a target="_blank" href="https://devowl.io">
<img src="https://devowl.io/wp-content/uploads/meta/favicon.webp" height="100px" title="devowl.io" />
<img src="website/src/public/img/devowl.io.svg" height="100px" width="200px" title="devowl.io" />
</a>
</td>
<td align="center" valign="middle">
<a target="_blank" href="https://magic.dev/">
<img src="website/src/public/img/magic.png" height="100px" width="200px" title="Magic" />
</a>
</td>
</tr>

View File

@@ -1,38 +0,0 @@
package main
import (
"context"
"fmt"
"net/http"
"time"
)
func main() {
ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond)
defer cancel()
if err := run(ctx); err != nil {
fmt.Println(ctx.Err())
fmt.Println(err)
}
}
func run(ctx context.Context) error {
req, err := http.NewRequest("GET", "https://taskfile.dev/schema.json", nil)
if err != nil {
fmt.Println(1)
return err
}
resp, err := http.DefaultClient.Do(req.WithContext(ctx))
if err != nil {
if ctx.Err() != nil {
fmt.Println(2)
return err
}
fmt.Println(3)
return err
}
defer resp.Body.Close()
return nil
}

View File

@@ -16,21 +16,18 @@ function __task_list() {
if [[ -n "$taskfile" && -f "$taskfile" ]]; then
enabled=1
cmd+=(--taskfile "$taskfile")
else
for taskfile in {T,t}askfile{,.dist}.{yaml,yml}; do
if [[ -f "$taskfile" ]]; then
enabled=1
break
fi
done
fi
if output=$("${cmd[@]}" $_GO_TASK_COMPLETION_LIST_OPTION 2>/dev/null); then
enabled=1
fi
(( enabled )) || return 0
scripts=()
for item in "${(@)${(f)$("${cmd[@]}" $_GO_TASK_COMPLETION_LIST_OPTION)}[2,-1]#\* }"; do
for item in "${(@)${(f)output}[2,-1]#\* }"; do
task="${item%%:[[:space:]]*}"
desc="${item##[^[:space:]]##[[:space:]]##}"
scripts+=( "${task//:/\\:}:$desc" )

View File

@@ -5,15 +5,12 @@ import (
"cmp"
"errors"
"fmt"
"regexp"
"strings"
"github.com/fatih/color"
"gopkg.in/yaml.v3"
"go.yaml.in/yaml/v4"
)
var typeErrorRegex = regexp.MustCompile(`line \d+: (.*)`)
type (
TaskfileDecodeError struct {
Message string
@@ -53,10 +50,10 @@ func (err *TaskfileDecodeError) Error() string {
if len(te.Errors) > 1 {
fmt.Fprintln(buf, color.RedString("errs:"))
for _, message := range te.Errors {
fmt.Fprintln(buf, color.RedString("- %s", extractTypeErrorMessage(message)))
fmt.Fprintln(buf, color.RedString("- %s", message.Err.Error()))
}
} else {
fmt.Fprintln(buf, color.RedString("err: %s", extractTypeErrorMessage(te.Errors[0])))
fmt.Fprintln(buf, color.RedString("err: %s", te.Errors[0].Err.Error()))
}
} else {
// Otherwise print the error message normally
@@ -128,11 +125,3 @@ func (err *TaskfileDecodeError) WithFileInfo(location string, snippet string) *T
err.Snippet = snippet
return err
}
func extractTypeErrorMessage(message string) string {
matches := typeErrorRegex.FindStringSubmatch(message)
if len(matches) == 2 {
return matches[1]
}
return message
}

View File

@@ -54,6 +54,10 @@ func (err *TaskRunError) TaskExitCode() int {
return err.Code()
}
func (err *TaskRunError) Unwrap() error {
return err.Err
}
// TaskInternalError when the user attempts to invoke a task that is internal.
type TaskInternalError struct {
TaskName string

View File

@@ -11,14 +11,18 @@ import (
// TaskfileNotFoundError is returned when no appropriate Taskfile is found when
// searching the filesystem.
type TaskfileNotFoundError struct {
URI string
Walk bool
URI string
Walk bool
AskInit bool
}
func (err TaskfileNotFoundError) Error() string {
var walkText string
if err.Walk {
walkText = " (or any of the parent directories)"
walkText = " (or any of the parent directories)."
}
if err.AskInit {
walkText += " Run `task --init` to create a new Taskfile."
}
return fmt.Sprintf(`task: No Taskfile found at %q%s`, err.URI, walkText)
}

View File

@@ -240,7 +240,7 @@ func (o *timeoutOption) ApplyToExecutor(e *Executor) {
}
// WithCacheExpiryDuration sets the duration after which the cache is considered
// expired. By default, the cache is considered expired after 24 hours.
// expired. By default, the cache is 0 (disabled).
func WithCacheExpiryDuration(duration time.Duration) ExecutorOption {
return &cacheExpiryDurationOption{duration: duration}
}

View File

@@ -143,12 +143,12 @@ func (tt *ExecutorTest) run(t *testing.T) {
t.Helper()
f := func(t *testing.T) {
t.Helper()
var buf bytes.Buffer
var buffer SyncBuffer
opts := append(
tt.executorOpts,
task.WithStdout(&buf),
task.WithStderr(&buf),
task.WithStdout(&buffer),
task.WithStderr(&buffer),
)
// If the test has input, create a reader for it and add it to the
@@ -171,7 +171,7 @@ func (tt *ExecutorTest) run(t *testing.T) {
if err := e.Setup(); tt.wantSetupError {
require.Error(t, err)
tt.writeFixtureErrSetup(t, g, err)
tt.writeFixtureBuffer(t, g, buf)
tt.writeFixtureBuffer(t, g, buffer.buf)
return
} else {
require.NoError(t, err)
@@ -192,7 +192,7 @@ func (tt *ExecutorTest) run(t *testing.T) {
if err := e.Run(ctx, call); tt.wantRunError {
require.Error(t, err)
tt.writeFixtureErrRun(t, g, err)
tt.writeFixtureBuffer(t, g, buf)
tt.writeFixtureBuffer(t, g, buffer.buf)
return
} else {
require.NoError(t, err)
@@ -205,7 +205,7 @@ func (tt *ExecutorTest) run(t *testing.T) {
}
}
tt.writeFixtureBuffer(t, g, buf)
tt.writeFixtureBuffer(t, g, buffer.buf)
}
// Run the test (with a name if it has one)
@@ -665,6 +665,15 @@ func TestLabel(t *testing.T) {
),
WithTask("foo"),
)
NewExecutorTest(t,
WithName("label in error"),
WithExecutorOptions(
task.WithDir("testdata/label_error"),
),
WithTask("foo"),
WithRunError(),
)
}
func TestPromptInSummary(t *testing.T) {

View File

@@ -33,14 +33,12 @@ var xList []Experiment
func Parse(dir string) {
config, _ := taskrc.GetConfig(dir)
ParseWithConfig(dir, config)
}
func ParseWithConfig(dir string, config *ast.TaskRC) {
// Read any .env files
readDotEnv(dir)
// Initialize the experiments
GentleForce = New("GENTLE_FORCE", config, 1)
RemoteTaskfiles = New("REMOTE_TASKFILES", config, 1)

23
go.mod
View File

@@ -13,7 +13,7 @@ require (
github.com/fatih/color v1.18.0
github.com/fsnotify/fsnotify v1.9.0
github.com/go-git/go-billy/v5 v5.6.2
github.com/go-git/go-git/v5 v5.16.2
github.com/go-git/go-git/v5 v5.16.3
github.com/go-task/slim-sprig/v3 v3.0.0
github.com/go-task/template v0.2.0
github.com/google/uuid v1.6.0
@@ -21,14 +21,14 @@ require (
github.com/mitchellh/hashstructure/v2 v2.0.2
github.com/puzpuzpuz/xsync/v3 v3.5.1
github.com/sajari/fuzzy v1.0.0
github.com/sebdah/goldie/v2 v2.7.1
github.com/sebdah/goldie/v2 v2.8.0
github.com/spf13/pflag v1.0.10
github.com/stretchr/testify v1.11.1
github.com/zeebo/xxh3 v1.0.2
golang.org/x/sync v0.17.0
golang.org/x/term v0.35.0
gopkg.in/yaml.v3 v3.0.1
mvdan.cc/sh/moreinterp v0.0.0-20250807215248-5a1a658912aa
go.yaml.in/yaml/v4 v4.0.0-rc.3
golang.org/x/sync v0.18.0
golang.org/x/term v0.37.0
mvdan.cc/sh/moreinterp v0.0.0-20251109230715-65adef8e2c5b
mvdan.cc/sh/v3 v3.12.0
)
@@ -45,7 +45,7 @@ require (
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
github.com/kevinburke/ssh_config v1.2.0 // indirect
github.com/klauspost/compress v1.17.4 // indirect
github.com/klauspost/compress v1.18.0 // indirect
github.com/klauspost/cpuid/v2 v2.2.7 // indirect
github.com/klauspost/pgzip v1.2.6 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
@@ -56,11 +56,12 @@ require (
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect
github.com/skeema/knownhosts v1.3.1 // indirect
github.com/stretchr/objx v0.5.2 // indirect
github.com/u-root/u-root v0.14.1-0.20250807200646-5e7721023dc7 // indirect
github.com/u-root/u-root v0.15.1-0.20251014130006-62f7144b33da // indirect
github.com/u-root/uio v0.0.0-20240224005618-d2acac8f3701 // indirect
github.com/xanzy/ssh-agent v0.3.3 // indirect
golang.org/x/crypto v0.37.0 // indirect
golang.org/x/net v0.39.0 // indirect
golang.org/x/sys v0.36.0 // indirect
golang.org/x/crypto v0.39.0 // indirect
golang.org/x/net v0.41.0 // indirect
golang.org/x/sys v0.38.0 // indirect
gopkg.in/warnings.v0 v0.1.2 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

58
go.sum
View File

@@ -54,8 +54,8 @@ github.com/go-git/go-billy/v5 v5.6.2 h1:6Q86EsPXMa7c3YZ3aLAQsMA0VlWmy43r6FHqa/UN
github.com/go-git/go-billy/v5 v5.6.2/go.mod h1:rcFC2rAsp/erv7CMz9GczHcuD0D32fWzH+MJAU+jaUU=
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4=
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII=
github.com/go-git/go-git/v5 v5.16.2 h1:fT6ZIOjE5iEnkzKyxTHK1W4HGAsPhqEqiSAssSO77hM=
github.com/go-git/go-git/v5 v5.16.2/go.mod h1:4Ge4alE/5gPs30F2H1esi2gPd69R0C39lolkucHBOp8=
github.com/go-git/go-git/v5 v5.16.3 h1:Z8BtvxZ09bYm/yYNgPKCzgWtaRqDTgIKRgIRHBfU6Z8=
github.com/go-git/go-git/v5 v5.16.3/go.mod h1:4Ge4alE/5gPs30F2H1esi2gPd69R0C39lolkucHBOp8=
github.com/go-quicktest/qt v1.101.0 h1:O1K29Txy5P2OK0dGo59b7b0LR6wKfIhttaAhHUyn7eI=
github.com/go-quicktest/qt v1.101.0/go.mod h1:14Bz/f7NwaXPtdYEgzsx46kqSxVwTbzVZsDC26tQJow=
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
@@ -76,8 +76,8 @@ github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4=
github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
github.com/klauspost/compress v1.17.4 h1:Ej5ixsIri7BrIjBkRZLTo6ghwrEtHFk7ijlczPW4fZ4=
github.com/klauspost/compress v1.17.4/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM=
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM=
github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
github.com/klauspost/pgzip v1.2.6 h1:8RXeL5crjEUFnR2/Sn6GJNWtSQ3Dk8pq4CL3jvdDyjU=
@@ -113,16 +113,14 @@ github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0t
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
github.com/sajari/fuzzy v1.0.0 h1:+FmwVvJErsd0d0hAPlj4CxqxUtQY/fOoY0DwX4ykpRY=
github.com/sajari/fuzzy v1.0.0/go.mod h1:OjYR6KxoWOe9+dOlXeiCJd4dIbED4Oo8wpS89o0pwOo=
github.com/sebdah/goldie/v2 v2.7.1 h1:PkBHymaYdtvEkZV7TmyqKxdmn5/Vcj+8TpATWZjnG5E=
github.com/sebdah/goldie/v2 v2.7.1/go.mod h1:oZ9fp0+se1eapSRjfYbsV/0Hqhbuu3bJVvKI/NNtssI=
github.com/sebdah/goldie/v2 v2.8.0 h1:dZb9wR8q5++oplmEiJT+U/5KyotVD+HNGCAc5gNr8rc=
github.com/sebdah/goldie/v2 v2.8.0/go.mod h1:oZ9fp0+se1eapSRjfYbsV/0Hqhbuu3bJVvKI/NNtssI=
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8=
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4=
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/skeema/knownhosts v1.3.1 h1:X2osQ+RAjK76shCbvhHHHVl3ZlgDm8apHEHFqRjnBY8=
github.com/skeema/knownhosts v1.3.1/go.mod h1:r7KTdC8l4uxWRyK2TpQZ/1o5HaSzh06ePQNxPwTcfiY=
github.com/spf13/pflag v1.0.7 h1:vN6T9TfwStFPFM5XzjsvmzZkLuaLX+HS+0SeFLRgU6M=
github.com/spf13/pflag v1.0.7/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
@@ -131,12 +129,10 @@ github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.11.0 h1:ib4sjIrwZKxE5u/Japgo/7SJV3PvgjGiRNAvTVGqQl8=
github.com/stretchr/testify v1.11.0/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
github.com/u-root/u-root v0.14.1-0.20250807200646-5e7721023dc7 h1:ax+jBy7xFhh+Ka0IGLmH5mft+YDuqvzEjSgWuAP0nsM=
github.com/u-root/u-root v0.14.1-0.20250807200646-5e7721023dc7/go.mod h1:/0Qr7qJeDwWxoKku2xKQ4Szc+SwBE3g9VE8jNiamsmc=
github.com/u-root/u-root v0.15.1-0.20251014130006-62f7144b33da h1:Vst9Tvq3G6f6pYBvxy7coi2arDsnOZ3Mkj8MkNarSK8=
github.com/u-root/u-root v0.15.1-0.20251014130006-62f7144b33da/go.mod h1:R49zft13memK20EgFAvmTbXBS0t29UvglnM0BCA1ldQ=
github.com/u-root/uio v0.0.0-20240224005618-d2acac8f3701 h1:pyC9PaHYZFgEKFdlp3G8RaCKgVpHZnecvArXvPXcFkM=
github.com/u-root/uio v0.0.0-20240224005618-d2acac8f3701/go.mod h1:P3a5rG4X7tI17Nn3aOIAYr5HbIMukwXG0urG0WuL8OA=
github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=
@@ -145,18 +141,20 @@ github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ=
github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0=
github.com/zeebo/xxh3 v1.0.2 h1:xZmwmqxHZA8AI603jOQ0tMqmBr9lPeFwGg6d+xy9DC0=
github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA=
go.yaml.in/yaml/v4 v4.0.0-rc.3 h1:3h1fjsh1CTAPjW7q/EMe+C8shx5d8ctzZTrLcs/j8Go=
go.yaml.in/yaml/v4 v4.0.0-rc.3/go.mod h1:aZqd9kCMsGL7AuUv/m/PvWLdg5sjJsZ4oHDEnfPPfY0=
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE=
golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc=
golang.org/x/crypto v0.39.0 h1:SHs+kF4LP+f+p14esP5jAoDpHU8Gu/v9lFRK6IT5imM=
golang.org/x/crypto v0.39.0/go.mod h1:L+Xg3Wf6HoL4Bn4238Z6ft6KfEpN0tJGo53AAPC632U=
golang.org/x/exp v0.0.0-20250305212735-054e65f0b394 h1:nDVHiLt8aIbd/VzvPWN6kSOPE7+F/fNFDSXLVYkE/Iw=
golang.org/x/exp v0.0.0-20250305212735-054e65f0b394/go.mod h1:sIifuuw/Yco/y6yb6+bDNfyeQ/MdPUy/hKEMYQV17cM=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY=
golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E=
golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw=
golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/net v0.41.0 h1:vBTly1HeNPEn3wtREYfy4GZ/NECgw2Cnl+nK6Nz3uvw=
golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA=
golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug=
golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I=
golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -166,18 +164,18 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI=
golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k=
golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ=
golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.34.0 h1:O/2T7POpk0ZZ7MAzMeWFSg6S5IpWd/RXDlM9hgM3DR4=
golang.org/x/term v0.34.0/go.mod h1:5jC53AEywhIVebHgPVeg0mj8OD3VO9OzclacVrqpaAw=
golang.org/x/term v0.35.0 h1:bZBVKBudEyhRcajGcNc3jIfWPqV4y/Kt2XcoigOWtDQ=
golang.org/x/term v0.35.0/go.mod h1:TPGtkTLesOwf2DE8CgVYiZinHAOuy5AYUYT1lENIZnA=
golang.org/x/term v0.36.0 h1:zMPR+aF8gfksFprF/Nc/rd1wRS1EI6nDBGyWAvDzx2Q=
golang.org/x/term v0.36.0/go.mod h1:Qu394IJq6V6dCBRgwqshf3mPF85AqzYEzofzRdZkWss=
golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU=
golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0=
golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU=
golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M=
golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
@@ -189,7 +187,7 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
mvdan.cc/sh/moreinterp v0.0.0-20250807215248-5a1a658912aa h1:sRmA9AmA5+9CbK6a7N52q9W9jAeoBy1EJ7cncm+SLxw=
mvdan.cc/sh/moreinterp v0.0.0-20250807215248-5a1a658912aa/go.mod h1:Of9PCedbLDYT8b3EyiYG64rNnx5nOp27OLCVdDrjJyo=
mvdan.cc/sh/moreinterp v0.0.0-20251109230715-65adef8e2c5b h1:vTpx76nZDTP/BAGnnhEXYjM+8nPKe9+I86qCErBvjCw=
mvdan.cc/sh/moreinterp v0.0.0-20251109230715-65adef8e2c5b/go.mod h1:bDyKbUYKqkFunWmxxuSPrkYpln9QZcUsqu7W128qYW4=
mvdan.cc/sh/v3 v3.12.0 h1:ejKUR7ONP5bb+UGHGEG/k9V5+pRVIyD+LsZz7o8KHrI=
mvdan.cc/sh/v3 v3.12.0/go.mod h1:Se6Cj17eYSn+sNooLZiEUnNNmNxg0imoYlTu4CyaGyg=

View File

@@ -154,7 +154,7 @@ func init() {
pflag.BoolVar(&Offline, "offline", getConfig(config, func() *bool { return config.Remote.Offline }, false), "Forces Task to only use local or cached Taskfiles.")
pflag.DurationVar(&Timeout, "timeout", getConfig(config, func() *time.Duration { return config.Remote.Timeout }, time.Second*10), "Timeout for downloading remote Taskfiles.")
pflag.BoolVar(&ClearCache, "clear-cache", false, "Clear the remote cache.")
pflag.DurationVar(&CacheExpiryDuration, "expiry", getConfig(config, func() *time.Duration { return config.Remote.Timeout }, 0), "Expiry duration for cached remote Taskfiles.")
pflag.DurationVar(&CacheExpiryDuration, "expiry", getConfig(config, func() *time.Duration { return config.Remote.CacheExpiry }, 0), "Expiry duration for cached remote Taskfiles.")
}
pflag.Parse()
}

View File

@@ -24,7 +24,6 @@ func (g Group) WrapWriter(stdOut, _ io.Writer, _ string, cache *templater.Cache)
if g.ErrorOnly && err == nil {
return nil
}
return gw.close()
}
}
@@ -40,14 +39,22 @@ func (gw *groupWriter) Write(p []byte) (int, error) {
}
func (gw *groupWriter) close() error {
if gw.buff.Len() == 0 {
// don't print begin/end messages if there's no buffered entries
switch {
case gw.buff.Len() == 0:
return nil
}
if _, err := io.WriteString(gw.writer, gw.begin); err != nil {
case gw.begin == "" && gw.end == "":
_, err := io.Copy(gw.writer, &gw.buff)
return err
default:
_, err := io.Copy(gw.writer, gw.combinedBuff())
return err
}
gw.buff.WriteString(gw.end)
_, err := io.Copy(gw.writer, &gw.buff)
return err
}
func (gw *groupWriter) combinedBuff() io.Reader {
var b bytes.Buffer
_, _ = b.WriteString(gw.begin)
_, _ = io.Copy(&b, &gw.buff)
_, _ = b.WriteString(gw.end)
return &b
}

View File

@@ -9,7 +9,7 @@ import (
"github.com/davecgh/go-spew/spew"
"github.com/google/uuid"
"gopkg.in/yaml.v3"
"go.yaml.in/yaml/v4"
"mvdan.cc/sh/v3/shell"
"mvdan.cc/sh/v3/syntax"

View File

@@ -1 +1 @@
3.45.0
3.45.5

View File

@@ -16,6 +16,7 @@ import (
"github.com/go-task/task/v3/internal/env"
"github.com/go-task/task/v3/internal/execext"
"github.com/go-task/task/v3/internal/filepathext"
"github.com/go-task/task/v3/internal/fsext"
"github.com/go-task/task/v3/internal/logger"
"github.com/go-task/task/v3/internal/output"
"github.com/go-task/task/v3/internal/version"
@@ -56,6 +57,13 @@ func (e *Executor) Setup() error {
func (e *Executor) getRootNode() (taskfile.Node, error) {
node, err := taskfile.NewRootNode(e.Entrypoint, e.Dir, e.Insecure, e.Timeout)
if os.IsNotExist(err) {
return nil, errors.TaskfileNotFoundError{
URI: fsext.DefaultDir(e.Entrypoint, e.Dir),
Walk: true,
AskInit: true,
}
}
if err != nil {
return nil, err
}

26
task.go
View File

@@ -150,7 +150,7 @@ func (e *Executor) RunTask(ctx context.Context, call *Call) error {
release := e.acquireConcurrencyLimit()
defer release()
return e.startExecution(ctx, t, func(ctx context.Context) error {
if err = e.startExecution(ctx, t, func(ctx context.Context) error {
e.Logger.VerboseErrf(logger.Magenta, "task: %q started\n", call.Task)
if err := e.runDeps(ctx, t); err != nil {
return err
@@ -210,7 +210,7 @@ func (e *Executor) RunTask(ctx context.Context, call *Call) error {
for i := range t.Cmds {
if t.Cmds[i].Defer {
defer e.runDeferred(t, call, i, &deferredExitCode)
defer e.runDeferred(t, call, i, t.Vars, &deferredExitCode)
continue
}
@@ -228,16 +228,16 @@ func (e *Executor) RunTask(ctx context.Context, call *Call) error {
deferredExitCode = uint8(exitCode)
}
if call.Indirect {
return err
}
return &errors.TaskRunError{TaskName: t.Task, Err: err}
return err
}
}
e.Logger.VerboseErrf(logger.Magenta, "task: %q finished\n", call.Task)
return nil
})
}); err != nil {
return &errors.TaskRunError{TaskName: t.Name(), Err: err}
}
return nil
}
func (e *Executor) mkdir(t *ast.Task) error {
@@ -277,17 +277,11 @@ func (e *Executor) runDeps(ctx context.Context, t *ast.Task) error {
return g.Wait()
}
func (e *Executor) runDeferred(t *ast.Task, call *Call, i int, deferredExitCode *uint8) {
func (e *Executor) runDeferred(t *ast.Task, call *Call, i int, vars *ast.Vars, deferredExitCode *uint8) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
origTask, err := e.GetTask(call)
if err != nil {
return
}
cmd := t.Cmds[i]
vars, _ := e.Compiler.GetVariables(origTask, call)
cache := &templater.Cache{Vars: vars}
extra := map[string]any{}
@@ -498,7 +492,7 @@ func (e *Executor) GetTaskList(filters ...FilterFunc) ([]*ast.Task, error) {
// Compile the list of tasks
for i := range tasks {
g.Go(func() error {
compiledTask, err := e.FastCompiledTask(&Call{Task: tasks[i].Task})
compiledTask, err := e.CompiledTaskForTaskList(&Call{Task: tasks[i].Task})
if err != nil {
return err
}

View File

@@ -569,7 +569,9 @@ func TestCyclicDep(t *testing.T) {
task.WithStderr(io.Discard),
)
require.NoError(t, e.Setup())
assert.IsType(t, &errors.TaskCalledTooManyTimesError{}, e.Run(t.Context(), &task.Call{Task: "task-1"}))
err := e.Run(t.Context(), &task.Call{Task: "task-1"})
var taskCalledTooManyTimesError *errors.TaskCalledTooManyTimesError
assert.ErrorAs(t, err, &taskCalledTooManyTimesError)
}
func TestTaskVersion(t *testing.T) {
@@ -1052,7 +1054,7 @@ func TestIncludesOptionalImplicitFalse(t *testing.T) {
const dir = "testdata/includes_optional_implicit_false"
wd, _ := os.Getwd()
message := "stat %s/%s/TaskfileOptional.yml: no such file or directory"
message := "task: No Taskfile found at \"%s/%s/TaskfileOptional.yml\""
expected := fmt.Sprintf(message, wd, dir)
e := task.NewExecutor(
@@ -1072,7 +1074,7 @@ func TestIncludesOptionalExplicitFalse(t *testing.T) {
const dir = "testdata/includes_optional_explicit_false"
wd, _ := os.Getwd()
message := "stat %s/%s/TaskfileOptional.yml: no such file or directory"
message := "task: No Taskfile found at \"%s/%s/TaskfileOptional.yml\""
expected := fmt.Sprintf(message, wd, dir)
e := task.NewExecutor(

View File

@@ -1,7 +1,7 @@
package ast
import (
"gopkg.in/yaml.v3"
"go.yaml.in/yaml/v4"
"github.com/go-task/task/v3/errors"
"github.com/go-task/task/v3/internal/deepcopy"

View File

@@ -1,7 +1,7 @@
package ast
import (
"gopkg.in/yaml.v3"
"go.yaml.in/yaml/v4"
"github.com/go-task/task/v3/errors"
)

View File

@@ -1,7 +1,7 @@
package ast
import (
"gopkg.in/yaml.v3"
"go.yaml.in/yaml/v4"
"github.com/go-task/task/v3/errors"
)

View File

@@ -1,7 +1,7 @@
package ast
import (
"gopkg.in/yaml.v3"
"go.yaml.in/yaml/v4"
"github.com/go-task/task/v3/errors"
"github.com/go-task/task/v3/internal/deepcopy"

View File

@@ -1,7 +1,7 @@
package ast
import (
"gopkg.in/yaml.v3"
"go.yaml.in/yaml/v4"
"github.com/go-task/task/v3/errors"
)

View File

@@ -5,7 +5,7 @@ import (
"sync"
"github.com/elliotchance/orderedmap/v3"
"gopkg.in/yaml.v3"
"go.yaml.in/yaml/v4"
"github.com/go-task/task/v3/errors"
"github.com/go-task/task/v3/internal/deepcopy"

View File

@@ -4,7 +4,7 @@ import (
"iter"
"github.com/elliotchance/orderedmap/v3"
"gopkg.in/yaml.v3"
"go.yaml.in/yaml/v4"
"github.com/go-task/task/v3/errors"
"github.com/go-task/task/v3/internal/deepcopy"

View File

@@ -1,7 +1,7 @@
package ast
import (
"gopkg.in/yaml.v3"
"go.yaml.in/yaml/v4"
"github.com/go-task/task/v3/errors"
)

View File

@@ -4,7 +4,7 @@ import (
"fmt"
"strings"
"gopkg.in/yaml.v3"
"go.yaml.in/yaml/v4"
"github.com/go-task/task/v3/errors"
"github.com/go-task/task/v3/internal/goext"

View File

@@ -3,7 +3,7 @@ package ast
import (
"fmt"
"gopkg.in/yaml.v3"
"go.yaml.in/yaml/v4"
"github.com/go-task/task/v3/errors"
)

View File

@@ -5,7 +5,7 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"gopkg.in/yaml.v3"
"go.yaml.in/yaml/v4"
"github.com/go-task/task/v3/taskfile/ast"
)

View File

@@ -1,7 +1,7 @@
package ast
import (
"gopkg.in/yaml.v3"
"go.yaml.in/yaml/v4"
"github.com/go-task/task/v3/errors"
)

View File

@@ -1,7 +1,7 @@
package ast
import (
"gopkg.in/yaml.v3"
"go.yaml.in/yaml/v4"
"github.com/go-task/task/v3/errors"
"github.com/go-task/task/v3/internal/deepcopy"

View File

@@ -5,7 +5,7 @@ import (
"regexp"
"strings"
"gopkg.in/yaml.v3"
"go.yaml.in/yaml/v4"
"github.com/go-task/task/v3/errors"
"github.com/go-task/task/v3/internal/deepcopy"

View File

@@ -5,7 +5,7 @@ import (
"time"
"github.com/Masterminds/semver/v3"
"gopkg.in/yaml.v3"
"go.yaml.in/yaml/v4"
"github.com/go-task/task/v3/errors"
)

View File

@@ -5,7 +5,7 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"gopkg.in/yaml.v3"
"go.yaml.in/yaml/v4"
"github.com/go-task/task/v3/taskfile/ast"
)

View File

@@ -8,7 +8,7 @@ import (
"sync"
"github.com/elliotchance/orderedmap/v3"
"gopkg.in/yaml.v3"
"go.yaml.in/yaml/v4"
"github.com/go-task/task/v3/errors"
"github.com/go-task/task/v3/internal/filepathext"

View File

@@ -1,7 +1,7 @@
package ast
import (
"gopkg.in/yaml.v3"
"go.yaml.in/yaml/v4"
"github.com/go-task/task/v3/errors"
)

View File

@@ -5,7 +5,7 @@ import (
"sync"
"github.com/elliotchance/orderedmap/v3"
"gopkg.in/yaml.v3"
"go.yaml.in/yaml/v4"
"github.com/go-task/task/v3/errors"
"github.com/go-task/task/v3/internal/deepcopy"
@@ -113,7 +113,7 @@ func (vars *Vars) ToCacheMap() (m map[string]any) {
m[k] = v.Value
}
}
return
return m
}
// Merge loops over other and merges it values with the variables in vars. If

View File

@@ -72,6 +72,16 @@ func NewNode(
return node, err
}
func isRemoteEntrypoint(entrypoint string) bool {
scheme, _ := getScheme(entrypoint)
switch scheme {
case "git", "http", "https":
return true
default:
return false
}
}
func getScheme(uri string) (string, error) {
u, err := giturls.Parse(uri)
if u == nil {

View File

@@ -4,8 +4,8 @@ import (
"io"
"os"
"path/filepath"
"strings"
"github.com/go-task/task/v3/errors"
"github.com/go-task/task/v3/internal/execext"
"github.com/go-task/task/v3/internal/filepathext"
"github.com/go-task/task/v3/internal/fsext"
@@ -21,6 +21,9 @@ func NewFileNode(entrypoint, dir string, opts ...NodeOption) (*FileNode, error)
// Find the entrypoint file
resolvedEntrypoint, err := fsext.Search(entrypoint, dir, defaultTaskfiles)
if err != nil {
if errors.Is(err, os.ErrNotExist) {
return nil, errors.TaskfileNotFoundError{URI: entrypoint, Walk: false}
}
return nil, err
}
@@ -51,10 +54,7 @@ func (node *FileNode) Read() ([]byte, error) {
func (node *FileNode) ResolveEntrypoint(entrypoint string) (string, error) {
// If the file is remote, we don't need to resolve the path
if strings.Contains(entrypoint, "://") {
return entrypoint, nil
}
if strings.HasPrefix(entrypoint, "git") {
if isRemoteEntrypoint(entrypoint) {
return entrypoint, nil
}

View File

@@ -98,6 +98,11 @@ func (node *GitNode) ReadContext(_ context.Context) ([]byte, error) {
}
func (node *GitNode) ResolveEntrypoint(entrypoint string) (string, error) {
// If the file is remote, we don't need to resolve the path
if isRemoteEntrypoint(entrypoint) {
return entrypoint, nil
}
dir, _ := filepath.Split(node.path)
resolvedEntrypoint := fmt.Sprintf("%s//%s", node.url, filepath.Join(dir, entrypoint))
if node.ref != "" {

View File

@@ -21,6 +21,17 @@ func TestGitNode_ssh(t *testing.T) {
assert.Equal(t, "ssh://git@github.com/foo/bar.git//common.yml?ref=main", entrypoint)
}
func TestGitNode_sshWithAltRepo(t *testing.T) {
t.Parallel()
node, err := NewGitNode("git@github.com:foo/bar.git//Taskfile.yml?ref=main", "", false)
assert.NoError(t, err)
entrypoint, err := node.ResolveEntrypoint("git@github.com:foo/other.git//Taskfile.yml?ref=dev")
assert.NoError(t, err)
assert.Equal(t, "git@github.com:foo/other.git//Taskfile.yml?ref=dev", entrypoint)
}
func TestGitNode_sshWithDir(t *testing.T) {
t.Parallel()

View File

@@ -53,7 +53,7 @@ func (node *HTTPNode) ReadContext(ctx context.Context) ([]byte, error) {
if err != nil {
return nil, err
}
req, err := http.NewRequest("GET", url.String(), nil)
req, err := http.NewRequestWithContext(ctx, "GET", url.String(), nil)
if err != nil {
return nil, errors.TaskfileFetchFailedError{URI: node.Location()}
}

View File

@@ -4,7 +4,6 @@ import (
"bufio"
"fmt"
"os"
"strings"
"github.com/go-task/task/v3/internal/execext"
"github.com/go-task/task/v3/internal/filepathext"
@@ -43,7 +42,7 @@ func (node *StdinNode) Read() ([]byte, error) {
func (node *StdinNode) ResolveEntrypoint(entrypoint string) (string, error) {
// If the file is remote, we don't need to resolve the path
if strings.Contains(entrypoint, "://") {
if isRemoteEntrypoint(entrypoint) {
return entrypoint, nil
}

View File

@@ -8,8 +8,8 @@ import (
"time"
"github.com/dominikbraun/graph"
"go.yaml.in/yaml/v4"
"golang.org/x/sync/errgroup"
"gopkg.in/yaml.v3"
"github.com/go-task/task/v3/errors"
"github.com/go-task/task/v3/internal/env"

View File

@@ -3,7 +3,7 @@ package taskrc
import (
"os"
"gopkg.in/yaml.v3"
"go.yaml.in/yaml/v4"
"github.com/go-task/task/v3/taskrc/ast"
)

View File

@@ -57,9 +57,13 @@ func GetConfig(dir string) (*ast.TaskRC, error) {
}
// Find all the nodes from the given directory up to the users home directory
entrypoints, err := fsext.SearchAll("", dir, defaultTaskRCs)
absDir, err := filepath.Abs(dir)
if err != nil {
return nil, err
return config, err
}
entrypoints, err := fsext.SearchAll("", absDir, defaultTaskRCs)
if err != nil {
return config, err
}
// Reverse the entrypoints since we want the child files to override parent ones
@@ -84,6 +88,5 @@ func GetConfig(dir string) (*ast.TaskRC, error) {
}
config.Merge(localConfig)
}
return config, nil
}

7
testdata/label_error/Taskfile.yml vendored Normal file
View File

@@ -0,0 +1,7 @@
version: '3'
tasks:
foo:
label: "foobar"
cmds:
- "false"

View File

@@ -0,0 +1 @@
task: Failed to run task "foobar": exit status 1

View File

@@ -0,0 +1 @@
task: [foobar] false

View File

@@ -1 +1 @@
task: precondition not met
task: Failed to run task "impossible": task: precondition not met

View File

@@ -1 +1 @@
task: Failed to run task "executes_failing_task_as_cmd": task: precondition not met
task: Failed to run task "executes_failing_task_as_cmd": task: Failed to run task "impossible": task: precondition not met

View File

@@ -1 +1 @@
task: precondition not met
task: Failed to run task "depends_on_impossible": task: Failed to run task "impossible": task: precondition not met

View File

@@ -1 +1 @@
task: Task "foo" cancelled by user
task: Failed to run task "foo": task: Task "foo" cancelled by user

View File

@@ -1 +1 @@
task: Task "foo" cancelled by user
task: Failed to run task "foo": task: Task "foo" cancelled by user

View File

@@ -1 +1 @@
task: Task "foo" cancelled by user
task: Failed to run task "foo": task: Task "foo" cancelled by user

View File

@@ -1 +1 @@
task: Task "foo" cancelled by user
task: Failed to run task "foo": task: Task "foo" cancelled by user

View File

@@ -29,6 +29,51 @@ func (e *Executor) FastCompiledTask(call *Call) (*ast.Task, error) {
return e.compiledTask(call, false)
}
func (e *Executor) CompiledTaskForTaskList(call *Call) (*ast.Task, error) {
origTask, err := e.GetTask(call)
if err != nil {
return nil, err
}
vars, err := e.Compiler.FastGetVariables(origTask, call)
if err != nil {
return nil, err
}
cache := &templater.Cache{Vars: vars}
return &ast.Task{
Task: origTask.Task,
Label: templater.Replace(origTask.Label, cache),
Desc: templater.Replace(origTask.Desc, cache),
Prompt: templater.Replace(origTask.Prompt, cache),
Summary: templater.Replace(origTask.Summary, cache),
Aliases: origTask.Aliases,
Sources: origTask.Sources,
Generates: origTask.Generates,
Dir: origTask.Dir,
Set: origTask.Set,
Shopt: origTask.Shopt,
Vars: vars,
Env: nil,
Dotenv: origTask.Dotenv,
Silent: origTask.Silent,
Interactive: origTask.Interactive,
Internal: origTask.Internal,
Method: origTask.Method,
Prefix: origTask.Prefix,
IgnoreError: origTask.IgnoreError,
Run: origTask.Run,
IncludeVars: origTask.IncludeVars,
IncludedTaskfileVars: origTask.IncludedTaskfileVars,
Platforms: origTask.Platforms,
Location: origTask.Location,
Requires: origTask.Requires,
Watch: origTask.Watch,
Namespace: origTask.Namespace,
}, nil
}
func (e *Executor) compiledTask(call *Call, evaluateShVars bool) (*ast.Task, error) {
origTask, err := e.GetTask(call)
if err != nil {

View File

@@ -71,26 +71,11 @@ export default defineConfig({
'task runner, build tool, taskfile, yaml build tool, go task runner, make alternative, cross-platform build tool, makefile alternative, automation tool, ci cd pipeline, developer productivity, build automation, command line tool, go binary, yaml configuration'
}
],
[
'script',
{
async: '',
src: 'https://www.googletagmanager.com/gtag/js?id=G-4RT25NXQ7N'
}
],
[
'script',
{},
`window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag("js", new Date());
gtag("config", "G-4RT25NXQ7N");`
],
[
"script",
{
defer: "",
src: "https://umami.taskfile.dev/script.js",
src: "https://u.taskfile.dev/script.js",
"data-website-id": "084030b0-0e3f-4891-8d2a-0c12c40f5933"
}
]

View File

@@ -7,6 +7,11 @@ export const sponsors = [
name: 'devowl',
url: 'https://devowl.io/',
img: '/img/devowl.io.svg'
},
{
name: 'Magic',
url: 'https://magic.dev/',
img: '/img/magic.png'
}
]
}

View File

@@ -22,5 +22,5 @@
"vitepress-plugin-tabs": "^0.7.1",
"vue": "^3.5.18"
},
"packageManager": "pnpm@10.15.1+sha512.34e538c329b5553014ca8e8f4535997f96180a1d0f614339357449935350d924e22f8614682191264ec33d1462ac21561aff97f6bb18065351c162c7e8f6de67"
"packageManager": "pnpm@10.21.0+sha512.da3337267e400fdd3d479a6c68079ac6db01d8ca4f67572083e722775a796788a7a9956613749e000fac20d424b594f7a791a5f4e2e13581c5ef947f26968a40"
}

2428
website/pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -144,5 +144,5 @@ We're looking for feedback on a couple of different proposals, so please give
them a go and let us know what you think. :pray:
[v3.37.0]: https://github.com/go-task/task/releases/tag/v3.37.0
[slim-sprig-math]: https://go-task.github.io/slim-sprig/math.html
[slim-sprig-list]: https://go-task.github.io/slim-sprig/lists.html
[slim-sprig-math]: https://sprig.taskfile.dev/math.html
[slim-sprig-list]: https://sprig.taskfile.dev/lists.html

View File

@@ -5,7 +5,42 @@ outline: deep
# Changelog
## v3.45.0 - 2025-09-15
## v3.45.5 - 2025-11-11
- Fixed bug that made a generic message, instead of an useful one, appear when a
Taskfile could not be found (#2431 by @andreynering).
- Fixed a bug that caused an error when including a Remote Git Taskfile (#2438
by @twelvelabs).
- Fixed issue where `.taskrc.yml` was not returned if reading it failed, and
corrected handling of remote entrypoint Taskfiles (#2460, #2461 by @vmaerten).
- Improved performance of `--list` and `--list-all` by introducing a faster
compilation method that skips source globbing and checksum updates (#1322,
#2053 by @vmaerten).
- Fixed a concurrency bug with `output: group`. This ensures that begin/end
parts won't be mixed up from different tasks (#1208, #2349, #2350 by
@trulede).
- Do not re-evaluate variables for `defer:` (#2244, #2418 by @trulede).
- Improve error message when a Taskfile is not found (#2441, #2494 by @vmaerten).
- Fixed generic error message `exit status 1` when a dependency task failed
(#2286 by @GrahamDennis).
- Fixed YAML library from the unmaintained `gopkg.in/yaml.v3` to the new fork
maintained by the official YAML org (#2171, #2434 by @andreynering).
- On Windows, the built-in version of the `rm` core utils contains a fix related
to the `-f` flag (#2426,
[u-root/u-root#3464](https://github.com/u-root/u-root/pull/3464),
[mvdan/sh#1199](https://github.com/mvdan/sh/pull/1199),
#2506 by @andreynering).
## v3.45.4 - 2025-09-17
- Fixed a bug where `cache-expiry` could not be defined in `.taskrc.yml` (#2423
by @vmaerten).
- Fixed a bug where `.taskrc.yml` files in parent folders were not read
correctly (#2424 by @vmaerten).
- Fixed a bug where autocomplete in subfolders did not work with zsh (#2425 by
@vmaerten).
## v3.45.3 - 2025-09-15
- Task now includes built-in core utilities to greatly improve compatibility on
Windows. This means that your commands that uses `cp`, `mv`, `mkdir` or any
@@ -36,8 +71,8 @@ outline: deep
- Enhanced support for tasks with wildcards: they are now logged correctly, and
wildcard parameters are fully considered during fingerprinting (#1808, #1795
by @vmaerten).
- Fixed panic when a variable was declared as an empty hash (`{}`) (#2416,
#2417 by @trulede).
- Fixed panic when a variable was declared as an empty hash (`{}`) (#2416, #2417
by @trulede).
#### Package API
@@ -54,6 +89,10 @@ more timely. We have already merged a couple of longstanding PRs in our
@pd93, @shrink, @trim21 and all the previous contributors to
[arduino/setup-task](https://github.com/arduino/setup-task/)).
## v3.45.0-v3.45.2 - 2025-09-15
Failed due to an issue with our release process.
## v3.44.1 - 2025-07-23
- Internal tasks will no longer be shown as suggestions since they cannot be

View File

@@ -22,11 +22,11 @@ can view the full list of community integrations
Some installation methods are maintained by third party:
- [GitHub Actions](https://github.com/arduino/setup-task) by @arduino
- [AUR](https://aur.archlinux.org/packages/go-task-bin) by @carlsmedstad
- [Arch Linux](https://archlinux.org/packages/extra/x86_64/go-task/)
- [AUR](https://aur.archlinux.org/packages/go-task-git) by @C0rn3j
- [Scoop](https://github.com/ScoopInstaller/Main/blob/master/bucket/task.json)
- [Fedora](https://packages.fedoraproject.org/pkgs/golang-github-task/go-task/)
- [NixOS](https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/tools/go-task/default.nix)
- [Nix](https://github.com/NixOS/nixpkgs/blob/master/pkgs/by-name/go/go-task/package.nix)
- [Conda](https://github.com/conda-forge/go-task-feedstock/)
## More

View File

@@ -30,10 +30,10 @@ Studio Code][vscode-task].
you invest your time into a PR.
- **Experiments** - If there is no way to make your change backward compatible
then there is a procedure to introduce breaking changes into minor versions.
We call these "[experiments](./experiments/index.md)". If you're intending to work on
an experiment, then please read the
[experiments workflow](./experiments/index.md#workflow) document carefully and submit a
proposal first.
We call these "[experiments](./experiments/index.md)". If you're intending to
work on an experiment, then please read the
[experiments workflow](./experiments/index.md#workflow) document carefully and
submit a proposal first.
## 1. Setup
@@ -85,12 +85,12 @@ by using `task website` (requires `nodejs` & `pnpm`). All content is written in
Markdown and is located in the `website/src` directory. All Markdown documents
should have an 80 character line wrap limit (enforced by Prettier).
When making a change, consider whether a change to the [Usage Guide](/docs/guide) is
necessary. This document contains descriptions and examples of how to use Task
features. If you're adding a new feature, try to find an appropriate place to
add a new section. If you're updating an existing feature, ensure that the
documentation and any examples are up-to-date. Ensure that any examples follow
the [Taskfile Styleguide](./styleguide.md).
When making a change, consider whether a change to the
[Usage Guide](/docs/guide) is necessary. This document contains descriptions and
examples of how to use Task features. If you're adding a new feature, try to
find an appropriate place to add a new section. If you're updating an existing
feature, ensure that the documentation and any examples are up-to-date. Ensure
that any examples follow the [Taskfile Styleguide](./styleguide.md).
If you added a new command or flag, ensure that you add it to the
[CLI Reference](./reference/cli.md). New fields also need to be added to the
@@ -168,7 +168,7 @@ If you have questions, feel free to ask them in the `#help` forum channel on our
[pnpm]: https://pnpm.io/
[vitepress]: https://vitepress.dev
[json-schema]:
https://github.com/go-task/task/blob/main/website/static/schema.json
https://github.com/go-task/task/blob/main/website/src/public/schema.json
[task-open-issues]: https://github.com/go-task/task/issues
[vscode-task-open-issues]: https://github.com/go-task/vscode-task/issues
[good-first-issue]:

View File

@@ -39,15 +39,15 @@ of node which you can use:
::: code-group
```text [HTTP/HTTPS]
https://raw.githubusercontent.com/go-task/task/main/website/static/Taskfile.yml
https://raw.githubusercontent.com/go-task/task/main/website/src/public/Taskfile.yml
```
```text [Git over HTTP]
https://github.com/go-task/task.git//website/static/Taskfile.yml?ref=main
https://github.com/go-task/task.git//website/src/public/Taskfile.yml?ref=main
```
```text [Git over SSH]
git@github.com/go-task/task.git//website/static/Taskfile.yml?ref=main
git@github.com/go-task/task.git//website/src/public/Taskfile.yml?ref=main
```
:::
@@ -56,7 +56,7 @@ git@github.com/go-task/task.git//website/static/Taskfile.yml?ref=main
### HTTP/HTTPS
`https://raw.githubusercontent.com/go-task/task/main/website/static/Taskfile.yml`
`https://raw.githubusercontent.com/go-task/task/main/website/src/public/Taskfile.yml`
This is the most basic type of remote node and works by downloading the file
from the specified URL. The file must be a valid Taskfile and can be of any
@@ -66,7 +66,7 @@ find a valid Taskfile, an error is returned.
### Git over HTTP
`https://github.com/go-task/task.git//website/static/Taskfile.yml?ref=main`
`https://github.com/go-task/task.git//website/src/public/Taskfile.yml?ref=main`
This type of node works by downloading the file from a Git repository over
HTTP/HTTPS. The first part of the URL is the base URL of the Git repository.
@@ -80,7 +80,7 @@ This is the same URL that you would use to clone the repo over HTTP.
### Git over SSH
`git@github.com/go-task/task.git//website/static/Taskfile.yml?ref=main`
`git@github.com/go-task/task.git//website/src/public/Taskfile.yml?ref=main`
This type of node works by downloading the file from a Git repository over SSH.
The first part of the URL is the user and base URL of the Git repository. This
@@ -121,19 +121,19 @@ file. For example:
::: code-group
```shell [HTTP/HTTPS]
$ task --taskfile https://raw.githubusercontent.com/go-task/task/main/website/static/Taskfile.yml
$ task --taskfile https://raw.githubusercontent.com/go-task/task/main/website/src/public/Taskfile.yml
task: [hello] echo "Hello Task!"
Hello Task!
```
```shell [Git over HTTP]
$ task --taskfile https://github.com/go-task/task.git//website/static/Taskfile.yml?ref=main
$ task --taskfile https://github.com/go-task/task.git//website/src/public/Taskfile.yml?ref=main
task: [hello] echo "Hello Task!"
Hello Task!
```
```shell [Git over SSH]
$ task --taskfile git@github.com/go-task/task.git//website/static/Taskfile.yml?ref=main
$ task --taskfile git@github.com/go-task/task.git//website/src/public/Taskfile.yml?ref=main
task: [hello] echo "Hello Task!"
Hello Task!
```
@@ -152,21 +152,21 @@ the remote Taskfile will be available to run from your main Taskfile.
version: '3'
includes:
my-remote-namespace: https://raw.githubusercontent.com/go-task/task/main/website/static/Taskfile.yml
my-remote-namespace: https://raw.githubusercontent.com/go-task/task/main/website/src/public/Taskfile.yml
```
```yaml [Git over HTTP]
version: '3'
includes:
my-remote-namespace: https://github.com/go-task/task.git//website/static/Taskfile.yml?ref=main
my-remote-namespace: https://github.com/go-task/task.git//website/src/public/Taskfile.yml?ref=main
```
```yaml [Git over SSH]
version: '3'
includes:
my-remote-namespace: git@github.com/go-task/task.git//website/static/Taskfile.yml?ref=main
my-remote-namespace: git@github.com/go-task/task.git//website/src/public/Taskfile.yml?ref=main
```
:::
@@ -292,7 +292,9 @@ the `--download` flag.
You can use the `--clear-cache` flag to clear all cached remote files.
## Configuration
This experiment adds a new `remote` section to the [configuration file](../reference/config.md).
This experiment adds a new `remote` section to the
[configuration file](../reference/config.md).
- **Type**: `object`
- **Description**: Remote configuration settings for handling remote Taskfiles
@@ -330,7 +332,7 @@ remote:
#### `timeout`
- **Type**: `string`
- **Default**: Not specified
- **Default**: 10s
- **Pattern**: `^[0-9]+(ns|us|µs|ms|s|m|h)$`
- **Description**: Timeout duration for remote operations (e.g., '30s', '5m')
@@ -342,12 +344,12 @@ remote:
#### `cache-expiry`
- **Type**: `string`
- **Default**: Not specified
- **Default**: 0s (no cache)
- **Pattern**: `^[0-9]+(ns|us|µs|ms|s|m|h)$`
- **Description**: Cache expiry duration for remote Taskfiles (e.g., '1h', '24h')
- **Description**: Cache expiry duration for remote Taskfiles (e.g., '1h',
'24h')
```yaml
remote:
cache-expiry: "6h"
```

View File

@@ -406,10 +406,11 @@ option takes the list of tasks to be excluded from this include.
```yaml [Taskfile.yml]
version: '3'
includes:
included:
taskfile: ./Included.yml
excludes: [foo]
includes:
included:
taskfile: ./Included.yml
excludes: [foo]
```
```yaml [Included.yml]
@@ -467,7 +468,7 @@ includes:
Vars declared in the included Taskfile have preference over the variables in the
including Taskfile! If you want a variable in an included Taskfile to be
overridable, use the
[default function](https://go-task.github.io/slim-sprig/defaults.html):
[default function](https://sprig.taskfile.dev/defaults.html):
<span v-pre>`MY_VAR: '{{.MY_VAR | default "my-default-value"}}'`</span>.
:::
@@ -926,7 +927,7 @@ tasks:
- ./vendor/autoload.php
# But also run the task if the last build was not a production build.
status:
- grep -q '"dev": false' ./vendor/composer/installed.json
- grep -q '"dev"{{:}} false' ./vendor/composer/installed.json
```
### Using programmatic checks to cancel the execution of a task and its dependencies
@@ -2371,9 +2372,10 @@ if called by another task, either directly or as a dependency.
::: warning
The watcher can misbehave in certain scenarios, in particular for long-running
servers. There is a known bug where child processes of the running might not be
killed appropriately. It's advised to avoid running commands as `go run` and
prefer `go build [...] && ./binary` instead.
servers. There is a [known bug](https://github.com/go-task/task/issues/160)
where child processes of the running might not be killed appropriately. It's
advised to avoid running commands as `go run` and prefer `go build [...] &&
./binary` instead.
If you are having issues, you might want to try tools specifically designed for
live-reloading, like [Air](https://github.com/air-verse/air/). Also, be sure to

View File

@@ -191,7 +191,7 @@ dnf install go-task
pkg install task
```
### NixOS ([nix](https://nixos.org)) ![NixOS](https://img.shields.io/badge/NixOS-5277C3?logo=nixos&logoColor=fff) ![Linux](https://img.shields.io/badge/Linux-FCC624?logo=linux&logoColor=black) {#nix}
### [Nix](https://nixos.org) ![Nix](https://img.shields.io/badge/Nix-5277C3?logo=nixos&logoColor=fff) ![NixOS](https://img.shields.io/badge/NixOS-5277C3?logo=nixos&logoColor=fff) ![Linux](https://img.shields.io/badge/Linux-FCC624?logo=linux&logoColor=black) ![macOS](https://img.shields.io/badge/MacOS-000000?logo=apple&logoColor=F0F0F0) {#nix}
[[source](https://github.com/NixOS/nixpkgs/blob/master/pkgs/by-name/go/go-task/package.nix)]
@@ -291,14 +291,6 @@ examples and configuration.
uses: go-task/setup-task@v1
```
::: warning Community Maintained
These installation methods are maintained by the community and may not always be
up-to-date with the latest Task version. The Task team does not directly control
these packages.
:::
## Build From Source
### Go Modules

View File

@@ -35,7 +35,7 @@ To get autocompletion and validation for your Taskfile, see the
This was initially created by @KROSF in
[this Gist](https://gist.github.com/KROSF/c5435acf590acd632f71bb720f685895) and
is now officially maintained in
[this file](https://github.com/go-task/task/blob/main/website/static/schema.json)
[this file](https://github.com/go-task/task/blob/main/website/src/public/schema.json)
and made available at https://taskfile.dev/schema.json. This schema can be used
to validate Taskfiles and provide autocompletion in many code editors:
@@ -82,6 +82,8 @@ developers who have created their own integrations for Task:
[[source](https://github.com/lechuckroh/task-intellij-plugin)] by @lechuckroh
- [mk](https://github.com/pycontribs/mk) command line tool recognizes Taskfiles
natively.
- [fzf-make](https://github.com/kyu08/fzf-make) fuzzy finder with preview window
for make, pnpm, yarn, just & task.
If you have made something that integrates with Task, please feel free to open a
PR to add it to this list.

View File

@@ -99,7 +99,7 @@ vars:
# Variable references
BUILD_VERSION:
ref: VERSION
ref: .VERSION
# Map variables
CONFIG:
@@ -360,7 +360,7 @@ vars:
vars:
BASE_VERSION: 1.0.0
FULL_VERSION:
ref: BASE_VERSION
ref: .BASE_VERSION
```
### Map Variables (`map`)
@@ -513,12 +513,19 @@ tasks:
```yaml
tasks:
# Single prompt
deploy:
prompt: "Deploy to production?"
# or multiple prompts
cmds:
- ./deploy.sh
# Multiple prompts
deploy-multi:
prompt:
- "Are you sure?"
- "This will affect live users!"
cmds:
- ./deploy.sh
```
#### `aliases`
@@ -592,7 +599,7 @@ tasks:
# Simple precondition (shorthand)
build:
preconditions:
- test -f ./src
- test -d ./src
cmds:
- go build ./...
@@ -773,7 +780,7 @@ tasks:
matrix:
OS: [linux, windows, darwin]
ARCH: [amd64, arm64]
cmd: echo "Testing {{.OS}}/{{.ARCH}}"
cmd: echo "Testing {{.ITEM.OS}}/{{.ITEM.ARCH}}"
```
#### Loop in Dependencies

View File

@@ -11,7 +11,8 @@ outline: deep
Task's templating engine uses Go's
[text/template](https://pkg.go.dev/text/template) package to interpolate values.
This reference covers the main features and all available functions for creating
dynamic Taskfiles.
dynamic Taskfiles. Most of the provided functions come from the
[slim-sprig](https://sprig.taskfile.dev/) library.
## Basic Usage
@@ -627,9 +628,11 @@ tasks:
port: 5432
ssl: true
cmds:
- echo "Database {{.CONFIG | get "database"}}"
- echo "Database {{get .CONFIG "database"}}"
- echo "Database {{"database" | get .CONFIG}}"
- echo "Keys {{.CONFIG | keys}}"
- echo "Has SSL {{.CONFIG | hasKey "ssl"}}"
- echo "Keys {{keys .CONFIG }}"
- echo "Has SSL {{hasKey .CONFIG "ssl"}}"
- echo "{{dict "env" "prod" "debug" false}}"
```

View File

@@ -61,7 +61,7 @@ If you think its Task version is outdated, open an issue to let us know.
Nix is a community owned installation method. Nix package maintainers usually
take care of updating versions there by editing
[this file](https://github.com/NixOS/nixpkgs/blob/nixos-unstable/pkgs/by-name/go/go-task/package.nix).
[this file](https://github.com/NixOS/nixpkgs/blob/master/pkgs/by-name/go/go-task/package.nix).
If you think its Task version is outdated, open an issue to let us know.
[goreleaser]: https://goreleaser.com/

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB