mirror of
https://github.com/go-task/task.git
synced 2026-06-29 07:34:18 +00:00
Compare commits
11 Commits
git-ignore
...
renovate/a
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
937648e29c | ||
|
|
d0b903c772 | ||
|
|
1d9b3cb7db | ||
|
|
1a0f146888 | ||
|
|
b9b50ca79c | ||
|
|
3dcaa7db89 | ||
|
|
a72eb84c15 | ||
|
|
91b9e42f17 | ||
|
|
f1ab404fbb | ||
|
|
24a3ccdf42 | ||
|
|
b455286b63 |
4
.github/workflows/lint.yml
vendored
4
.github/workflows/lint.yml
vendored
@@ -23,7 +23,7 @@ jobs:
|
||||
with:
|
||||
go-version: ${{matrix.go-version}}
|
||||
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
|
||||
- name: golangci-lint
|
||||
uses: golangci/golangci-lint-action@82606bf257cbaff209d206a39f5134f0cfbfd2ee # v9.2.1
|
||||
@@ -37,7 +37,7 @@ jobs:
|
||||
with:
|
||||
python-version: 3.14
|
||||
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
|
||||
- name: install check-jsonschema
|
||||
run: python -m pip install 'check-jsonschema==0.27.3'
|
||||
|
||||
69
.github/workflows/pr-build.yml
vendored
69
.github/workflows/pr-build.yml
vendored
@@ -1,69 +0,0 @@
|
||||
name: PR Build
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [labeled, synchronize]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
build:
|
||||
if: contains(github.event.pull_request.labels.*.name, 'needs-build')
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
fetch-depth: 0
|
||||
- uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
|
||||
with:
|
||||
go-version: "1.26.x"
|
||||
cache: true
|
||||
- uses: goreleaser/goreleaser-action@5daf1e915a5f0af01ddbcd89a43b8061ff4f1a89 # v7
|
||||
with:
|
||||
version: "~> v2"
|
||||
args: release --snapshot --clean --config .goreleaser-pr.yml
|
||||
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||
with:
|
||||
name: task_linux_amd64
|
||||
path: dist/task_linux_amd64.tar.gz
|
||||
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||
with:
|
||||
name: task_linux_arm64
|
||||
path: dist/task_linux_arm64.tar.gz
|
||||
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||
with:
|
||||
name: task_darwin_amd64
|
||||
path: dist/task_darwin_amd64.tar.gz
|
||||
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||
with:
|
||||
name: task_darwin_arm64
|
||||
path: dist/task_darwin_arm64.tar.gz
|
||||
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||
with:
|
||||
name: task_windows_amd64
|
||||
path: dist/task_windows_amd64.zip
|
||||
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||
with:
|
||||
name: checksums
|
||||
path: dist/task_checksums.txt
|
||||
- uses: peter-evans/find-comment@b30e6a3c0ed37e7c023ccd3f1db5c6c0b0c23aad # v4.0.0
|
||||
id: find-comment
|
||||
with:
|
||||
token: ${{secrets.GITHUB_TOKEN}}
|
||||
issue-number: ${{ github.event.pull_request.number }}
|
||||
body-includes: "📦 Build artifacts ready!"
|
||||
- uses: peter-evans/create-or-update-comment@e8674b075228eee787fea43ef493e45ece1004c9 # v5.0.0
|
||||
with:
|
||||
token: ${{secrets.GITHUB_TOKEN}}
|
||||
comment-id: ${{ steps.find-comment.outputs.comment-id }}
|
||||
issue-number: ${{ github.event.pull_request.number }}
|
||||
body: |
|
||||
## 📦 Build artifacts ready!
|
||||
|
||||
Download binaries from [this workflow run](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}).
|
||||
|
||||
Available platforms: Linux, macOS, Windows (amd64, arm64)
|
||||
edit-mode: replace
|
||||
2
.github/workflows/release-nightly.yml
vendored
2
.github/workflows/release-nightly.yml
vendored
@@ -13,7 +13,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
|
||||
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
@@ -14,7 +14,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
|
||||
2
.github/workflows/test.yml
vendored
2
.github/workflows/test.yml
vendored
@@ -22,7 +22,7 @@ jobs:
|
||||
runs-on: ${{matrix.platform}}
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
|
||||
- name: Set up Go ${{matrix.go-version}}
|
||||
uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
# yaml-language-server: $schema=https://goreleaser.com/static/schema.json
|
||||
version: 2
|
||||
|
||||
builds:
|
||||
- binary: task
|
||||
main: ./cmd/task
|
||||
goos: [windows, darwin, linux]
|
||||
goarch: [amd64, arm64]
|
||||
env:
|
||||
- CGO_ENABLED=0
|
||||
mod_timestamp: '{{ .CommitTimestamp }}'
|
||||
flags:
|
||||
- -trimpath
|
||||
ldflags:
|
||||
- "-s -w"
|
||||
|
||||
archives:
|
||||
- name_template: '{{.Binary}}_{{.Os}}_{{.Arch}}'
|
||||
files:
|
||||
- README.md
|
||||
- LICENSE
|
||||
- completion/**/*
|
||||
format_overrides:
|
||||
- goos: windows
|
||||
formats: [zip]
|
||||
|
||||
snapshot:
|
||||
version_template: 'pr-{{ .ShortCommit }}'
|
||||
|
||||
checksum:
|
||||
name_template: 'task_checksums.txt'
|
||||
23
CHANGELOG.md
23
CHANGELOG.md
@@ -2,11 +2,20 @@
|
||||
|
||||
## Unreleased
|
||||
|
||||
- Fixed --interactive prompts for required vars sometimes appearing in a random
|
||||
order. Prompts now follow the order the vars are declared in the Taskfile.
|
||||
(#2871 by @caproven)
|
||||
- Fixed Fish completions not being picked up correctly by installing them to
|
||||
Fish's `vendor_completions.d` directory instead of `completions` (#2850, #2859
|
||||
by @Legimity).
|
||||
- PowerShell completions now work with aliases of the `task` command, not just
|
||||
the `task` binary itself (#2852 by @kojiishi).
|
||||
- Fixed task names containing certain characters (e.g. `\`, `_`, `^`) leaking
|
||||
into checksum/timestamp filenames, breaking `sources:`/`generates:`
|
||||
up-to-date detection (#2886 by @s3onghyun).
|
||||
- Fixed `for: matrix:` loops using `ref:` rows producing wrong values when the
|
||||
same task was run concurrently (e.g. by parallel `deps`) with different vars
|
||||
(#2890, #2894 by @amitmishra11).
|
||||
|
||||
## v3.51.1 - 2026-05-16
|
||||
|
||||
@@ -16,9 +25,9 @@
|
||||
cleaning `..` and `.` components (#2681, #2788 by @mateenanjum).
|
||||
- Added `joinEnv` function to join paths based on your oprating system: `;` for
|
||||
Windows and `:` elsewhere, and `joinUrl` to join URL paths. Also, added two
|
||||
new special variables: `FILE_PATH_SEPARATOR` which returns `\` on Windows
|
||||
and `/` elsewhere, and `PATH_LIST_SEPARATOR` which returns `;` on Windows and
|
||||
`:` elsewhere (#2406, #2408 by @solvingj).
|
||||
new special variables: `FILE_PATH_SEPARATOR` which returns `\` on Windows and
|
||||
`/` elsewhere, and `PATH_LIST_SEPARATOR` which returns `;` on Windows and `:`
|
||||
elsewhere (#2406, #2408 by @solvingj).
|
||||
- Update the shell interpreter with a regression fix (#2812, #2832 by
|
||||
@andreynering).
|
||||
- Fix potential panic with the shell interpreter (#2810 by @trulede).
|
||||
@@ -34,13 +43,13 @@
|
||||
- Fixed watch mode ignoring SIGHUP signal, causing the watcher to exit instead
|
||||
of restarting (#2764, #2642).
|
||||
- Fixed a long time bug where the task wouldn't re-run as it should when using
|
||||
`method: timestamp` and the files listed on `generates:` were deleted.
|
||||
This makes `method: timestamp` behaves the same as `method: checksum`
|
||||
(#1230, #2716 by @drichardson).
|
||||
`method: timestamp` and the files listed on `generates:` were deleted. This
|
||||
makes `method: timestamp` behaves the same as `method: checksum` (#1230, #2716
|
||||
by @drichardson).
|
||||
|
||||
## v3.49.1 - 2026-03-08
|
||||
|
||||
* Reverted #2632 for now, which caused some regressions. That change will be
|
||||
- Reverted #2632 for now, which caused some regressions. That change will be
|
||||
reworked (#2720, #2722, #2723).
|
||||
|
||||
## v3.49.0 - 2026-03-07
|
||||
|
||||
16
go.mod
16
go.mod
@@ -4,11 +4,11 @@ go 1.25.10
|
||||
|
||||
require (
|
||||
charm.land/bubbles/v2 v2.1.0
|
||||
charm.land/bubbletea/v2 v2.0.6
|
||||
charm.land/lipgloss/v2 v2.0.3
|
||||
charm.land/bubbletea/v2 v2.0.7
|
||||
charm.land/lipgloss/v2 v2.0.4
|
||||
github.com/Ladicle/tabwriter v1.0.0
|
||||
github.com/Masterminds/semver/v3 v3.5.0
|
||||
github.com/alecthomas/chroma/v2 v2.26.1
|
||||
github.com/alecthomas/chroma/v2 v2.27.0
|
||||
github.com/chainguard-dev/git-urls v1.0.2
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc
|
||||
github.com/dominikbraun/graph v0.23.0
|
||||
@@ -28,8 +28,8 @@ require (
|
||||
github.com/stretchr/testify v1.11.1
|
||||
github.com/zeebo/xxh3 v1.1.0
|
||||
go.yaml.in/yaml/v3 v3.0.4
|
||||
golang.org/x/sync v0.20.0
|
||||
golang.org/x/term v0.43.0
|
||||
golang.org/x/sync v0.21.0
|
||||
golang.org/x/term v0.44.0
|
||||
mvdan.cc/sh/moreinterp v0.0.0-20260120230322-19def062a997
|
||||
mvdan.cc/sh/v3 v3.13.2-0.20260510185049-f5c6e2779117
|
||||
)
|
||||
@@ -69,7 +69,7 @@ require (
|
||||
github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/charmbracelet/colorprofile v0.4.3 // indirect
|
||||
github.com/charmbracelet/ultraviolet v0.0.0-20260416155717-489999b90468 // indirect
|
||||
github.com/charmbracelet/ultraviolet v0.0.0-20260525132238-948f4557a654 // indirect
|
||||
github.com/charmbracelet/x/ansi v0.11.7 // indirect
|
||||
github.com/charmbracelet/x/term v0.2.2 // indirect
|
||||
github.com/charmbracelet/x/termios v0.1.1 // indirect
|
||||
@@ -77,7 +77,7 @@ require (
|
||||
github.com/clipperhouse/displaywidth v0.11.0 // indirect
|
||||
github.com/clipperhouse/uax29/v2 v2.7.0 // indirect
|
||||
github.com/cncf/xds/go v0.0.0-20251210132809-ee656c7534f5 // indirect
|
||||
github.com/dlclark/regexp2/v2 v2.1.1 // indirect
|
||||
github.com/dlclark/regexp2/v2 v2.2.1 // indirect
|
||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||
github.com/envoyproxy/go-control-plane/envoy v1.36.0 // indirect
|
||||
github.com/envoyproxy/protoc-gen-validate v1.3.0 // indirect
|
||||
@@ -123,7 +123,7 @@ require (
|
||||
golang.org/x/crypto v0.51.0 // indirect
|
||||
golang.org/x/net v0.55.0 // indirect
|
||||
golang.org/x/oauth2 v0.36.0 // indirect
|
||||
golang.org/x/sys v0.45.0 // indirect
|
||||
golang.org/x/sys v0.46.0 // indirect
|
||||
golang.org/x/text v0.37.0 // indirect
|
||||
golang.org/x/time v0.15.0 // indirect
|
||||
google.golang.org/api v0.271.0 // indirect
|
||||
|
||||
16
go.sum
16
go.sum
@@ -4,8 +4,12 @@ charm.land/bubbles/v2 v2.1.0 h1:YSnNh5cPYlYjPxRrzs5VEn3vwhtEn3jVGRBT3M7/I0g=
|
||||
charm.land/bubbles/v2 v2.1.0/go.mod h1:l97h4hym2hvWBVfmJDtrEHHCtkIKeTEb3TTJ4ZOB3wY=
|
||||
charm.land/bubbletea/v2 v2.0.6 h1:UHN/91OyuhaOFGSrBXQ/hMZD8IO1Uc4BvHlgHXL2WJo=
|
||||
charm.land/bubbletea/v2 v2.0.6/go.mod h1:MH/D8ZLlN3op37vQvijKuU29g3rqTp+aQapURFonF9g=
|
||||
charm.land/bubbletea/v2 v2.0.7 h1:7qw2tTAVar7m7klOPBYfTB0mniv/RuexsYwMRNxSeL0=
|
||||
charm.land/bubbletea/v2 v2.0.7/go.mod h1:DGW2q8gvzHnOpMpZTORs0aySVHCox5C+2Svk0fci1qs=
|
||||
charm.land/lipgloss/v2 v2.0.3 h1:yM2zJ4Cf5Y51b7RHIwioil4ApI/aypFXXVHSwlM6RzU=
|
||||
charm.land/lipgloss/v2 v2.0.3/go.mod h1:7myLU9iG/3xluAWzpY/fSxYYHCgoKTie7laxk6ATwXA=
|
||||
charm.land/lipgloss/v2 v2.0.4 h1:lcPeVtcp23SNra7lHy8iYE4UC2aIipVQ47sbGyyxR5Q=
|
||||
charm.land/lipgloss/v2 v2.0.4/go.mod h1:0653x8epbZSzdDfO/XPS1a/uYPOBeSsCssOpJOqDzik=
|
||||
cloud.google.com/go v0.123.0 h1:2NAUJwPR47q+E35uaJeYoNhuNEM9kM8SjgRgdeOJUSE=
|
||||
cloud.google.com/go v0.123.0/go.mod h1:xBoMV08QcqUGuPW65Qfm1o9Y4zKZBpGS+7bImXLTAZU=
|
||||
cloud.google.com/go/auth v0.18.2 h1:+Nbt5Ev0xEqxlNjd6c+yYUeosQ5TtEUaNcN/3FozlaM=
|
||||
@@ -42,6 +46,8 @@ github.com/alecthomas/assert/v2 v2.11.0 h1:2Q9r3ki8+JYXvGsDyBXwH3LcJ+WK5D0gc5E8v
|
||||
github.com/alecthomas/assert/v2 v2.11.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k=
|
||||
github.com/alecthomas/chroma/v2 v2.26.1 h1:2X21EdxGZNv5GF9mG5u+uzc02GCFyGxbcBm3Grd9A78=
|
||||
github.com/alecthomas/chroma/v2 v2.26.1/go.mod h1:lxhRRa9H4hPmRLOOdYga4zkQIQjq3dtrrdwQeCfu78Y=
|
||||
github.com/alecthomas/chroma/v2 v2.27.0 h1:FodwmyOBgJULFYmDqibcp9pvfDLWdtPRh9v/r5BXYZs=
|
||||
github.com/alecthomas/chroma/v2 v2.27.0/go.mod h1:NjJ3ciIgrqBNeIkWZ4e46nseoLDslxU1LmfCoL+wcY8=
|
||||
github.com/alecthomas/repr v0.5.2 h1:SU73FTI9D1P5UNtvseffFSGmdNci/O6RsqzeXJtP0Qs=
|
||||
github.com/alecthomas/repr v0.5.2/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=
|
||||
github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4=
|
||||
@@ -96,6 +102,8 @@ github.com/charmbracelet/colorprofile v0.4.3 h1:QPa1IWkYI+AOB+fE+mg/5/4HRMZcaXex
|
||||
github.com/charmbracelet/colorprofile v0.4.3/go.mod h1:/zT4BhpD5aGFpqQQqw7a+VtHCzu+zrQtt1zhMt9mR4Q=
|
||||
github.com/charmbracelet/ultraviolet v0.0.0-20260416155717-489999b90468 h1:Q9fO0y1Zo5KB/5Vu8JZoLGm1N3RzF9bNj3Ao3xoR+Ac=
|
||||
github.com/charmbracelet/ultraviolet v0.0.0-20260416155717-489999b90468/go.mod h1:bAAz7dh/FTYfC+oiHavL4mX1tOIBZ0ZwYjSi3qE6ivM=
|
||||
github.com/charmbracelet/ultraviolet v0.0.0-20260525132238-948f4557a654 h1:FpSYhY28ucg9ZRr+2wj67FAQ0Ey5yiK0072PmRDJNek=
|
||||
github.com/charmbracelet/ultraviolet v0.0.0-20260525132238-948f4557a654/go.mod h1:hFpumms29Smx3LStRfku8vcCTBe1Kq8aCXtHUJa3mjY=
|
||||
github.com/charmbracelet/x/ansi v0.11.7 h1:kzv1kJvjg2S3r9KHo8hDdHFQLEqn4RBCb39dAYC84jI=
|
||||
github.com/charmbracelet/x/ansi v0.11.7/go.mod h1:9qGpnAVYz+8ACONkZBUWPtL7lulP9No6p1epAihUZwQ=
|
||||
github.com/charmbracelet/x/exp/golden v0.0.0-20250806222409-83e3a29d542f h1:pk6gmGpCE7F3FcjaOEKYriCvpmIN4+6OS/RD0vm4uIA=
|
||||
@@ -120,6 +128,8 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dlclark/regexp2/v2 v2.1.1 h1:LCUGyd9Wf+r+VVOl8Ny38JTpWJcAsdVnCIuhhtthmKw=
|
||||
github.com/dlclark/regexp2/v2 v2.1.1/go.mod h1:avUrQvPaLz2DrFNHJF0taWAFFX2C1GMSSoeiqFjcBmU=
|
||||
github.com/dlclark/regexp2/v2 v2.2.1 h1:mf4KkFUj0gJuarK8P+LgiS+Lit7m9N1yAwEfPbee7R0=
|
||||
github.com/dlclark/regexp2/v2 v2.2.1/go.mod h1:avUrQvPaLz2DrFNHJF0taWAFFX2C1GMSSoeiqFjcBmU=
|
||||
github.com/dominikbraun/graph v0.23.0 h1:TdZB4pPqCLFxYhdyMFb1TBdFxp8XLcJfTTBQucVPgCo=
|
||||
github.com/dominikbraun/graph v0.23.0/go.mod h1:yOjYyogZLY1LSG9E33JWZJiq5k83Qy2C6POAuiViluc=
|
||||
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
|
||||
@@ -282,11 +292,17 @@ golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs=
|
||||
golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q=
|
||||
golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4=
|
||||
golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
|
||||
golang.org/x/sync v0.21.0 h1:HLII4xRRTtCRkxYp4HNFF0Js/Og6q2i++KXbg0gHCwM=
|
||||
golang.org/x/sync v0.21.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY=
|
||||
golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
|
||||
golang.org/x/sys v0.46.0 h1:noSf2Fq6F8DBgS+LysIkx7rIExoNHJsxOAtPp4rthXw=
|
||||
golang.org/x/sys v0.46.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
|
||||
golang.org/x/term v0.43.0 h1:S4RLU2sB31O/NCl+zFN9Aru9A/Cq2aqKpTZJ6B+DwT4=
|
||||
golang.org/x/term v0.43.0/go.mod h1:lrhlHNdQJHO+1qVYiHfFKVuVioJIheAc3fBSMFYEIsk=
|
||||
golang.org/x/term v0.44.0 h1:0rLvDRCtNj0gZkyIXhCyOb2OAzEhLVqc4B+hrsBhrmc=
|
||||
golang.org/x/term v0.44.0/go.mod h1:7ze4MdzUzLXpSAoFP1H0bOI9aXDqveSvatT5vKcFh2Y=
|
||||
golang.org/x/text v0.37.0 h1:Cqjiwd9eSg8e0QAkyCaQTNHFIIzWtidPahFWR83rTrc=
|
||||
golang.org/x/text v0.37.0/go.mod h1:a5sjxXGs9hsn/AJVwuElvCAo9v8QYLzvavO5z2PiM38=
|
||||
golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U=
|
||||
|
||||
@@ -119,7 +119,7 @@ func (checker *ChecksumChecker) checksumFilePath(t *ast.Task) string {
|
||||
return filepath.Join(checker.tempDir, "checksum", normalizeFilename(t.Name()))
|
||||
}
|
||||
|
||||
var checksumFilenameRegexp = regexp.MustCompile("[^A-z0-9]")
|
||||
var checksumFilenameRegexp = regexp.MustCompile("[^[:alnum:]]")
|
||||
|
||||
// replaces invalid characters on filenames with "-"
|
||||
func normalizeFilename(f string) string {
|
||||
|
||||
@@ -16,6 +16,10 @@ func TestNormalizeFilename(t *testing.T) {
|
||||
{"foo/bar/baz", "foo-bar-baz"},
|
||||
{"foo@bar/baz", "foo-bar-baz"},
|
||||
{"foo1bar2baz3", "foo1bar2baz3"},
|
||||
{"foo\\bar", "foo-bar"},
|
||||
{"foo_bar", "foo-bar"},
|
||||
{"foo[bar]baz", "foo-bar-baz"},
|
||||
{"foo^bar`baz", "foo-bar-baz"},
|
||||
}
|
||||
for _, test := range tests {
|
||||
assert.Equal(t, test.Out, normalizeFilename(test.In))
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
[tools]
|
||||
# Runtimes
|
||||
go = "1.25.10"
|
||||
go = "1.26.4"
|
||||
node = "24"
|
||||
pnpm = "11.5.0"
|
||||
pnpm = "11.8.0"
|
||||
|
||||
# Dev tools
|
||||
golangci-lint = "2.12.2"
|
||||
mockery = "3.2.2"
|
||||
mockery = "3.7.1"
|
||||
gotestsum = "latest"
|
||||
goreleaser = "2"
|
||||
"go:golang.org/x/exp/cmd/gorelease" = "latest"
|
||||
|
||||
12
requires.go
12
requires.go
@@ -3,6 +3,8 @@ package task
|
||||
import (
|
||||
"slices"
|
||||
|
||||
"github.com/elliotchance/orderedmap/v3"
|
||||
|
||||
"github.com/go-task/task/v3/errors"
|
||||
"github.com/go-task/task/v3/internal/input"
|
||||
"github.com/go-task/task/v3/internal/term"
|
||||
@@ -32,7 +34,7 @@ func (e *Executor) promptDepsVars(calls []*Call) error {
|
||||
|
||||
// Collect all missing vars from the dependency tree
|
||||
visited := make(map[string]bool)
|
||||
varsMap := make(map[string]*ast.VarsWithValidation)
|
||||
varsMap := orderedmap.NewOrderedMap[string, *ast.VarsWithValidation]()
|
||||
|
||||
var collect func(call *Call) error
|
||||
collect = func(call *Call) error {
|
||||
@@ -42,8 +44,8 @@ func (e *Executor) promptDepsVars(calls []*Call) error {
|
||||
}
|
||||
|
||||
for _, v := range getMissingRequiredVars(compiledTask) {
|
||||
if _, exists := varsMap[v.Name]; !exists {
|
||||
varsMap[v.Name] = v
|
||||
if !varsMap.Has(v.Name) {
|
||||
varsMap.Set(v.Name, v)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,14 +75,14 @@ func (e *Executor) promptDepsVars(calls []*Call) error {
|
||||
}
|
||||
}
|
||||
|
||||
if len(varsMap) == 0 {
|
||||
if varsMap.Len() == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
prompter := e.newPrompter()
|
||||
e.promptedVars = ast.NewVars()
|
||||
|
||||
for _, v := range varsMap {
|
||||
for v := range varsMap.Values() {
|
||||
value, err := prompter.Prompt(v.Name, getEnumValues(v.Enum))
|
||||
if err != nil {
|
||||
if errors.Is(err, input.ErrCancelled) {
|
||||
|
||||
@@ -93,6 +93,21 @@ func (matrix *Matrix) DeepCopy() *Matrix {
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy returns a copy of the MatrixRow. Without this, deepcopy.OrderedMap
|
||||
// falls back to copying the *MatrixRow pointer as-is, so every "copy" of a
|
||||
// Matrix would still share the same underlying rows - see #2890, where
|
||||
// concurrent invocations of a task with a `ref:` matrix row raced on
|
||||
// resolveMatrixRefs mutating that shared row.
|
||||
func (row *MatrixRow) DeepCopy() *MatrixRow {
|
||||
if row == nil {
|
||||
return nil
|
||||
}
|
||||
return &MatrixRow{
|
||||
Ref: row.Ref,
|
||||
Value: deepcopy.Slice(row.Value),
|
||||
}
|
||||
}
|
||||
|
||||
func (matrix *Matrix) UnmarshalYAML(node *yaml.Node) error {
|
||||
switch node.Kind {
|
||||
case yaml.MappingNode:
|
||||
|
||||
34
variables.go
34
variables.go
@@ -347,13 +347,14 @@ func itemsFromFor(
|
||||
var values []any // The list of values to loop over
|
||||
// Get the list from a matrix
|
||||
if f.Matrix.Len() != 0 {
|
||||
if err := resolveMatrixRefs(f.Matrix, cache); err != nil {
|
||||
resolvedMatrix, err := resolveMatrixRefs(f.Matrix, cache)
|
||||
if err != nil {
|
||||
return nil, nil, errors.TaskfileInvalidError{
|
||||
URI: location.Taskfile,
|
||||
Err: err,
|
||||
}
|
||||
}
|
||||
return asAnySlice(product(f.Matrix)), nil, nil
|
||||
return asAnySlice(product(resolvedMatrix)), nil, nil
|
||||
}
|
||||
// Get the list from the explicit for list
|
||||
if len(f.List) > 0 {
|
||||
@@ -425,22 +426,43 @@ func itemsFromFor(
|
||||
return values, keys, nil
|
||||
}
|
||||
|
||||
func resolveMatrixRefs(matrix *ast.Matrix, cache *templater.Cache) error {
|
||||
// resolveMatrixRefs resolves any `ref:` rows in matrix and returns a new
|
||||
// Matrix with those rows populated. It must not mutate the matrix passed in:
|
||||
// that matrix is part of the shared, cached Task AST, and concurrent
|
||||
// invocations of the same task (e.g. via parallel deps) call this with the
|
||||
// same *ast.Matrix and would otherwise race on the row.Value assignment
|
||||
// below, intermittently leaking a value resolved for one caller into another
|
||||
// caller's expansion. See #2890.
|
||||
func resolveMatrixRefs(matrix *ast.Matrix, cache *templater.Cache) (*ast.Matrix, error) {
|
||||
if matrix.Len() == 0 {
|
||||
return nil
|
||||
return matrix, nil
|
||||
}
|
||||
hasRef := false
|
||||
for _, row := range matrix.All() {
|
||||
if row.Ref != "" {
|
||||
hasRef = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !hasRef {
|
||||
return matrix, nil
|
||||
}
|
||||
resolved := matrix.DeepCopy()
|
||||
for _, row := range resolved.All() {
|
||||
if row.Ref != "" {
|
||||
v := templater.ResolveRef(row.Ref, cache)
|
||||
if cache.Err() != nil {
|
||||
return nil, cache.Err()
|
||||
}
|
||||
switch value := v.(type) {
|
||||
case []any:
|
||||
row.Value = value
|
||||
default:
|
||||
return fmt.Errorf("matrix reference %q must resolve to a list", row.Ref)
|
||||
return nil, fmt.Errorf("matrix reference %q must resolve to a list", row.Ref)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
return resolved, nil
|
||||
}
|
||||
|
||||
func resolveEnumRefs(requires *ast.Requires, cache *templater.Cache) error {
|
||||
|
||||
45
variables_test.go
Normal file
45
variables_test.go
Normal file
@@ -0,0 +1,45 @@
|
||||
package task
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/go-task/task/v3/internal/templater"
|
||||
"github.com/go-task/task/v3/taskfile/ast"
|
||||
)
|
||||
|
||||
// TestResolveMatrixRefsDoesNotMutateInput is a regression test for #2890. The
|
||||
// *ast.Matrix passed to resolveMatrixRefs is part of the shared, cached Task
|
||||
// AST: the same *ast.Matrix is reused on every invocation of a task. If
|
||||
// resolveMatrixRefs resolved `ref:` rows in place, concurrent invocations of
|
||||
// the same task (e.g. via parallel deps) would race on that mutation and leak
|
||||
// a value resolved for one caller into another caller's expansion.
|
||||
//
|
||||
// The invariant that prevents this is that resolveMatrixRefs must resolve into
|
||||
// a copy and leave its input untouched, which this test asserts deterministically.
|
||||
func TestResolveMatrixRefsDoesNotMutateInput(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
matrix := ast.NewMatrix(
|
||||
&ast.MatrixElement{Key: "ARCH", Value: &ast.MatrixRow{Ref: ".ARCH_VAR"}},
|
||||
)
|
||||
|
||||
vars := ast.NewVars()
|
||||
vars.Set("ARCH_VAR", ast.Var{Value: []any{"amd64"}})
|
||||
cache := &templater.Cache{Vars: vars}
|
||||
|
||||
resolved, err := resolveMatrixRefs(matrix, cache)
|
||||
require.NoError(t, err)
|
||||
|
||||
// The returned matrix has the ref resolved...
|
||||
row, ok := resolved.Get("ARCH")
|
||||
require.True(t, ok, "ARCH row missing from resolved matrix")
|
||||
require.Equal(t, []any{"amd64"}, row.Value)
|
||||
|
||||
// ...but the shared input matrix must be left untouched.
|
||||
orig, ok := matrix.Get("ARCH")
|
||||
require.True(t, ok, "ARCH row missing from input matrix")
|
||||
require.Nil(t, orig.Value, "input matrix was mutated: Ref rows must be resolved into a copy")
|
||||
require.Equal(t, ".ARCH_VAR", orig.Ref, "input matrix Ref was altered")
|
||||
}
|
||||
@@ -23,5 +23,5 @@
|
||||
"vitepress-plugin-llms": "^1.9.1",
|
||||
"vue": "^3.5.18"
|
||||
},
|
||||
"packageManager": "pnpm@11.5.0+sha512.dbfcc4f81cf48597afd4bc391ffdf12c11f1a9fb83a395bfa6b0a2d9cc2fd8ffebafdb1ccbd529632153f793904c2615b7f09fe1a345473fd1c35845172a8eb1"
|
||||
"packageManager": "pnpm@11.8.0+sha512.c1f5e7c4cb241c8f174b743851d82f42b802324afc8b0f116b96adb15aa06664948dde36960a3ba1079ba5b4b29dd0140135b94b5b5f5263592249d68e555f26"
|
||||
}
|
||||
|
||||
1075
website/pnpm-lock.yaml
generated
1075
website/pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -944,7 +944,7 @@ Also, `task --status [tasks]...` will exit with a non-zero
|
||||
|
||||
`status` can be combined with the
|
||||
[fingerprinting](#by-fingerprinting-locally-generated-files-and-their-sources)
|
||||
to have a task run if either the the source/generated artifacts changes, or the
|
||||
to have a task run if either the source/generated artifacts changes, or the
|
||||
programmatic check fails:
|
||||
|
||||
```yaml
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema",
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "Taskfile YAML Schema",
|
||||
"description": "Schema for Taskfile files.",
|
||||
"definitions": {
|
||||
|
||||
Reference in New Issue
Block a user