mirror of
https://github.com/go-task/task.git
synced 2026-05-19 05:36:24 +02:00
Compare commits
16 Commits
feat/add-g
...
v3.42.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cd086228b2 | ||
|
|
1b8b399c7e | ||
|
|
8426f84b18 | ||
|
|
14bbb324e5 | ||
|
|
b9d202c491 | ||
|
|
c23c46e326 | ||
|
|
a266fba93e | ||
|
|
fb631902ce | ||
|
|
b14125bacd | ||
|
|
3c5782f4a4 | ||
|
|
60c8ee0ce6 | ||
|
|
cdaf69e03d | ||
|
|
d6234af49a | ||
|
|
a31f2cf4a8 | ||
|
|
0dd6f78855 | ||
|
|
6f80777faf |
@@ -9,6 +9,7 @@ linters:
|
||||
- goimports
|
||||
- gofmt
|
||||
- gofumpt
|
||||
- mirror
|
||||
- misspell
|
||||
- noctx
|
||||
- paralleltest
|
||||
|
||||
28
CHANGELOG.md
28
CHANGELOG.md
@@ -1,6 +1,6 @@
|
||||
# Changelog
|
||||
|
||||
## Unreleased
|
||||
## v3.42.0 - 2025-03-08
|
||||
|
||||
- Made `--init` less verbose by default and respect `--silent` and `--verbose`
|
||||
flags (#2009, #2011 by @HeCorr).
|
||||
@@ -15,7 +15,7 @@
|
||||
- Print warnings when attempting to enable an inactive experiment or an active
|
||||
experiment with an invalid value (#1979, #2049 by @pd93).
|
||||
- Refactored the experiments package and added tests (#2049 by @pd93).
|
||||
- Show allowed values when a variable with an enum is missing (#2027, 2052 by
|
||||
- Show allowed values when a variable with an enum is missing (#2027, #2052 by
|
||||
@vmaerten).
|
||||
- Refactored how snippets in error work and added tests (#2068 by @pd93).
|
||||
- Fixed a bug where errors decoding commands were sometimes unhelpful (#2068 by
|
||||
@@ -25,6 +25,12 @@
|
||||
- Refactored how task sorting functions work (#1798 by @pd93).
|
||||
- Added a new `.taskrc.yml` (or `.taskrc.yaml`) file to let users enable
|
||||
experiments (similar to `.env`) (#1982 by @vmaerten).
|
||||
- Added new [Getting Started docs](https://taskfile.dev/getting-started) (#2086
|
||||
by @pd93).
|
||||
- Allow `matrix` to use references to other variables (#2065, #2069 by @pd93).
|
||||
- Fixed a bug where, when a dynamic variable is provided, even if it is not
|
||||
used, all other variables become unavailable in the templating system within
|
||||
the include (#2092 by @vmaerten).
|
||||
|
||||
#### Package API
|
||||
|
||||
@@ -47,7 +53,8 @@ stabilize the API in the future. #121 now tracks this piece of work.
|
||||
(#2068 by @pd93).
|
||||
- The caller is now expected to create the snippet themselves (see below).
|
||||
- [`TaskfileSnippet`](https://pkg.go.dev/github.com/go-task/task/v3/taskfile#Snippet)
|
||||
and related code moved from `v3/errors` to `v3/taskfile` (#2068 by @pd93).
|
||||
and related code moved from the `errors` package to the `taskfile` package
|
||||
(#2068 by @pd93).
|
||||
- Renamed `TaskMissingRequiredVars` to
|
||||
[`TaskMissingRequiredVarsError`](https://pkg.go.dev/github.com/go-task/task/v3/errors#TaskMissingRequiredVarsError)
|
||||
(#2052 by @vmaerten).
|
||||
@@ -57,8 +64,8 @@ stabilize the API in the future. #121 now tracks this piece of work.
|
||||
- The
|
||||
[`taskfile.Reader`](https://pkg.go.dev/github.com/go-task/task/v3/taskfile#Reader)
|
||||
is now constructed using the functional options pattern (#2082 by @pd93).
|
||||
- Removed our internal `logger.Logger` from the entire `v3/taskfile` package
|
||||
(#2082 by @pd93).
|
||||
- Removed our internal `logger.Logger` from the entire `taskfile` package (#2082
|
||||
by @pd93).
|
||||
- Users are now expected to pass a custom debug/prompt functions into
|
||||
[`taskfile.Reader`](https://pkg.go.dev/github.com/go-task/task/v3/taskfile#Reader)
|
||||
if they want this functionality by using the new
|
||||
@@ -66,8 +73,15 @@ stabilize the API in the future. #121 now tracks this piece of work.
|
||||
and
|
||||
[`WithPromptFunc`](https://pkg.go.dev/github.com/go-task/task/v3/taskfile#WithPromptFunc)
|
||||
functional options.
|
||||
- Remove `Range` functions in `v3/taskfile/ast` in favour of new iterator
|
||||
functions (#1798 by @pd93).
|
||||
- Remove `Range` functions in the `taskfile/ast` package in favour of new
|
||||
iterator functions (#1798 by @pd93).
|
||||
- `ast.Call` was moved from the `taskfile/ast` package to the main `task`
|
||||
package (#2084 by @pd93).
|
||||
- `ast.Tasks.FindMatchingTasks` was moved from the `taskfile/ast` package to the
|
||||
`task.Executor.FindMatchingTasks` in the main `task` package (#2084 by @pd93).
|
||||
- The `Compiler` and its `GetVariables` and `FastGetVariables` methods were
|
||||
moved from the `internal/compiler` package to the main `task` package (#2084
|
||||
by @pd93).
|
||||
|
||||
## v3.41.0 - 2025-01-18
|
||||
|
||||
|
||||
@@ -3,17 +3,18 @@ package args
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/go-task/task/v3"
|
||||
"github.com/go-task/task/v3/taskfile/ast"
|
||||
)
|
||||
|
||||
// Parse parses command line argument: tasks and global variables
|
||||
func Parse(args ...string) ([]*ast.Call, *ast.Vars) {
|
||||
calls := []*ast.Call{}
|
||||
func Parse(args ...string) ([]*task.Call, *ast.Vars) {
|
||||
calls := []*task.Call{}
|
||||
globals := ast.NewVars()
|
||||
|
||||
for _, arg := range args {
|
||||
if !strings.Contains(arg, "=") {
|
||||
calls = append(calls, &ast.Call{Task: arg})
|
||||
calls = append(calls, &task.Call{Task: arg})
|
||||
continue
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/go-task/task/v3"
|
||||
"github.com/go-task/task/v3/args"
|
||||
"github.com/go-task/task/v3/taskfile/ast"
|
||||
)
|
||||
@@ -15,12 +16,12 @@ func TestArgs(t *testing.T) {
|
||||
|
||||
tests := []struct {
|
||||
Args []string
|
||||
ExpectedCalls []*ast.Call
|
||||
ExpectedCalls []*task.Call
|
||||
ExpectedGlobals *ast.Vars
|
||||
}{
|
||||
{
|
||||
Args: []string{"task-a", "task-b", "task-c"},
|
||||
ExpectedCalls: []*ast.Call{
|
||||
ExpectedCalls: []*task.Call{
|
||||
{Task: "task-a"},
|
||||
{Task: "task-b"},
|
||||
{Task: "task-c"},
|
||||
@@ -28,7 +29,7 @@ func TestArgs(t *testing.T) {
|
||||
},
|
||||
{
|
||||
Args: []string{"task-a", "FOO=bar", "task-b", "task-c", "BAR=baz", "BAZ=foo"},
|
||||
ExpectedCalls: []*ast.Call{
|
||||
ExpectedCalls: []*task.Call{
|
||||
{Task: "task-a"},
|
||||
{Task: "task-b"},
|
||||
{Task: "task-c"},
|
||||
@@ -56,7 +57,7 @@ func TestArgs(t *testing.T) {
|
||||
},
|
||||
{
|
||||
Args: []string{"task-a", "CONTENT=with some spaces"},
|
||||
ExpectedCalls: []*ast.Call{
|
||||
ExpectedCalls: []*task.Call{
|
||||
{Task: "task-a"},
|
||||
},
|
||||
ExpectedGlobals: ast.NewVars(
|
||||
@@ -70,7 +71,7 @@ func TestArgs(t *testing.T) {
|
||||
},
|
||||
{
|
||||
Args: []string{"FOO=bar", "task-a", "task-b"},
|
||||
ExpectedCalls: []*ast.Call{
|
||||
ExpectedCalls: []*task.Call{
|
||||
{Task: "task-a"},
|
||||
{Task: "task-b"},
|
||||
},
|
||||
@@ -85,15 +86,15 @@ func TestArgs(t *testing.T) {
|
||||
},
|
||||
{
|
||||
Args: nil,
|
||||
ExpectedCalls: []*ast.Call{},
|
||||
ExpectedCalls: []*task.Call{},
|
||||
},
|
||||
{
|
||||
Args: []string{},
|
||||
ExpectedCalls: []*ast.Call{},
|
||||
ExpectedCalls: []*task.Call{},
|
||||
},
|
||||
{
|
||||
Args: []string{"FOO=bar", "BAR=baz"},
|
||||
ExpectedCalls: []*ast.Call{},
|
||||
ExpectedCalls: []*task.Call{},
|
||||
ExpectedGlobals: ast.NewVars(
|
||||
&ast.VarElement{
|
||||
Key: "FOO",
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
package ast
|
||||
package task
|
||||
|
||||
import "github.com/go-task/task/v3/taskfile/ast"
|
||||
|
||||
// Call is the parameters to a task call
|
||||
type Call struct {
|
||||
Task string
|
||||
Vars *Vars
|
||||
Vars *ast.Vars
|
||||
Silent bool
|
||||
Indirect bool // True if the task was called by another task
|
||||
}
|
||||
@@ -201,7 +201,7 @@ func run() error {
|
||||
}
|
||||
|
||||
var (
|
||||
calls []*ast.Call
|
||||
calls []*task.Call
|
||||
globals *ast.Vars
|
||||
)
|
||||
|
||||
@@ -214,7 +214,7 @@ func run() error {
|
||||
|
||||
// If there are no calls, run the default task instead
|
||||
if len(calls) == 0 {
|
||||
calls = append(calls, &ast.Call{Task: "default"})
|
||||
calls = append(calls, &task.Call{Task: "default"})
|
||||
}
|
||||
|
||||
globals.Set("CLI_ARGS", ast.Var{Value: cliArgs})
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package compiler
|
||||
package task
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
@@ -36,16 +36,16 @@ func (c *Compiler) GetTaskfileVariables() (*ast.Vars, error) {
|
||||
return c.getVariables(nil, nil, true)
|
||||
}
|
||||
|
||||
func (c *Compiler) GetVariables(t *ast.Task, call *ast.Call) (*ast.Vars, error) {
|
||||
func (c *Compiler) GetVariables(t *ast.Task, call *Call) (*ast.Vars, error) {
|
||||
return c.getVariables(t, call, true)
|
||||
}
|
||||
|
||||
func (c *Compiler) FastGetVariables(t *ast.Task, call *ast.Call) (*ast.Vars, error) {
|
||||
func (c *Compiler) FastGetVariables(t *ast.Task, call *Call) (*ast.Vars, error) {
|
||||
return c.getVariables(t, call, false)
|
||||
}
|
||||
|
||||
func (c *Compiler) getVariables(t *ast.Task, call *ast.Call, evaluateShVars bool) (*ast.Vars, error) {
|
||||
result := GetEnviron()
|
||||
func (c *Compiler) getVariables(t *ast.Task, call *Call, evaluateShVars bool) (*ast.Vars, error) {
|
||||
result := env.GetEnviron()
|
||||
specialVars, err := c.getSpecialVars(t, call)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -196,7 +196,7 @@ func (c *Compiler) ResetCache() {
|
||||
c.dynamicCache = nil
|
||||
}
|
||||
|
||||
func (c *Compiler) getSpecialVars(t *ast.Task, call *ast.Call) (map[string]string, error) {
|
||||
func (c *Compiler) getSpecialVars(t *ast.Task, call *Call) (map[string]string, error) {
|
||||
allVars := map[string]string{
|
||||
"TASK_EXE": filepath.ToSlash(os.Args[0]),
|
||||
"ROOT_TASKFILE": filepathext.SmartJoin(c.Dir, c.Entrypoint),
|
||||
28
go.mod
28
go.mod
@@ -12,7 +12,7 @@ require (
|
||||
github.com/elliotchance/orderedmap/v3 v3.1.0
|
||||
github.com/fatih/color v1.18.0
|
||||
github.com/go-git/go-billy/v5 v5.6.2
|
||||
github.com/go-git/go-git/v5 v5.13.2
|
||||
github.com/go-git/go-git/v5 v5.14.0
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0
|
||||
github.com/go-task/template v0.1.0
|
||||
github.com/joho/godotenv v1.5.1
|
||||
@@ -24,22 +24,22 @@ require (
|
||||
github.com/spf13/pflag v1.0.6
|
||||
github.com/stretchr/testify v1.10.0
|
||||
github.com/zeebo/xxh3 v1.0.2
|
||||
golang.org/x/sync v0.11.0
|
||||
golang.org/x/term v0.29.0
|
||||
golang.org/x/sync v0.12.0
|
||||
golang.org/x/term v0.30.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
mvdan.cc/sh/v3 v3.10.0
|
||||
mvdan.cc/sh/v3 v3.11.0
|
||||
)
|
||||
|
||||
require (
|
||||
dario.cat/mergo v1.0.0 // indirect
|
||||
github.com/Microsoft/go-winio v0.6.1 // indirect
|
||||
github.com/Microsoft/go-winio v0.6.2 // indirect
|
||||
github.com/ProtonMail/go-crypto v1.1.5 // indirect
|
||||
github.com/cloudflare/circl v1.3.7 // indirect
|
||||
github.com/cyphar/filepath-securejoin v0.3.6 // indirect
|
||||
github.com/cloudflare/circl v1.6.0 // indirect
|
||||
github.com/cyphar/filepath-securejoin v0.4.1 // indirect
|
||||
github.com/dlclark/regexp2 v1.11.4 // indirect
|
||||
github.com/emirpasic/gods v1.18.1 // indirect
|
||||
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
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/cpuid/v2 v2.2.7 // indirect
|
||||
@@ -50,13 +50,13 @@ require (
|
||||
github.com/pjbgf/sha1cd v0.3.2 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect
|
||||
github.com/skeema/knownhosts v1.3.0 // indirect
|
||||
github.com/skeema/knownhosts v1.3.1 // indirect
|
||||
github.com/stretchr/objx v0.5.2 // indirect
|
||||
github.com/xanzy/ssh-agent v0.3.3 // indirect
|
||||
golang.org/x/crypto v0.32.0 // indirect
|
||||
golang.org/x/mod v0.18.0 // indirect
|
||||
golang.org/x/net v0.34.0 // indirect
|
||||
golang.org/x/sys v0.30.0 // indirect
|
||||
golang.org/x/tools v0.22.0 // indirect
|
||||
golang.org/x/crypto v0.35.0 // indirect
|
||||
golang.org/x/mod v0.22.0 // indirect
|
||||
golang.org/x/net v0.35.0 // indirect
|
||||
golang.org/x/sys v0.31.0 // indirect
|
||||
golang.org/x/tools v0.27.0 // indirect
|
||||
gopkg.in/warnings.v0 v0.1.2 // indirect
|
||||
)
|
||||
|
||||
26
go.sum
26
go.sum
@@ -7,6 +7,8 @@ github.com/Masterminds/semver/v3 v3.3.1/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lpr
|
||||
github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
|
||||
github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=
|
||||
github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=
|
||||
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
|
||||
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
|
||||
github.com/ProtonMail/go-crypto v1.1.5 h1:eoAQfK2dwL+tFSFpr7TbOaPNUbPiJj4fLYwwGE1FQO4=
|
||||
github.com/ProtonMail/go-crypto v1.1.5/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE=
|
||||
github.com/alecthomas/assert/v2 v2.11.0 h1:2Q9r3ki8+JYXvGsDyBXwH3LcJ+WK5D0gc5E8vS6K3D0=
|
||||
@@ -23,10 +25,14 @@ github.com/chainguard-dev/git-urls v1.0.2 h1:pSpT7ifrpc5X55n4aTTm7FFUE+ZQHKiqpiw
|
||||
github.com/chainguard-dev/git-urls v1.0.2/go.mod h1:rbGgj10OS7UgZlbzdUQIQpT0k/D4+An04HJY7Ol+Y/o=
|
||||
github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU=
|
||||
github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA=
|
||||
github.com/cloudflare/circl v1.6.0 h1:cr5JKic4HI+LkINy2lg3W2jF8sHCVTBncJr5gIIq7qk=
|
||||
github.com/cloudflare/circl v1.6.0/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs=
|
||||
github.com/creack/pty v1.1.23 h1:4M6+isWdcStXEf15G/RbrMPOQj1dZ7HPZCGwE4kOeP0=
|
||||
github.com/creack/pty v1.1.23/go.mod h1:08sCNb52WyoAwi2QDyzUCTgcvVFhUzewun7wtTfvcwE=
|
||||
github.com/cyphar/filepath-securejoin v0.3.6 h1:4d9N5ykBnSp5Xn2JkhocYDkOpURL/18CYMpo6xB9uWM=
|
||||
github.com/cyphar/filepath-securejoin v0.3.6/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI=
|
||||
github.com/cyphar/filepath-securejoin v0.4.1 h1:JyxxyPEaktOD+GAnqIqTf9A8tHyAG22rowi7HkoSU1s=
|
||||
github.com/cyphar/filepath-securejoin v0.4.1/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
@@ -52,6 +58,8 @@ github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMj
|
||||
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.13.2 h1:7O7xvsK7K+rZPKW6AQR1YyNhfywkv7B8/FsP3ki6Zv0=
|
||||
github.com/go-git/go-git/v5 v5.13.2/go.mod h1:hWdW5P4YZRjmpGHwRH2v3zkWcNl6HeXaXQEMGb3NJ9A=
|
||||
github.com/go-git/go-git/v5 v5.14.0 h1:/MD3lCrGjCen5WfEAzKg00MJJffKhC8gzS80ycmCi60=
|
||||
github.com/go-git/go-git/v5 v5.14.0/go.mod h1:Z5Xhoia5PcWA3NF8vRLURn9E5FRhSl7dGj9ItW3Wk5k=
|
||||
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=
|
||||
@@ -60,6 +68,8 @@ github.com/go-task/template v0.1.0 h1:ym/r2G937RZA1bsgiWedNnY9e5kxDT+3YcoAnuIetT
|
||||
github.com/go-task/template v0.1.0/go.mod h1:RgwRaZK+kni/hJJ7/AaOE2lPQFPbAdji/DyhC6pxo4k=
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ=
|
||||
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM=
|
||||
@@ -113,6 +123,8 @@ github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG
|
||||
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/skeema/knownhosts v1.3.0 h1:AM+y0rI04VksttfwjkSTNQorvGqmwATnvnAHpSgc0LY=
|
||||
github.com/skeema/knownhosts v1.3.0/go.mod h1:sPINvnADmT/qYH1kfv+ePMmOBTH6Tbl7b5LvTDjFK7M=
|
||||
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.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
|
||||
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
@@ -131,15 +143,22 @@ github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaD
|
||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc=
|
||||
golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc=
|
||||
golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs=
|
||||
golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ=
|
||||
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8=
|
||||
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY=
|
||||
golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0=
|
||||
golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0=
|
||||
golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k=
|
||||
golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8=
|
||||
golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk=
|
||||
golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=
|
||||
golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw=
|
||||
golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||
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=
|
||||
@@ -151,15 +170,20 @@ 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.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
|
||||
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
|
||||
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU=
|
||||
golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s=
|
||||
golang.org/x/term v0.30.0 h1:PQ39fJZ+mfadBm0y5WlL4vlM7Sx1Hgf13sMIY2+QS9Y=
|
||||
golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
|
||||
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA=
|
||||
golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c=
|
||||
golang.org/x/tools v0.27.0/go.mod h1:sUi0ZgbwW9ZPAq26Ekut+weQPR5eIM6GQLQ1Yjm1H0Q=
|
||||
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=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
@@ -172,3 +196,5 @@ 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/v3 v3.10.0 h1:v9z7N1DLZ7owyLM/SXZQkBSXcwr2IGMm2LY2pmhVXj4=
|
||||
mvdan.cc/sh/v3 v3.10.0/go.mod h1:z/mSSVyLFGZzqb3ZIKojjyqIx/xbmz/UHdCSv9HmqXY=
|
||||
mvdan.cc/sh/v3 v3.11.0 h1:q5h+XMDRfUGUedCqFFsjoFjrhwf2Mvtt1rkMvVz0blw=
|
||||
mvdan.cc/sh/v3 v3.11.0/go.mod h1:LRM+1NjoYCzuq/WZ6y44x14YNAI0NK7FLPeQSaFagGg=
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
package compiler
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/go-task/task/v3/taskfile/ast"
|
||||
)
|
||||
|
||||
// GetEnviron the all return all environment variables encapsulated on a
|
||||
// ast.Vars
|
||||
func GetEnviron() *ast.Vars {
|
||||
m := ast.NewVars()
|
||||
for _, e := range os.Environ() {
|
||||
keyVal := strings.SplitN(e, "=", 2)
|
||||
key, val := keyVal[0], keyVal[1]
|
||||
m.Set(key, ast.Var{Value: val})
|
||||
}
|
||||
return m
|
||||
}
|
||||
13
internal/env/env.go
vendored
13
internal/env/env.go
vendored
@@ -3,6 +3,7 @@ package env
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/go-task/task/v3/internal/experiments"
|
||||
"github.com/go-task/task/v3/taskfile/ast"
|
||||
@@ -10,6 +11,18 @@ import (
|
||||
|
||||
const taskVarPrefix = "TASK_"
|
||||
|
||||
// GetEnviron the all return all environment variables encapsulated on a
|
||||
// ast.Vars
|
||||
func GetEnviron() *ast.Vars {
|
||||
m := ast.NewVars()
|
||||
for _, e := range os.Environ() {
|
||||
keyVal := strings.SplitN(e, "=", 2)
|
||||
key, val := keyVal[0], keyVal[1]
|
||||
m.Set(key, ast.Var{Value: val})
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
func Get(t *ast.Task) []string {
|
||||
if t.Env == nil {
|
||||
return nil
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package sort
|
||||
|
||||
import (
|
||||
"slices"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
@@ -11,9 +12,7 @@ type Sorter func(items []string, namespaces []string) []string
|
||||
// AlphaNumeric sorts the JSON output so that tasks are in alpha numeric order
|
||||
// by task name.
|
||||
func AlphaNumeric(items []string, namespaces []string) []string {
|
||||
sort.Slice(items, func(i, j int) bool {
|
||||
return items[i] < items[j]
|
||||
})
|
||||
slices.Sort(items)
|
||||
return items
|
||||
}
|
||||
|
||||
|
||||
@@ -7,10 +7,10 @@ import (
|
||||
"github.com/go-task/task/v3/taskfile/ast"
|
||||
)
|
||||
|
||||
func PrintTasks(l *logger.Logger, t *ast.Taskfile, c []*ast.Call) {
|
||||
func PrintTasks(l *logger.Logger, t *ast.Taskfile, c []string) {
|
||||
for i, call := range c {
|
||||
PrintSpaceBetweenSummaries(l, i)
|
||||
if task, ok := t.Tasks.Get(call.Task); ok {
|
||||
if task, ok := t.Tasks.Get(call); ok {
|
||||
PrintTask(l, task)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -179,7 +179,8 @@ func TestPrintAllWithSpaces(t *testing.T) {
|
||||
|
||||
summary.PrintTasks(&l,
|
||||
&ast.Taskfile{Tasks: tasks},
|
||||
[]*ast.Call{{Task: "t1"}, {Task: "t2"}, {Task: "t3"}})
|
||||
[]string{"t1", "t2", "t3"},
|
||||
)
|
||||
|
||||
assert.True(t, strings.HasPrefix(buffer.String(), "task: t1"))
|
||||
assert.Contains(t, buffer.String(), "\n(task does not have description or summary)\n\n\ntask: t2")
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package templater
|
||||
|
||||
import (
|
||||
"maps"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
@@ -60,13 +61,9 @@ func init() {
|
||||
cap += len(m)
|
||||
}
|
||||
result := make(map[string]any, cap)
|
||||
for k, v := range base {
|
||||
result[k] = v
|
||||
}
|
||||
maps.Copy(result, base)
|
||||
for _, m := range v {
|
||||
for k, v := range m {
|
||||
result[k] = v
|
||||
}
|
||||
maps.Copy(result, m)
|
||||
}
|
||||
return result
|
||||
},
|
||||
@@ -84,7 +81,5 @@ func init() {
|
||||
taskFuncs["ExeExt"] = taskFuncs["exeExt"]
|
||||
|
||||
templateFuncs = template.FuncMap(sprig.TxtFuncMap())
|
||||
for k, v := range taskFuncs {
|
||||
templateFuncs[k] = v
|
||||
}
|
||||
maps.Copy(templateFuncs, taskFuncs)
|
||||
}
|
||||
|
||||
2
package-lock.json
generated
2
package-lock.json
generated
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@go-task/cli",
|
||||
"version": "3.41.0",
|
||||
"version": "3.42.0",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@go-task/cli",
|
||||
"version": "3.41.0",
|
||||
"version": "3.42.0",
|
||||
"description": "A task runner / simpler Make alternative written in Go",
|
||||
"scripts": {
|
||||
"postinstall": "go-npm install",
|
||||
|
||||
@@ -2,7 +2,6 @@ package task
|
||||
|
||||
import (
|
||||
"context"
|
||||
"slices"
|
||||
|
||||
"github.com/go-task/task/v3/errors"
|
||||
"github.com/go-task/task/v3/internal/env"
|
||||
@@ -15,7 +14,7 @@ import (
|
||||
var ErrPreconditionFailed = errors.New("task: precondition not met")
|
||||
|
||||
func (e *Executor) areTaskPreconditionsMet(ctx context.Context, t *ast.Task) (bool, error) {
|
||||
for _, p := range slices.Concat(e.Taskfile.Preconditions.Values, t.Preconditions) {
|
||||
for _, p := range t.Preconditions {
|
||||
err := execext.RunCommand(ctx, &execext.RunCommandOptions{
|
||||
Command: p.Sh,
|
||||
Dir: t.Dir,
|
||||
|
||||
10
setup.go
10
setup.go
@@ -13,7 +13,6 @@ import (
|
||||
"github.com/sajari/fuzzy"
|
||||
|
||||
"github.com/go-task/task/v3/errors"
|
||||
"github.com/go-task/task/v3/internal/compiler"
|
||||
"github.com/go-task/task/v3/internal/env"
|
||||
"github.com/go-task/task/v3/internal/execext"
|
||||
"github.com/go-task/task/v3/internal/filepathext"
|
||||
@@ -198,7 +197,7 @@ func (e *Executor) setupCompiler() error {
|
||||
}
|
||||
}
|
||||
|
||||
e.Compiler = &compiler.Compiler{
|
||||
e.Compiler = &Compiler{
|
||||
Dir: e.Dir,
|
||||
Entrypoint: e.Entrypoint,
|
||||
UserWorkingDir: e.UserWorkingDir,
|
||||
@@ -214,7 +213,12 @@ func (e *Executor) readDotEnvFiles() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
env, err := taskfile.Dotenv(e.Compiler, e.Taskfile, e.Dir)
|
||||
vars, err := e.Compiler.GetTaskfileVariables()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
env, err := taskfile.Dotenv(vars, e.Taskfile, e.Dir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
)
|
||||
|
||||
// Status returns an error if any the of given tasks is not up-to-date
|
||||
func (e *Executor) Status(ctx context.Context, calls ...*ast.Call) error {
|
||||
func (e *Executor) Status(ctx context.Context, calls ...*Call) error {
|
||||
for _, call := range calls {
|
||||
|
||||
// Compile the task
|
||||
|
||||
60
task.go
60
task.go
@@ -11,10 +11,7 @@ import (
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"mvdan.cc/sh/v3/interp"
|
||||
|
||||
"github.com/go-task/task/v3/errors"
|
||||
"github.com/go-task/task/v3/internal/compiler"
|
||||
"github.com/go-task/task/v3/internal/env"
|
||||
"github.com/go-task/task/v3/internal/execext"
|
||||
"github.com/go-task/task/v3/internal/fingerprint"
|
||||
@@ -28,6 +25,7 @@ import (
|
||||
|
||||
"github.com/sajari/fuzzy"
|
||||
"golang.org/x/sync/errgroup"
|
||||
"mvdan.cc/sh/v3/interp"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -71,7 +69,7 @@ type Executor struct {
|
||||
Stderr io.Writer
|
||||
|
||||
Logger *logger.Logger
|
||||
Compiler *compiler.Compiler
|
||||
Compiler *Compiler
|
||||
Output output.Output
|
||||
OutputStyle ast.Output
|
||||
TaskSorter sort.Sorter
|
||||
@@ -87,8 +85,15 @@ type Executor struct {
|
||||
executionHashesMutex sync.Mutex
|
||||
}
|
||||
|
||||
// MatchingTask represents a task that matches a given call. It includes the
|
||||
// task itself and a list of wildcards that were matched.
|
||||
type MatchingTask struct {
|
||||
Task *ast.Task
|
||||
Wildcards []string
|
||||
}
|
||||
|
||||
// Run runs Task
|
||||
func (e *Executor) Run(ctx context.Context, calls ...*ast.Call) error {
|
||||
func (e *Executor) Run(ctx context.Context, calls ...*Call) error {
|
||||
// check if given tasks exist
|
||||
for _, call := range calls {
|
||||
task, err := e.GetTask(call)
|
||||
@@ -150,7 +155,7 @@ func (e *Executor) Run(ctx context.Context, calls ...*ast.Call) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *Executor) splitRegularAndWatchCalls(calls ...*ast.Call) (regularCalls []*ast.Call, watchCalls []*ast.Call, err error) {
|
||||
func (e *Executor) splitRegularAndWatchCalls(calls ...*Call) (regularCalls []*Call, watchCalls []*Call, err error) {
|
||||
for _, c := range calls {
|
||||
t, err := e.GetTask(c)
|
||||
if err != nil {
|
||||
@@ -167,7 +172,7 @@ func (e *Executor) splitRegularAndWatchCalls(calls ...*ast.Call) (regularCalls [
|
||||
}
|
||||
|
||||
// RunTask runs a task by its name
|
||||
func (e *Executor) RunTask(ctx context.Context, call *ast.Call) error {
|
||||
func (e *Executor) RunTask(ctx context.Context, call *Call) error {
|
||||
t, err := e.FastCompiledTask(call)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -317,7 +322,7 @@ func (e *Executor) runDeps(ctx context.Context, t *ast.Task) error {
|
||||
for _, d := range t.Deps {
|
||||
d := d
|
||||
g.Go(func() error {
|
||||
err := e.RunTask(ctx, &ast.Call{Task: d.Task, Vars: d.Vars, Silent: d.Silent, Indirect: true})
|
||||
err := e.RunTask(ctx, &Call{Task: d.Task, Vars: d.Vars, Silent: d.Silent, Indirect: true})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -328,7 +333,7 @@ func (e *Executor) runDeps(ctx context.Context, t *ast.Task) error {
|
||||
return g.Wait()
|
||||
}
|
||||
|
||||
func (e *Executor) runDeferred(t *ast.Task, call *ast.Call, i int, deferredExitCode *uint8) {
|
||||
func (e *Executor) runDeferred(t *ast.Task, call *Call, i int, deferredExitCode *uint8) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
@@ -353,7 +358,7 @@ func (e *Executor) runDeferred(t *ast.Task, call *ast.Call, i int, deferredExitC
|
||||
}
|
||||
}
|
||||
|
||||
func (e *Executor) runCommand(ctx context.Context, t *ast.Task, call *ast.Call, i int) error {
|
||||
func (e *Executor) runCommand(ctx context.Context, t *ast.Task, call *Call, i int) error {
|
||||
cmd := t.Cmds[i]
|
||||
|
||||
switch {
|
||||
@@ -361,7 +366,7 @@ func (e *Executor) runCommand(ctx context.Context, t *ast.Task, call *ast.Call,
|
||||
reacquire := e.releaseConcurrencyLimit()
|
||||
defer reacquire()
|
||||
|
||||
err := e.RunTask(ctx, &ast.Call{Task: cmd.Task, Vars: cmd.Vars, Silent: cmd.Silent, Indirect: true})
|
||||
err := e.RunTask(ctx, &Call{Task: cmd.Task, Vars: cmd.Vars, Silent: cmd.Silent, Indirect: true})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -447,12 +452,39 @@ func (e *Executor) startExecution(ctx context.Context, t *ast.Task, execute func
|
||||
return execute(ctx)
|
||||
}
|
||||
|
||||
// FindMatchingTasks returns a list of tasks that match the given call. A task
|
||||
// matches a call if its name is equal to the call's task name or if it matches
|
||||
// a wildcard pattern. The function returns a list of MatchingTask structs, each
|
||||
// containing a task and a list of wildcards that were matched.
|
||||
func (e *Executor) FindMatchingTasks(call *Call) []*MatchingTask {
|
||||
if call == nil {
|
||||
return nil
|
||||
}
|
||||
var matchingTasks []*MatchingTask
|
||||
// If there is a direct match, return it
|
||||
if task, ok := e.Taskfile.Tasks.Get(call.Task); ok {
|
||||
matchingTasks = append(matchingTasks, &MatchingTask{Task: task, Wildcards: nil})
|
||||
return matchingTasks
|
||||
}
|
||||
// Attempt a wildcard match
|
||||
// For now, we can just nil check the task before each loop
|
||||
for _, value := range e.Taskfile.Tasks.All(nil) {
|
||||
if match, wildcards := value.WildcardMatch(call.Task); match {
|
||||
matchingTasks = append(matchingTasks, &MatchingTask{
|
||||
Task: value,
|
||||
Wildcards: wildcards,
|
||||
})
|
||||
}
|
||||
}
|
||||
return matchingTasks
|
||||
}
|
||||
|
||||
// GetTask will return the task with the name matching the given call from the taskfile.
|
||||
// If no task is found, it will search for tasks with a matching alias.
|
||||
// If multiple tasks contain the same alias or no matches are found an error is returned.
|
||||
func (e *Executor) GetTask(call *ast.Call) (*ast.Task, error) {
|
||||
func (e *Executor) GetTask(call *Call) (*ast.Task, error) {
|
||||
// Search for a matching task
|
||||
matchingTasks := e.Taskfile.Tasks.FindMatchingTasks(call)
|
||||
matchingTasks := e.FindMatchingTasks(call)
|
||||
switch len(matchingTasks) {
|
||||
case 0: // Carry on
|
||||
case 1:
|
||||
@@ -532,7 +564,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(&ast.Call{Task: tasks[i].Task})
|
||||
compiledTask, err := e.FastCompiledTask(&Call{Task: tasks[i].Task})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
387
task_test.go
387
task_test.go
File diff suppressed because it is too large
Load Diff
@@ -10,15 +10,25 @@ import (
|
||||
"github.com/go-task/task/v3/internal/deepcopy"
|
||||
)
|
||||
|
||||
type Matrix struct {
|
||||
om *orderedmap.OrderedMap[string, []any]
|
||||
}
|
||||
|
||||
type MatrixElement orderedmap.Element[string, []any]
|
||||
type (
|
||||
// Matrix is an ordered map of variable names to arrays of values.
|
||||
Matrix struct {
|
||||
om *orderedmap.OrderedMap[string, *MatrixRow]
|
||||
}
|
||||
// A MatrixElement is a key-value pair that is used for initializing a
|
||||
// Matrix structure.
|
||||
MatrixElement orderedmap.Element[string, *MatrixRow]
|
||||
// A MatrixRow list of values for a matrix key or a reference to another
|
||||
// variable.
|
||||
MatrixRow struct {
|
||||
Ref string
|
||||
Value []any
|
||||
}
|
||||
)
|
||||
|
||||
func NewMatrix(els ...*MatrixElement) *Matrix {
|
||||
matrix := &Matrix{
|
||||
om: orderedmap.NewOrderedMap[string, []any](),
|
||||
om: orderedmap.NewOrderedMap[string, *MatrixRow](),
|
||||
}
|
||||
for _, el := range els {
|
||||
matrix.Set(el.Key, el.Value)
|
||||
@@ -33,27 +43,27 @@ func (matrix *Matrix) Len() int {
|
||||
return matrix.om.Len()
|
||||
}
|
||||
|
||||
func (matrix *Matrix) Get(key string) ([]any, bool) {
|
||||
func (matrix *Matrix) Get(key string) (*MatrixRow, bool) {
|
||||
if matrix == nil || matrix.om == nil {
|
||||
return nil, false
|
||||
}
|
||||
return matrix.om.Get(key)
|
||||
}
|
||||
|
||||
func (matrix *Matrix) Set(key string, value []any) bool {
|
||||
func (matrix *Matrix) Set(key string, value *MatrixRow) bool {
|
||||
if matrix == nil {
|
||||
matrix = NewMatrix()
|
||||
}
|
||||
if matrix.om == nil {
|
||||
matrix.om = orderedmap.NewOrderedMap[string, []any]()
|
||||
matrix.om = orderedmap.NewOrderedMap[string, *MatrixRow]()
|
||||
}
|
||||
return matrix.om.Set(key, value)
|
||||
}
|
||||
|
||||
// All returns an iterator that loops over all task key-value pairs.
|
||||
func (matrix *Matrix) All() iter.Seq2[string, []any] {
|
||||
func (matrix *Matrix) All() iter.Seq2[string, *MatrixRow] {
|
||||
if matrix == nil || matrix.om == nil {
|
||||
return func(yield func(string, []any) bool) {}
|
||||
return func(yield func(string, *MatrixRow) bool) {}
|
||||
}
|
||||
return matrix.om.AllFromFront()
|
||||
}
|
||||
@@ -67,9 +77,9 @@ func (matrix *Matrix) Keys() iter.Seq[string] {
|
||||
}
|
||||
|
||||
// Values returns an iterator that loops over all task values.
|
||||
func (matrix *Matrix) Values() iter.Seq[[]any] {
|
||||
func (matrix *Matrix) Values() iter.Seq[*MatrixRow] {
|
||||
if matrix == nil || matrix.om == nil {
|
||||
return func(yield func([]any) bool) {}
|
||||
return func(yield func(*MatrixRow) bool) {}
|
||||
}
|
||||
return matrix.om.Values()
|
||||
}
|
||||
@@ -93,14 +103,36 @@ func (matrix *Matrix) UnmarshalYAML(node *yaml.Node) error {
|
||||
keyNode := node.Content[i]
|
||||
valueNode := node.Content[i+1]
|
||||
|
||||
// Decode the value node into a Matrix struct
|
||||
var v []any
|
||||
if err := valueNode.Decode(&v); err != nil {
|
||||
return errors.NewTaskfileDecodeError(err, node)
|
||||
}
|
||||
switch valueNode.Kind {
|
||||
case yaml.SequenceNode:
|
||||
// Decode the value node into a Matrix struct
|
||||
var v []any
|
||||
if err := valueNode.Decode(&v); err != nil {
|
||||
return errors.NewTaskfileDecodeError(err, node)
|
||||
}
|
||||
|
||||
// Add the task to the ordered map
|
||||
matrix.Set(keyNode.Value, v)
|
||||
// Add the row to the ordered map
|
||||
matrix.Set(keyNode.Value, &MatrixRow{
|
||||
Value: v,
|
||||
})
|
||||
|
||||
case yaml.MappingNode:
|
||||
// Decode the value node into a Matrix struct
|
||||
var refStruct struct {
|
||||
Ref string
|
||||
}
|
||||
if err := valueNode.Decode(&refStruct); err != nil {
|
||||
return errors.NewTaskfileDecodeError(err, node)
|
||||
}
|
||||
|
||||
// Add the reference to the ordered map
|
||||
matrix.Set(keyNode.Value, &MatrixRow{
|
||||
Ref: refStruct.Ref,
|
||||
})
|
||||
|
||||
default:
|
||||
return errors.NewTaskfileDecodeError(nil, node).WithMessage("matrix values must be an array or a reference")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -9,12 +9,10 @@ import (
|
||||
)
|
||||
|
||||
// Precondition represents a precondition necessary for a task to run
|
||||
type (
|
||||
Precondition struct {
|
||||
Sh string
|
||||
Msg string
|
||||
}
|
||||
)
|
||||
type Precondition struct {
|
||||
Sh string
|
||||
Msg string
|
||||
}
|
||||
|
||||
func (p *Precondition) DeepCopy() *Precondition {
|
||||
if p == nil {
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
package ast
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"github.com/go-task/task/v3/errors"
|
||||
"github.com/go-task/task/v3/internal/deepcopy"
|
||||
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
// Precondition represents a precondition necessary for a task to run
|
||||
type (
|
||||
Preconditions struct {
|
||||
Values []*Precondition
|
||||
mutex sync.RWMutex
|
||||
}
|
||||
)
|
||||
|
||||
func NewPreconditions() *Preconditions {
|
||||
return &Preconditions{
|
||||
Values: make([]*Precondition, 0),
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Preconditions) DeepCopy() *Preconditions {
|
||||
if p == nil {
|
||||
return nil
|
||||
}
|
||||
defer p.mutex.RUnlock()
|
||||
p.mutex.RLock()
|
||||
return &Preconditions{
|
||||
Values: deepcopy.Slice(p.Values),
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Preconditions) UnmarshalYAML(node *yaml.Node) error {
|
||||
if p == nil || p.Values == nil {
|
||||
*p = *NewPreconditions()
|
||||
}
|
||||
|
||||
if err := node.Decode(&p.Values); err != nil {
|
||||
return errors.NewTaskfileDecodeError(err, node).WithTypeMessage("preconditions")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -18,26 +18,22 @@ var V3 = semver.MustParse("3")
|
||||
// ErrIncludedTaskfilesCantHaveDotenvs is returned when a included Taskfile contains dotenvs
|
||||
var ErrIncludedTaskfilesCantHaveDotenvs = errors.New("task: Included Taskfiles can't have dotenv declarations. Please, move the dotenv declaration to the main Taskfile")
|
||||
|
||||
// ErrIncludedTaskfilesCantHavePreconditions is returned when a included Taskfile contains Preconditions
|
||||
var ErrIncludedTaskfilesCantHavePreconditions = errors.New("task: Included Taskfiles can't have preconditions declarations. Please, move the preconditions declaration to the main Taskfile")
|
||||
|
||||
// Taskfile is the abstract syntax tree for a Taskfile
|
||||
type Taskfile struct {
|
||||
Location string
|
||||
Version *semver.Version
|
||||
Output Output
|
||||
Method string
|
||||
Includes *Includes
|
||||
Set []string
|
||||
Shopt []string
|
||||
Vars *Vars
|
||||
Env *Vars
|
||||
Preconditions *Preconditions
|
||||
Tasks *Tasks
|
||||
Silent bool
|
||||
Dotenv []string
|
||||
Run string
|
||||
Interval time.Duration
|
||||
Location string
|
||||
Version *semver.Version
|
||||
Output Output
|
||||
Method string
|
||||
Includes *Includes
|
||||
Set []string
|
||||
Shopt []string
|
||||
Vars *Vars
|
||||
Env *Vars
|
||||
Tasks *Tasks
|
||||
Silent bool
|
||||
Dotenv []string
|
||||
Run string
|
||||
Interval time.Duration
|
||||
}
|
||||
|
||||
// Merge merges the second Taskfile into the first
|
||||
@@ -48,9 +44,6 @@ func (t1 *Taskfile) Merge(t2 *Taskfile, include *Include) error {
|
||||
if len(t2.Dotenv) > 0 {
|
||||
return ErrIncludedTaskfilesCantHaveDotenvs
|
||||
}
|
||||
if len(t2.Preconditions.Values) > 0 {
|
||||
return ErrIncludedTaskfilesCantHavePreconditions
|
||||
}
|
||||
if t2.Output.IsSet() {
|
||||
t1.Output = t2.Output
|
||||
}
|
||||
@@ -66,9 +59,6 @@ func (t1 *Taskfile) Merge(t2 *Taskfile, include *Include) error {
|
||||
if t1.Tasks == nil {
|
||||
t1.Tasks = NewTasks()
|
||||
}
|
||||
if t1.Preconditions == nil {
|
||||
t1.Preconditions = NewPreconditions()
|
||||
}
|
||||
t1.Vars.Merge(t2.Vars, include)
|
||||
t1.Env.Merge(t2.Env, include)
|
||||
return t1.Tasks.Merge(t2.Tasks, include, t1.Vars)
|
||||
@@ -78,20 +68,19 @@ func (tf *Taskfile) UnmarshalYAML(node *yaml.Node) error {
|
||||
switch node.Kind {
|
||||
case yaml.MappingNode:
|
||||
var taskfile struct {
|
||||
Version *semver.Version
|
||||
Output Output
|
||||
Method string
|
||||
Includes *Includes
|
||||
Preconditions *Preconditions
|
||||
Set []string
|
||||
Shopt []string
|
||||
Vars *Vars
|
||||
Env *Vars
|
||||
Tasks *Tasks
|
||||
Silent bool
|
||||
Dotenv []string
|
||||
Run string
|
||||
Interval time.Duration
|
||||
Version *semver.Version
|
||||
Output Output
|
||||
Method string
|
||||
Includes *Includes
|
||||
Set []string
|
||||
Shopt []string
|
||||
Vars *Vars
|
||||
Env *Vars
|
||||
Tasks *Tasks
|
||||
Silent bool
|
||||
Dotenv []string
|
||||
Run string
|
||||
Interval time.Duration
|
||||
}
|
||||
if err := node.Decode(&taskfile); err != nil {
|
||||
return errors.NewTaskfileDecodeError(err, node)
|
||||
@@ -109,7 +98,6 @@ func (tf *Taskfile) UnmarshalYAML(node *yaml.Node) error {
|
||||
tf.Dotenv = taskfile.Dotenv
|
||||
tf.Run = taskfile.Run
|
||||
tf.Interval = taskfile.Interval
|
||||
tf.Preconditions = taskfile.Preconditions
|
||||
if tf.Includes == nil {
|
||||
tf.Includes = NewIncludes()
|
||||
}
|
||||
@@ -122,9 +110,6 @@ func (tf *Taskfile) UnmarshalYAML(node *yaml.Node) error {
|
||||
if tf.Tasks == nil {
|
||||
tf.Tasks = NewTasks()
|
||||
}
|
||||
if tf.Preconditions == nil {
|
||||
tf.Preconditions = NewPreconditions()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -24,12 +24,6 @@ type (
|
||||
// A TaskElement is a key-value pair that is used for initializing a Tasks
|
||||
// structure.
|
||||
TaskElement orderedmap.Element[string, *Task]
|
||||
// MatchingTask represents a task that matches a given call. It includes the
|
||||
// task itself and a list of wildcards that were matched.
|
||||
MatchingTask struct {
|
||||
Task *Task
|
||||
Wildcards []string
|
||||
}
|
||||
)
|
||||
|
||||
// NewTasks creates a new instance of Tasks and initializes it with the provided
|
||||
@@ -124,33 +118,6 @@ func (t *Tasks) Values(sorter sort.Sorter) iter.Seq[*Task] {
|
||||
}
|
||||
}
|
||||
|
||||
// FindMatchingTasks returns a list of tasks that match the given call. A task
|
||||
// matches a call if its name is equal to the call's task name or if it matches
|
||||
// a wildcard pattern. The function returns a list of MatchingTask structs, each
|
||||
// containing a task and a list of wildcards that were matched.
|
||||
func (t *Tasks) FindMatchingTasks(call *Call) []*MatchingTask {
|
||||
if call == nil {
|
||||
return nil
|
||||
}
|
||||
var matchingTasks []*MatchingTask
|
||||
// If there is a direct match, return it
|
||||
if task, ok := t.Get(call.Task); ok {
|
||||
matchingTasks = append(matchingTasks, &MatchingTask{Task: task, Wildcards: nil})
|
||||
return matchingTasks
|
||||
}
|
||||
// Attempt a wildcard match
|
||||
// For now, we can just nil check the task before each loop
|
||||
for _, value := range t.All(nil) {
|
||||
if match, wildcards := value.WildcardMatch(call.Task); match {
|
||||
matchingTasks = append(matchingTasks, &MatchingTask{
|
||||
Task: value,
|
||||
Wildcards: wildcards,
|
||||
})
|
||||
}
|
||||
}
|
||||
return matchingTasks
|
||||
}
|
||||
|
||||
func (t1 *Tasks) Merge(t2 *Tasks, include *Include, includedTaskfileVars *Vars) error {
|
||||
defer t2.mutex.RUnlock()
|
||||
t2.mutex.RLock()
|
||||
|
||||
@@ -105,7 +105,7 @@ func (vars *Vars) ToCacheMap() (m map[string]any) {
|
||||
if v.Sh != nil && *v.Sh != "" {
|
||||
// Dynamic variable is not yet resolved; trigger
|
||||
// <no value> to be used in templates.
|
||||
return nil
|
||||
continue
|
||||
}
|
||||
if v.Live != nil {
|
||||
m[k] = v.Live
|
||||
|
||||
@@ -6,22 +6,16 @@ import (
|
||||
|
||||
"github.com/joho/godotenv"
|
||||
|
||||
"github.com/go-task/task/v3/internal/compiler"
|
||||
"github.com/go-task/task/v3/internal/filepathext"
|
||||
"github.com/go-task/task/v3/internal/templater"
|
||||
"github.com/go-task/task/v3/taskfile/ast"
|
||||
)
|
||||
|
||||
func Dotenv(c *compiler.Compiler, tf *ast.Taskfile, dir string) (*ast.Vars, error) {
|
||||
func Dotenv(vars *ast.Vars, tf *ast.Taskfile, dir string) (*ast.Vars, error) {
|
||||
if len(tf.Dotenv) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
vars, err := c.GetTaskfileVariables()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
env := ast.NewVars()
|
||||
cache := &templater.Cache{Vars: vars}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
"gopkg.in/yaml.v3"
|
||||
|
||||
"github.com/go-task/task/v3/errors"
|
||||
"github.com/go-task/task/v3/internal/compiler"
|
||||
"github.com/go-task/task/v3/internal/env"
|
||||
"github.com/go-task/task/v3/internal/filepathext"
|
||||
"github.com/go-task/task/v3/internal/templater"
|
||||
"github.com/go-task/task/v3/taskfile/ast"
|
||||
@@ -188,7 +188,7 @@ func (r *Reader) include(node Node) error {
|
||||
|
||||
// Loop over each included taskfile
|
||||
for _, include := range vertex.Taskfile.Includes.All() {
|
||||
vars := compiler.GetEnviron()
|
||||
vars := env.GetEnviron()
|
||||
vars.Merge(vertex.Taskfile.Vars, nil)
|
||||
// Start a goroutine to process each included Taskfile
|
||||
g.Go(func() error {
|
||||
|
||||
@@ -59,7 +59,7 @@ func NewSnippet(b []byte, opts ...SnippetOption) *Snippet {
|
||||
// Syntax highlight the input and split it into lines
|
||||
buf := &bytes.Buffer{}
|
||||
if err := quick.Highlight(buf, string(b), "yaml", "terminal", "task"); err != nil {
|
||||
buf.WriteString(string(b))
|
||||
buf.Write(b)
|
||||
}
|
||||
linesRaw := strings.Split(string(b), "\n")
|
||||
linesHighlighted := strings.Split(buf.String(), "\n")
|
||||
|
||||
25
testdata/for/cmds/Taskfile.yml
vendored
25
testdata/for/cmds/Taskfile.yml
vendored
@@ -1,5 +1,10 @@
|
||||
version: "3"
|
||||
|
||||
vars:
|
||||
OS_VAR: ["windows", "linux", "darwin"]
|
||||
ARCH_VAR: ["amd64", "arm64"]
|
||||
NOT_A_LIST: "not a list"
|
||||
|
||||
tasks:
|
||||
# Loop over a list of values
|
||||
loop-explicit:
|
||||
@@ -15,6 +20,26 @@ tasks:
|
||||
ARCH: ["amd64", "arm64"]
|
||||
cmd: echo "{{.ITEM.OS}}/{{.ITEM.ARCH}}"
|
||||
|
||||
loop-matrix-ref:
|
||||
cmds:
|
||||
- for:
|
||||
matrix:
|
||||
OS:
|
||||
ref: .OS_VAR
|
||||
ARCH:
|
||||
ref: .ARCH_VAR
|
||||
cmd: echo "{{.ITEM.OS}}/{{.ITEM.ARCH}}"
|
||||
|
||||
loop-matrix-ref-error:
|
||||
cmds:
|
||||
- for:
|
||||
matrix:
|
||||
OS:
|
||||
ref: .OS_VAR
|
||||
ARCH:
|
||||
ref: .NOT_A_LIST
|
||||
cmd: echo "{{.ITEM.OS}}/{{.ITEM.ARCH}}"
|
||||
|
||||
# Loop over the task's sources
|
||||
loop-sources:
|
||||
sources:
|
||||
|
||||
29
testdata/for/deps/Taskfile.yml
vendored
29
testdata/for/deps/Taskfile.yml
vendored
@@ -1,5 +1,10 @@
|
||||
version: "3"
|
||||
|
||||
vars:
|
||||
OS_VAR: ["windows", "linux", "darwin"]
|
||||
ARCH_VAR: ["amd64", "arm64"]
|
||||
NOT_A_LIST: "not a list"
|
||||
|
||||
tasks:
|
||||
# Loop over a list of values
|
||||
loop-explicit:
|
||||
@@ -19,6 +24,30 @@ tasks:
|
||||
vars:
|
||||
TEXT: "{{.ITEM.OS}}/{{.ITEM.ARCH}}"
|
||||
|
||||
loop-matrix-ref:
|
||||
deps:
|
||||
- for:
|
||||
matrix:
|
||||
OS:
|
||||
ref: .OS_VAR
|
||||
ARCH:
|
||||
ref: .ARCH_VAR
|
||||
task: echo
|
||||
vars:
|
||||
TEXT: "{{.ITEM.OS}}/{{.ITEM.ARCH}}"
|
||||
|
||||
loop-matrix-ref-error:
|
||||
deps:
|
||||
- for:
|
||||
matrix:
|
||||
OS:
|
||||
ref: .OS_VAR
|
||||
ARCH:
|
||||
ref: .NOT_A_LIST
|
||||
task: echo
|
||||
vars:
|
||||
TEXT: "{{.ITEM.OS}}/{{.ITEM.ARCH}}"
|
||||
|
||||
# Loop over the task's sources
|
||||
loop-sources:
|
||||
sources:
|
||||
|
||||
10
testdata/include_with_vars_inside_include/Taskfile.yml
vendored
Normal file
10
testdata/include_with_vars_inside_include/Taskfile.yml
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
version: "3"
|
||||
|
||||
vars:
|
||||
INCLUDE: include
|
||||
FOO:
|
||||
sh : echo bar
|
||||
|
||||
includes:
|
||||
included1:
|
||||
taskfile: '{{.INCLUDE}}/Taskfile.include.yml'
|
||||
1
testdata/include_with_vars_inside_include/include/Taskfile.include.yml
vendored
Normal file
1
testdata/include_with_vars_inside_include/include/Taskfile.include.yml
vendored
Normal file
@@ -0,0 +1 @@
|
||||
version: "3"
|
||||
9
testdata/precondition/global/Taskfile.yml
vendored
9
testdata/precondition/global/Taskfile.yml
vendored
@@ -1,9 +0,0 @@
|
||||
version: '3'
|
||||
|
||||
preconditions:
|
||||
- sh: "[ 1 = 0 ]"
|
||||
msg: "1 != 0 obviously!"
|
||||
|
||||
tasks:
|
||||
impossible:
|
||||
cmd: echo "won't run"
|
||||
@@ -1,8 +0,0 @@
|
||||
version: 3
|
||||
|
||||
includes:
|
||||
included: included.yml
|
||||
|
||||
preconditions:
|
||||
- sh: "[ 1 = 0 ]"
|
||||
msg: "1 != 0 obviously!"
|
||||
@@ -1,5 +0,0 @@
|
||||
version: 3
|
||||
|
||||
preconditions:
|
||||
- sh: "[ 1 = 0 ]"
|
||||
msg: "1 != 0 obviously!"
|
||||
@@ -1,12 +0,0 @@
|
||||
version: '3'
|
||||
|
||||
preconditions:
|
||||
- test -f foo.txt
|
||||
|
||||
tasks:
|
||||
foo:
|
||||
|
||||
impossible:
|
||||
preconditions:
|
||||
- sh: "[ 1 = 0 ]"
|
||||
msg: "1 != 0 obviously!"
|
||||
0
testdata/precondition/local/foo.txt
vendored
0
testdata/precondition/local/foo.txt
vendored
49
variables.go
49
variables.go
@@ -1,6 +1,8 @@
|
||||
package task
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"maps"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
@@ -18,16 +20,16 @@ import (
|
||||
|
||||
// CompiledTask returns a copy of a task, but replacing variables in almost all
|
||||
// properties using the Go template package.
|
||||
func (e *Executor) CompiledTask(call *ast.Call) (*ast.Task, error) {
|
||||
func (e *Executor) CompiledTask(call *Call) (*ast.Task, error) {
|
||||
return e.compiledTask(call, true)
|
||||
}
|
||||
|
||||
// FastCompiledTask is like CompiledTask, but it skippes dynamic variables.
|
||||
func (e *Executor) FastCompiledTask(call *ast.Call) (*ast.Task, error) {
|
||||
func (e *Executor) FastCompiledTask(call *Call) (*ast.Task, error) {
|
||||
return e.compiledTask(call, false)
|
||||
}
|
||||
|
||||
func (e *Executor) compiledTask(call *ast.Call, evaluateShVars bool) (*ast.Task, error) {
|
||||
func (e *Executor) compiledTask(call *Call, evaluateShVars bool) (*ast.Task, error) {
|
||||
origTask, err := e.GetTask(call)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -151,7 +153,7 @@ func (e *Executor) compiledTask(call *ast.Call, evaluateShVars bool) (*ast.Task,
|
||||
continue
|
||||
}
|
||||
if cmd.For != nil {
|
||||
list, keys, err := itemsFromFor(cmd.For, new.Dir, new.Sources, vars, origTask.Location)
|
||||
list, keys, err := itemsFromFor(cmd.For, new.Dir, new.Sources, vars, origTask.Location, cache)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -198,7 +200,7 @@ func (e *Executor) compiledTask(call *ast.Call, evaluateShVars bool) (*ast.Task,
|
||||
continue
|
||||
}
|
||||
if dep.For != nil {
|
||||
list, keys, err := itemsFromFor(dep.For, new.Dir, new.Sources, vars, origTask.Location)
|
||||
list, keys, err := itemsFromFor(dep.For, new.Dir, new.Sources, vars, origTask.Location, cache)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -270,11 +272,18 @@ func itemsFromFor(
|
||||
sources []*ast.Glob,
|
||||
vars *ast.Vars,
|
||||
location *ast.Location,
|
||||
cache *templater.Cache,
|
||||
) ([]any, []string, error) {
|
||||
var keys []string // The list of keys to loop over (only if looping over a map)
|
||||
var values []any // The list of values to loop over
|
||||
// Get the list from a matrix
|
||||
if f.Matrix.Len() != 0 {
|
||||
if err := resolveMatrixRefs(f.Matrix, cache); err != nil {
|
||||
return nil, nil, errors.TaskfileInvalidError{
|
||||
URI: location.Taskfile,
|
||||
Err: err,
|
||||
}
|
||||
}
|
||||
return asAnySlice(product(f.Matrix)), nil, nil
|
||||
}
|
||||
// Get the list from the explicit for list
|
||||
@@ -333,9 +342,27 @@ func itemsFromFor(
|
||||
return values, keys, nil
|
||||
}
|
||||
|
||||
func resolveMatrixRefs(matrix *ast.Matrix, cache *templater.Cache) error {
|
||||
if matrix.Len() == 0 {
|
||||
return nil
|
||||
}
|
||||
for _, row := range matrix.All() {
|
||||
if row.Ref != "" {
|
||||
v := templater.ResolveRef(row.Ref, cache)
|
||||
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
|
||||
}
|
||||
|
||||
// product generates the cartesian product of the input map of slices.
|
||||
func product(inputMap *ast.Matrix) []map[string]any {
|
||||
if inputMap.Len() == 0 {
|
||||
func product(matrix *ast.Matrix) []map[string]any {
|
||||
if matrix.Len() == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -343,18 +370,16 @@ func product(inputMap *ast.Matrix) []map[string]any {
|
||||
result := []map[string]any{{}}
|
||||
|
||||
// Iterate over each slice in the slices
|
||||
for key, slice := range inputMap.All() {
|
||||
for key, row := range matrix.All() {
|
||||
var newResult []map[string]any
|
||||
|
||||
// For each combination in the current result
|
||||
for _, combination := range result {
|
||||
// Append each element from the current slice to the combinations
|
||||
for _, item := range slice {
|
||||
for _, item := range row.Value {
|
||||
newComb := make(map[string]any, len(combination))
|
||||
// Copy the existing combination
|
||||
for k, v := range combination {
|
||||
newComb[k] = v
|
||||
}
|
||||
maps.Copy(newComb, combination)
|
||||
// Add the current item with the corresponding key
|
||||
newComb[key] = item
|
||||
newResult = append(newResult, newComb)
|
||||
|
||||
13
watch.go
13
watch.go
@@ -15,13 +15,12 @@ import (
|
||||
"github.com/go-task/task/v3/errors"
|
||||
"github.com/go-task/task/v3/internal/fingerprint"
|
||||
"github.com/go-task/task/v3/internal/logger"
|
||||
"github.com/go-task/task/v3/taskfile/ast"
|
||||
)
|
||||
|
||||
const defaultWatchInterval = 5 * time.Second
|
||||
|
||||
// watchTasks start watching the given tasks
|
||||
func (e *Executor) watchTasks(calls ...*ast.Call) error {
|
||||
func (e *Executor) watchTasks(calls ...*Call) error {
|
||||
tasks := make([]string, len(calls))
|
||||
for i, c := range calls {
|
||||
tasks[i] = c.Task
|
||||
@@ -119,24 +118,24 @@ func closeOnInterrupt(w *watcher.Watcher) {
|
||||
}()
|
||||
}
|
||||
|
||||
func (e *Executor) registerWatchedFiles(w *watcher.Watcher, calls ...*ast.Call) error {
|
||||
func (e *Executor) registerWatchedFiles(w *watcher.Watcher, calls ...*Call) error {
|
||||
watchedFiles := w.WatchedFiles()
|
||||
|
||||
var registerTaskFiles func(*ast.Call) error
|
||||
registerTaskFiles = func(c *ast.Call) error {
|
||||
var registerTaskFiles func(*Call) error
|
||||
registerTaskFiles = func(c *Call) error {
|
||||
task, err := e.CompiledTask(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, d := range task.Deps {
|
||||
if err := registerTaskFiles(&ast.Call{Task: d.Task, Vars: d.Vars}); err != nil {
|
||||
if err := registerTaskFiles(&Call{Task: d.Task, Vars: d.Vars}); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
for _, c := range task.Cmds {
|
||||
if c.Task != "" {
|
||||
if err := registerTaskFiles(&ast.Call{Task: c.Task, Vars: c.Vars}); err != nil {
|
||||
if err := registerTaskFiles(&Call{Task: c.Task, Vars: c.Vars}); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,89 @@ sidebar_position: 14
|
||||
|
||||
# Changelog
|
||||
|
||||
## v3.42.0 - 2025-03-08
|
||||
|
||||
- Made `--init` less verbose by default and respect `--silent` and `--verbose`
|
||||
flags (#2009, #2011 by @HeCorr).
|
||||
- `--init` now accepts a file name or directory as an argument (#2008, #2018 by
|
||||
@HeCorr).
|
||||
- Fix a bug where an HTTP node's location was being mutated incorrectly (#2007
|
||||
by @jeongukjae).
|
||||
- Fixed a bug where allowed values didn't work with dynamic var (#2032, #2033 by
|
||||
@vmaerten).
|
||||
- Use only the relevant checker (timestamp or checksum) to improve performance
|
||||
(#2029, #2031 by @vmaerten).
|
||||
- Print warnings when attempting to enable an inactive experiment or an active
|
||||
experiment with an invalid value (#1979, #2049 by @pd93).
|
||||
- Refactored the experiments package and added tests (#2049 by @pd93).
|
||||
- Show allowed values when a variable with an enum is missing (#2027, #2052 by
|
||||
@vmaerten).
|
||||
- Refactored how snippets in error work and added tests (#2068 by @pd93).
|
||||
- Fixed a bug where errors decoding commands were sometimes unhelpful (#2068 by
|
||||
@pd93).
|
||||
- Fixed a bug in the Taskfile schema where `defer` statements in the shorthand
|
||||
`cmds` syntax were not considered valid (#2068 by @pd93).
|
||||
- Refactored how task sorting functions work (#1798 by @pd93).
|
||||
- Added a new `.taskrc.yml` (or `.taskrc.yaml`) file to let users enable
|
||||
experiments (similar to `.env`) (#1982 by @vmaerten).
|
||||
- Added new [Getting Started docs](https://taskfile.dev/getting-started) (#2086
|
||||
by @pd93).
|
||||
- Allow `matrix` to use references to other variables (#2065, #2069 by @pd93).
|
||||
- Fixed a bug where, when a dynamic variable is provided, even if it is not
|
||||
used, all other variables become unavailable in the templating system within
|
||||
the include (#2092 by @vmaerten).
|
||||
|
||||
#### Package API
|
||||
|
||||
Unlike our CLI tool,
|
||||
[Task's package API is not currently stable](https://taskfile.dev/reference/package).
|
||||
In an effort to ease the pain of breaking changes for our users, we will be
|
||||
providing changelogs for our package API going forwards. The hope is that these
|
||||
changes will provide a better long-term experience for our users and allow to
|
||||
stabilize the API in the future. #121 now tracks this piece of work.
|
||||
|
||||
- Bumped the minimum required Go version to 1.23 (#2059 by @pd93).
|
||||
- [`task.InitTaskfile`](https://pkg.go.dev/github.com/go-task/task/v3#InitTaskfile)
|
||||
(#2011, ff8c913 by @HeCorr and @pd93)
|
||||
- No longer accepts an `io.Writer` (output is now the caller's
|
||||
responsibility).
|
||||
- The path argument can now be a filename OR a directory.
|
||||
- The function now returns the full path of the generated file.
|
||||
- [`TaskfileDecodeError.WithFileInfo`](https://pkg.go.dev/github.com/go-task/task/v3/errors#TaskfileDecodeError.WithFileInfo)
|
||||
now accepts a string instead of the arguments required to generate a snippet
|
||||
(#2068 by @pd93).
|
||||
- The caller is now expected to create the snippet themselves (see below).
|
||||
- [`TaskfileSnippet`](https://pkg.go.dev/github.com/go-task/task/v3/taskfile#Snippet)
|
||||
and related code moved from the `errors` package to the `taskfile` package
|
||||
(#2068 by @pd93).
|
||||
- Renamed `TaskMissingRequiredVars` to
|
||||
[`TaskMissingRequiredVarsError`](https://pkg.go.dev/github.com/go-task/task/v3/errors#TaskMissingRequiredVarsError)
|
||||
(#2052 by @vmaerten).
|
||||
- Renamed `TaskNotAllowedVars` to
|
||||
[`TaskNotAllowedVarsError`](https://pkg.go.dev/github.com/go-task/task/v3/errors#TaskNotAllowedVarsError)
|
||||
(#2052 by @vmaerten).
|
||||
- The
|
||||
[`taskfile.Reader`](https://pkg.go.dev/github.com/go-task/task/v3/taskfile#Reader)
|
||||
is now constructed using the functional options pattern (#2082 by @pd93).
|
||||
- Removed our internal `logger.Logger` from the entire `taskfile` package (#2082
|
||||
by @pd93).
|
||||
- Users are now expected to pass a custom debug/prompt functions into
|
||||
[`taskfile.Reader`](https://pkg.go.dev/github.com/go-task/task/v3/taskfile#Reader)
|
||||
if they want this functionality by using the new
|
||||
[`WithDebugFunc`](https://pkg.go.dev/github.com/go-task/task/v3/taskfile#WithDebugFunc)
|
||||
and
|
||||
[`WithPromptFunc`](https://pkg.go.dev/github.com/go-task/task/v3/taskfile#WithPromptFunc)
|
||||
functional options.
|
||||
- Remove `Range` functions in the `taskfile/ast` package in favour of new
|
||||
iterator functions (#1798 by @pd93).
|
||||
- `ast.Call` was moved from the `taskfile/ast` package to the main `task`
|
||||
package (#2084 by @pd93).
|
||||
- `ast.Tasks.FindMatchingTasks` was moved from the `taskfile/ast` package to the
|
||||
`task.Executor.FindMatchingTasks` in the main `task` package (#2084 by @pd93).
|
||||
- The `Compiler` and its `GetVariables` and `FastGetVariables` methods were
|
||||
moved from the `internal/compiler` package to the main `task` package (#2084
|
||||
by @pd93).
|
||||
|
||||
## v3.41.0 - 2025-01-18
|
||||
|
||||
- Fixed an issue where dynamic variables were not properly logged in verbose
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
slug: /community/
|
||||
sidebar_position: 9
|
||||
sidebar_position: 10
|
||||
---
|
||||
|
||||
# Community
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
slug: /contributing/
|
||||
sidebar_position: 11
|
||||
sidebar_position: 12
|
||||
---
|
||||
|
||||
# Contributing
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
slug: /deprecations/
|
||||
sidebar_position: 7
|
||||
sidebar_position: 8
|
||||
---
|
||||
|
||||
# Deprecations
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
slug: /experiments/
|
||||
sidebar_position: 6
|
||||
sidebar_position: 7
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
|
||||
143
website/docs/getting_started.mdx
Normal file
143
website/docs/getting_started.mdx
Normal file
@@ -0,0 +1,143 @@
|
||||
---
|
||||
slug: /getting-started/
|
||||
sidebar_position: 3
|
||||
---
|
||||
|
||||
# Getting Started
|
||||
|
||||
The following guide will help introduce you to the basics of Task. We'll cover
|
||||
how to create a Taskfile, how to write a basic task and how to call it. If you
|
||||
haven't installed Task yet, head over to our [installation
|
||||
guide][installation].
|
||||
|
||||
## Creating your first Taskfile
|
||||
|
||||
Once Task is installed, you can create your first Taskfile by running:
|
||||
|
||||
```shell
|
||||
task --init
|
||||
```
|
||||
|
||||
This will create a file called `Taskfile.yml` in the current directory. If you
|
||||
want to create the file in another directory, you can pass an absolute or
|
||||
relative path to the directory into the command:
|
||||
|
||||
```shell
|
||||
task --init ./subdirectory
|
||||
```
|
||||
|
||||
Or if you want the Taskfile to have a specific name, you can pass in the name of
|
||||
the file:
|
||||
|
||||
```shell
|
||||
task --init Custom.yml
|
||||
```
|
||||
|
||||
This will create a Taskfile that looks something like this:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
vars:
|
||||
GREETING: Hello, World!
|
||||
|
||||
tasks:
|
||||
default:
|
||||
cmds:
|
||||
- echo "{{.GREETING}}"
|
||||
silent: true
|
||||
```
|
||||
|
||||
As you can see, all Taskfiles are written in [YAML format][yaml]. The `version`
|
||||
attribute specifies the minimum version of Task that can be used to run this
|
||||
file. The `vars` attribute is used to define variables that can be used in
|
||||
tasks. In this case, we are creating a string variable called `GREETING` with a
|
||||
value of `Hello, World!`.
|
||||
|
||||
Finally, the `tasks` attribute is used to define the tasks that can be run. In
|
||||
this case, we have a task called `default` that echoes the value of the
|
||||
`GREETING` variable. The `silent` attribute is set to `true`, which means that
|
||||
the task metadata will not be printed when the task is run - only the output of
|
||||
the commands.
|
||||
|
||||
## Calling a task
|
||||
|
||||
To call the task, you simply invoke `task` followed by the name of the task you
|
||||
want to run. In this case, the name of the task is `default`, so you should run:
|
||||
|
||||
```shell
|
||||
task default
|
||||
```
|
||||
|
||||
Note that we don't have to specify the name of the Taskfile. Task will
|
||||
automatically look for a file called `Taskfile.yml` (or any of Task's [supported
|
||||
file names][supported-file-names]) in the current directory. Additionally, tasks
|
||||
with the name `default` are special. They can also be run without specifying the
|
||||
task name.
|
||||
|
||||
If you created a Taskfile in a different directory, you can run it by passing
|
||||
the absolute or relative path to the directory as an argument using the `--dir`
|
||||
flag:
|
||||
|
||||
```shell
|
||||
task --dir ./subdirectory
|
||||
```
|
||||
|
||||
Or if you created a Taskfile with a different name, you can run it by passing
|
||||
the name of the Taskfile as an argument using the `--taskfile` flag:
|
||||
|
||||
```shell
|
||||
task --taskfile Custom.yml
|
||||
```
|
||||
|
||||
## Adding a build task
|
||||
|
||||
Let's create a task to build a program in Go. Start by adding a new task called
|
||||
`build` below the existing `default` task. We can then add a `cmds` attribute
|
||||
with a single command to build the program.
|
||||
|
||||
Task uses [mvdan/sh][mvdan/sh], a native Go sh interpreter. So you can write
|
||||
sh/bash-like commands - even in environments where `sh` or `bash` are usually
|
||||
not available (like Windows). Just remember any executables called must be
|
||||
available as a built-in or in the system's `PATH`.
|
||||
|
||||
When you're done, it should look something like this:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
vars:
|
||||
GREETING: Hello, World!
|
||||
|
||||
tasks:
|
||||
default:
|
||||
cmds:
|
||||
- echo "{{.GREETING}}"
|
||||
silent: true
|
||||
|
||||
build:
|
||||
cmds:
|
||||
- go build ./cmd/main.go
|
||||
```
|
||||
|
||||
Call the task by running:
|
||||
|
||||
```shell
|
||||
task build
|
||||
```
|
||||
|
||||
That's about it for the basics, but there's _so much_ more that you can do with
|
||||
Task. Check out the rest of the documentation to learn more about all the
|
||||
features Task has to offer! We recommend taking a look at the [usage
|
||||
guide][usage] next. Alternatively, you can check out our reference docs for the
|
||||
[Taskfile schema][schema] and [CLI][cli].
|
||||
|
||||
{/* prettier-ignore-start */}
|
||||
[yaml]: https://yaml.org/
|
||||
[installation]: /installation/
|
||||
[supported-file-names]: /usage/#supported-file-names
|
||||
[mvdan/sh]: https://github.com/mvdan/sh
|
||||
[usage]: /usage/
|
||||
[schema]: /reference/schema/
|
||||
[cli]: /reference/cli/
|
||||
{/* prettier-ignore-end */}
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
slug: /integrations/
|
||||
sidebar_position: 8
|
||||
sidebar_position: 9
|
||||
---
|
||||
|
||||
# Integrations
|
||||
|
||||
@@ -17,24 +17,6 @@ Since it's written in [Go][go], Task is just a single binary and has no other
|
||||
dependencies, which means you don't need to mess with any complicated install
|
||||
setups just to use a build tool.
|
||||
|
||||
Once [installed](/installation), you just need to describe your build tasks
|
||||
using a simple [YAML][yaml] schema in a file called `Taskfile.yml`:
|
||||
|
||||
```yaml title="Taskfile.yml"
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
hello:
|
||||
cmds:
|
||||
- echo 'Hello World from Task!'
|
||||
silent: true
|
||||
```
|
||||
|
||||
And call it by running `task hello` from your terminal.
|
||||
|
||||
The above example is just the start, you can take a look at the [usage](/usage)
|
||||
guide to check the full schema documentation and Task features.
|
||||
|
||||
## Features
|
||||
|
||||
- [Easy installation](/installation): just download a single binary, add to
|
||||
@@ -50,6 +32,15 @@ guide to check the full schema documentation and Task features.
|
||||
of files haven't changed since last run (based either on its timestamp or
|
||||
content).
|
||||
|
||||
## Documentation
|
||||
|
||||
- If you're new to Task, we recommend taking a look at our [getting started
|
||||
guide][getting-started] for an quick introduction.
|
||||
- You can also browse our [usage documentation][usage] for more details on how
|
||||
all the features work.
|
||||
- Or use our quick reference documentation for the [Taskfile schema][schema] or
|
||||
[CLI][cli].
|
||||
|
||||
## Gold Sponsors
|
||||
|
||||
<table class="gold-sponsors">
|
||||
@@ -70,4 +61,8 @@ guide to check the full schema documentation and Task features.
|
||||
[snapcraft]: https://snapcraft.io/
|
||||
[scoop]: https://scoop.sh/
|
||||
[sh]: https://github.com/mvdan/sh
|
||||
[getting-started]: /getting-started/
|
||||
[usage]: /usage/
|
||||
[schema]: /reference/schema/
|
||||
[cli]: /reference/cli/
|
||||
{/* prettier-ignore-end */}
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
position: 4
|
||||
position: 5
|
||||
label: Reference
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
---
|
||||
slug: /styleguide/
|
||||
sidebar_position: 10
|
||||
sidebar_position: 11
|
||||
---
|
||||
|
||||
# Style guide
|
||||
# Style Guide
|
||||
|
||||
This is the official style guide for `Taskfile.yml` files. It provides basic
|
||||
instructions for keeping your Taskfiles clean and familiar to other users.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
slug: /taskfile-versions/
|
||||
sidebar_position: 5
|
||||
sidebar_position: 6
|
||||
---
|
||||
|
||||
# Taskfile Versions
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
slug: /usage/
|
||||
sidebar_position: 3
|
||||
sidebar_position: 4
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
@@ -8,56 +8,29 @@ import TabItem from '@theme/TabItem';
|
||||
|
||||
# Usage
|
||||
|
||||
## Getting started
|
||||
## Running Taskfiles
|
||||
|
||||
Create a file called `Taskfile.yml` in the root of your project. The `cmds`
|
||||
attribute should contain the commands of a task. The example below allows
|
||||
compiling a Go app and uses [esbuild](https://esbuild.github.io/) to concat and
|
||||
minify multiple CSS files into a single one.
|
||||
Specific Taskfiles can be called by specifying the `--taskfile` flag. If you
|
||||
don't specify a Taskfile, Task will automatically look for a file with one of
|
||||
the [supported file names](#supported-file-names) in the current directory. If
|
||||
you want to search in a different directory, you can use the `--dir` flag.
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
### Supported file names
|
||||
|
||||
tasks:
|
||||
build:
|
||||
cmds:
|
||||
- go build -v -i main.go
|
||||
Task looks for files with the following names, in order of priority:
|
||||
|
||||
assets:
|
||||
cmds:
|
||||
- esbuild --bundle --minify css/index.css > public/bundle.css
|
||||
```
|
||||
- `Taskfile.yml`
|
||||
- `taskfile.yml`
|
||||
- `Taskfile.yaml`
|
||||
- `taskfile.yaml`
|
||||
- `Taskfile.dist.yml`
|
||||
- `taskfile.dist.yml`
|
||||
- `Taskfile.dist.yaml`
|
||||
- `taskfile.dist.yaml`
|
||||
|
||||
Running the tasks is as simple as running:
|
||||
|
||||
```shell
|
||||
task assets build
|
||||
```
|
||||
|
||||
Task uses [mvdan.cc/sh](https://mvdan.cc/sh/), a native Go sh interpreter. So
|
||||
you can write sh/bash commands, and it will work even on Windows, where `sh` or
|
||||
`bash` are usually not available. Just remember any executable called must be
|
||||
available by the OS or in PATH.
|
||||
|
||||
If you omit a task name, "default" will be assumed.
|
||||
|
||||
## Supported file names
|
||||
|
||||
Task will look for the following file names, in order of priority:
|
||||
|
||||
- Taskfile.yml
|
||||
- taskfile.yml
|
||||
- Taskfile.yaml
|
||||
- taskfile.yaml
|
||||
- Taskfile.dist.yml
|
||||
- taskfile.dist.yml
|
||||
- Taskfile.dist.yaml
|
||||
- taskfile.dist.yaml
|
||||
|
||||
The intention of having the `.dist` variants is to allow projects to have one
|
||||
committed version (`.dist`) while still allowing individual users to override
|
||||
the Taskfile by adding an additional `Taskfile.yml` (which would be on
|
||||
`.gitignore`).
|
||||
The `.dist` variants allow projects to have one committed file (`.dist`) while
|
||||
still allowing individual users to override the Taskfile by adding an additional
|
||||
`Taskfile.yml` (which would be in your `.gitignore`).
|
||||
|
||||
### Running a Taskfile from a subdirectory
|
||||
|
||||
@@ -263,11 +236,7 @@ Taskfile.
|
||||
|
||||
### OS-specific Taskfiles
|
||||
|
||||
With `version: '2'`, task automatically includes any `Taskfile_{{OS}}.yml` if it
|
||||
exists (for example: `Taskfile_windows.yml`, `Taskfile_linux.yml` or
|
||||
`Taskfile_darwin.yml`). Since this behavior was a bit too implicit, it was
|
||||
removed on version 3, but you still can have a similar behavior by explicitly
|
||||
importing these files:
|
||||
You can include OS-specific Taskfiles by using a templating function:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
@@ -442,7 +411,7 @@ If you run `task -a` it will print:
|
||||
task: Found multiple tasks (greet) included by "lib"
|
||||
```
|
||||
|
||||
If you the included Taskfile has a task with the same name as a task in the main Taskfile,
|
||||
If the included Taskfile has a task with the same name as a task in the main Taskfile,
|
||||
you may want to exclude it from the flattened tasks.
|
||||
|
||||
You can do this by using the [`excludes` option](#exclude-tasks-from-being-included).
|
||||
@@ -1019,28 +988,6 @@ tasks:
|
||||
- echo "I will not run"
|
||||
```
|
||||
|
||||
They can be defined at two levels:
|
||||
|
||||
- Global Level: Applies to all tasks.
|
||||
- Task Level: Applies only to a specific task.
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
preconditions:
|
||||
- sh: 'exit 1'
|
||||
|
||||
tasks:
|
||||
task-will-fail: echo "I will not run"
|
||||
```
|
||||
|
||||
:::info
|
||||
|
||||
Please note that you are not currently able to use the `preconditions` key inside
|
||||
included Taskfiles. It'll produce an error.
|
||||
|
||||
:::
|
||||
|
||||
### Limiting when tasks run
|
||||
|
||||
If a task executed by multiple `cmds` or multiple `deps` you can control when it
|
||||
@@ -1465,6 +1412,27 @@ darwin/amd64
|
||||
darwin/arm64
|
||||
```
|
||||
|
||||
You can also use references to other variables as long as they are also lists:
|
||||
|
||||
```yaml
|
||||
version: "3"
|
||||
|
||||
vars:
|
||||
OS_VAR: ["windows", "linux", "darwin"]
|
||||
ARCH_VAR: ["amd64", "arm64"]
|
||||
|
||||
tasks:
|
||||
default:
|
||||
cmds:
|
||||
- for:
|
||||
matrix:
|
||||
OS:
|
||||
ref: .OS_VAR
|
||||
ARCH:
|
||||
ref: .ARCH_VAR
|
||||
cmd: echo "{{.ITEM.OS}}/{{.ITEM.ARCH}}"
|
||||
```
|
||||
|
||||
### Looping over your task's sources
|
||||
|
||||
You are also able to loop over the sources of your task:
|
||||
|
||||
@@ -699,13 +699,6 @@
|
||||
"description": "A set of global environment variables.",
|
||||
"$ref": "#/definitions/env"
|
||||
},
|
||||
"preconditions": {
|
||||
"description": "A list of commands to check if any task should run. If a condition is not met, the task will return an error.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/precondition"
|
||||
}
|
||||
},
|
||||
"tasks": {
|
||||
"description": "A set of task definitions.",
|
||||
"$ref": "#/definitions/tasks"
|
||||
|
||||
@@ -5,6 +5,89 @@ sidebar_position: 14
|
||||
|
||||
# Changelog
|
||||
|
||||
## v3.42.0 - 2025-03-08
|
||||
|
||||
- Made `--init` less verbose by default and respect `--silent` and `--verbose`
|
||||
flags (#2009, #2011 by @HeCorr).
|
||||
- `--init` now accepts a file name or directory as an argument (#2008, #2018 by
|
||||
@HeCorr).
|
||||
- Fix a bug where an HTTP node's location was being mutated incorrectly (#2007
|
||||
by @jeongukjae).
|
||||
- Fixed a bug where allowed values didn't work with dynamic var (#2032, #2033 by
|
||||
@vmaerten).
|
||||
- Use only the relevant checker (timestamp or checksum) to improve performance
|
||||
(#2029, #2031 by @vmaerten).
|
||||
- Print warnings when attempting to enable an inactive experiment or an active
|
||||
experiment with an invalid value (#1979, #2049 by @pd93).
|
||||
- Refactored the experiments package and added tests (#2049 by @pd93).
|
||||
- Show allowed values when a variable with an enum is missing (#2027, #2052 by
|
||||
@vmaerten).
|
||||
- Refactored how snippets in error work and added tests (#2068 by @pd93).
|
||||
- Fixed a bug where errors decoding commands were sometimes unhelpful (#2068 by
|
||||
@pd93).
|
||||
- Fixed a bug in the Taskfile schema where `defer` statements in the shorthand
|
||||
`cmds` syntax were not considered valid (#2068 by @pd93).
|
||||
- Refactored how task sorting functions work (#1798 by @pd93).
|
||||
- Added a new `.taskrc.yml` (or `.taskrc.yaml`) file to let users enable
|
||||
experiments (similar to `.env`) (#1982 by @vmaerten).
|
||||
- Added new [Getting Started docs](https://taskfile.dev/getting-started) (#2086
|
||||
by @pd93).
|
||||
- Allow `matrix` to use references to other variables (#2065, #2069 by @pd93).
|
||||
- Fixed a bug where, when a dynamic variable is provided, even if it is not
|
||||
used, all other variables become unavailable in the templating system within
|
||||
the include (#2092 by @vmaerten).
|
||||
|
||||
#### Package API
|
||||
|
||||
Unlike our CLI tool,
|
||||
[Task's package API is not currently stable](https://taskfile.dev/reference/package).
|
||||
In an effort to ease the pain of breaking changes for our users, we will be
|
||||
providing changelogs for our package API going forwards. The hope is that these
|
||||
changes will provide a better long-term experience for our users and allow to
|
||||
stabilize the API in the future. #121 now tracks this piece of work.
|
||||
|
||||
- Bumped the minimum required Go version to 1.23 (#2059 by @pd93).
|
||||
- [`task.InitTaskfile`](https://pkg.go.dev/github.com/go-task/task/v3#InitTaskfile)
|
||||
(#2011, ff8c913 by @HeCorr and @pd93)
|
||||
- No longer accepts an `io.Writer` (output is now the caller's
|
||||
responsibility).
|
||||
- The path argument can now be a filename OR a directory.
|
||||
- The function now returns the full path of the generated file.
|
||||
- [`TaskfileDecodeError.WithFileInfo`](https://pkg.go.dev/github.com/go-task/task/v3/errors#TaskfileDecodeError.WithFileInfo)
|
||||
now accepts a string instead of the arguments required to generate a snippet
|
||||
(#2068 by @pd93).
|
||||
- The caller is now expected to create the snippet themselves (see below).
|
||||
- [`TaskfileSnippet`](https://pkg.go.dev/github.com/go-task/task/v3/taskfile#Snippet)
|
||||
and related code moved from the `errors` package to the `taskfile` package
|
||||
(#2068 by @pd93).
|
||||
- Renamed `TaskMissingRequiredVars` to
|
||||
[`TaskMissingRequiredVarsError`](https://pkg.go.dev/github.com/go-task/task/v3/errors#TaskMissingRequiredVarsError)
|
||||
(#2052 by @vmaerten).
|
||||
- Renamed `TaskNotAllowedVars` to
|
||||
[`TaskNotAllowedVarsError`](https://pkg.go.dev/github.com/go-task/task/v3/errors#TaskNotAllowedVarsError)
|
||||
(#2052 by @vmaerten).
|
||||
- The
|
||||
[`taskfile.Reader`](https://pkg.go.dev/github.com/go-task/task/v3/taskfile#Reader)
|
||||
is now constructed using the functional options pattern (#2082 by @pd93).
|
||||
- Removed our internal `logger.Logger` from the entire `taskfile` package (#2082
|
||||
by @pd93).
|
||||
- Users are now expected to pass a custom debug/prompt functions into
|
||||
[`taskfile.Reader`](https://pkg.go.dev/github.com/go-task/task/v3/taskfile#Reader)
|
||||
if they want this functionality by using the new
|
||||
[`WithDebugFunc`](https://pkg.go.dev/github.com/go-task/task/v3/taskfile#WithDebugFunc)
|
||||
and
|
||||
[`WithPromptFunc`](https://pkg.go.dev/github.com/go-task/task/v3/taskfile#WithPromptFunc)
|
||||
functional options.
|
||||
- Remove `Range` functions in the `taskfile/ast` package in favour of new
|
||||
iterator functions (#1798 by @pd93).
|
||||
- `ast.Call` was moved from the `taskfile/ast` package to the main `task`
|
||||
package (#2084 by @pd93).
|
||||
- `ast.Tasks.FindMatchingTasks` was moved from the `taskfile/ast` package to the
|
||||
`task.Executor.FindMatchingTasks` in the main `task` package (#2084 by @pd93).
|
||||
- The `Compiler` and its `GetVariables` and `FastGetVariables` methods were
|
||||
moved from the `internal/compiler` package to the main `task` package (#2084
|
||||
by @pd93).
|
||||
|
||||
## v3.41.0 - 2025-01-18
|
||||
|
||||
- Fixed an issue where dynamic variables were not properly logged in verbose
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
slug: /community/
|
||||
sidebar_position: 9
|
||||
sidebar_position: 10
|
||||
---
|
||||
|
||||
# Community
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
slug: /contributing/
|
||||
sidebar_position: 11
|
||||
sidebar_position: 12
|
||||
---
|
||||
|
||||
# Contributing
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
slug: /deprecations/
|
||||
sidebar_position: 7
|
||||
sidebar_position: 8
|
||||
---
|
||||
|
||||
# Deprecations
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
---
|
||||
slug: /experiments/
|
||||
sidebar_position: 6
|
||||
sidebar_position: 7
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# Experiments
|
||||
|
||||
:::caution
|
||||
@@ -39,7 +42,7 @@ Which method you use depends on how you intend to use the experiment:
|
||||
1. Prefixing your task commands with the relevant environment variable(s). For
|
||||
example, `TASK_X_{FEATURE}=1 task {my-task}`. This is intended for one-off
|
||||
invocations of Task to test out experimental features.
|
||||
1. Adding the relevant environment variable(s) in your "dotfiles" (e.g.
|
||||
2. Adding the relevant environment variable(s) in your "dotfiles" (e.g.
|
||||
`.bashrc`, `.zshrc` etc.). This will permanently enable experimental features
|
||||
for your personal environment.
|
||||
|
||||
@@ -47,15 +50,33 @@ Which method you use depends on how you intend to use the experiment:
|
||||
export TASK_X_FEATURE=1
|
||||
```
|
||||
|
||||
1. Creating a `.env` file in the same directory as your root Taskfile that
|
||||
contains the relevant environment variable(s). This allows you to enable an
|
||||
experimental feature at a project level. If you commit the `.env` file to
|
||||
source control then other users of your project will also have these
|
||||
experiments enabled.
|
||||
3. Creating a `.env` or a `.task-experiments.yml` file in the same directory as
|
||||
your root Taskfile.\
|
||||
The `.env` file should contain the relevant environment
|
||||
variable(s), while the `.task-experiments.yml` file should use a YAML format
|
||||
where each experiment is defined as a key with a corresponding value.
|
||||
|
||||
```shell title=".env"
|
||||
TASK_X_FEATURE=1
|
||||
```
|
||||
This allows you to enable an experimental feature at a project level. If you
|
||||
commit this file to source control, then other users of your project will
|
||||
also have these experiments enabled.
|
||||
|
||||
If both files are present, the values in the `.task-experiments.yml` file
|
||||
will take precedence.
|
||||
|
||||
<Tabs values={[ {label: '.task-experiments.yml', value: 'yaml'}, {label: '.env', value: 'env'}]}>
|
||||
<TabItem value="yaml">
|
||||
```yaml title=".taskrc.yml"
|
||||
experiments:
|
||||
FEATURE: 1
|
||||
```
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="env">
|
||||
```shell title=".env"
|
||||
TASK_X_FEATURE=1
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Workflow
|
||||
|
||||
|
||||
143
website/versioned_docs/version-latest/getting_started.mdx
Normal file
143
website/versioned_docs/version-latest/getting_started.mdx
Normal file
@@ -0,0 +1,143 @@
|
||||
---
|
||||
slug: /getting-started/
|
||||
sidebar_position: 3
|
||||
---
|
||||
|
||||
# Getting Started
|
||||
|
||||
The following guide will help introduce you to the basics of Task. We'll cover
|
||||
how to create a Taskfile, how to write a basic task and how to call it. If you
|
||||
haven't installed Task yet, head over to our [installation
|
||||
guide][installation].
|
||||
|
||||
## Creating your first Taskfile
|
||||
|
||||
Once Task is installed, you can create your first Taskfile by running:
|
||||
|
||||
```shell
|
||||
task --init
|
||||
```
|
||||
|
||||
This will create a file called `Taskfile.yml` in the current directory. If you
|
||||
want to create the file in another directory, you can pass an absolute or
|
||||
relative path to the directory into the command:
|
||||
|
||||
```shell
|
||||
task --init ./subdirectory
|
||||
```
|
||||
|
||||
Or if you want the Taskfile to have a specific name, you can pass in the name of
|
||||
the file:
|
||||
|
||||
```shell
|
||||
task --init Custom.yml
|
||||
```
|
||||
|
||||
This will create a Taskfile that looks something like this:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
vars:
|
||||
GREETING: Hello, World!
|
||||
|
||||
tasks:
|
||||
default:
|
||||
cmds:
|
||||
- echo "{{.GREETING}}"
|
||||
silent: true
|
||||
```
|
||||
|
||||
As you can see, all Taskfiles are written in [YAML format][yaml]. The `version`
|
||||
attribute specifies the minimum version of Task that can be used to run this
|
||||
file. The `vars` attribute is used to define variables that can be used in
|
||||
tasks. In this case, we are creating a string variable called `GREETING` with a
|
||||
value of `Hello, World!`.
|
||||
|
||||
Finally, the `tasks` attribute is used to define the tasks that can be run. In
|
||||
this case, we have a task called `default` that echoes the value of the
|
||||
`GREETING` variable. The `silent` attribute is set to `true`, which means that
|
||||
the task metadata will not be printed when the task is run - only the output of
|
||||
the commands.
|
||||
|
||||
## Calling a task
|
||||
|
||||
To call the task, you simply invoke `task` followed by the name of the task you
|
||||
want to run. In this case, the name of the task is `default`, so you should run:
|
||||
|
||||
```shell
|
||||
task default
|
||||
```
|
||||
|
||||
Note that we don't have to specify the name of the Taskfile. Task will
|
||||
automatically look for a file called `Taskfile.yml` (or any of Task's [supported
|
||||
file names][supported-file-names]) in the current directory. Additionally, tasks
|
||||
with the name `default` are special. They can also be run without specifying the
|
||||
task name.
|
||||
|
||||
If you created a Taskfile in a different directory, you can run it by passing
|
||||
the absolute or relative path to the directory as an argument using the `--dir`
|
||||
flag:
|
||||
|
||||
```shell
|
||||
task --dir ./subdirectory
|
||||
```
|
||||
|
||||
Or if you created a Taskfile with a different name, you can run it by passing
|
||||
the name of the Taskfile as an argument using the `--taskfile` flag:
|
||||
|
||||
```shell
|
||||
task --taskfile Custom.yml
|
||||
```
|
||||
|
||||
## Adding a build task
|
||||
|
||||
Let's create a task to build a program in Go. Start by adding a new task called
|
||||
`build` below the existing `default` task. We can then add a `cmds` attribute
|
||||
with a single command to build the program.
|
||||
|
||||
Task uses [mvdan/sh][mvdan/sh], a native Go sh interpreter. So you can write
|
||||
sh/bash-like commands - even in environments where `sh` or `bash` are usually
|
||||
not available (like Windows). Just remember any executables called must be
|
||||
available as a built-in or in the system's `PATH`.
|
||||
|
||||
When you're done, it should look something like this:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
vars:
|
||||
GREETING: Hello, World!
|
||||
|
||||
tasks:
|
||||
default:
|
||||
cmds:
|
||||
- echo "{{.GREETING}}"
|
||||
silent: true
|
||||
|
||||
build:
|
||||
cmds:
|
||||
- go build ./cmd/main.go
|
||||
```
|
||||
|
||||
Call the task by running:
|
||||
|
||||
```shell
|
||||
task build
|
||||
```
|
||||
|
||||
That's about it for the basics, but there's _so much_ more that you can do with
|
||||
Task. Check out the rest of the documentation to learn more about all the
|
||||
features Task has to offer! We recommend taking a look at the [usage
|
||||
guide][usage] next. Alternatively, you can check out our reference docs for the
|
||||
[Taskfile schema][schema] and [CLI][cli].
|
||||
|
||||
{/* prettier-ignore-start */}
|
||||
[yaml]: https://yaml.org/
|
||||
[installation]: /installation/
|
||||
[supported-file-names]: /usage/#supported-file-names
|
||||
[mvdan/sh]: https://github.com/mvdan/sh
|
||||
[usage]: /usage/
|
||||
[schema]: /reference/schema/
|
||||
[cli]: /reference/cli/
|
||||
{/* prettier-ignore-end */}
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
slug: /integrations/
|
||||
sidebar_position: 8
|
||||
sidebar_position: 9
|
||||
---
|
||||
|
||||
# Integrations
|
||||
|
||||
@@ -17,24 +17,6 @@ Since it's written in [Go][go], Task is just a single binary and has no other
|
||||
dependencies, which means you don't need to mess with any complicated install
|
||||
setups just to use a build tool.
|
||||
|
||||
Once [installed](/installation), you just need to describe your build tasks
|
||||
using a simple [YAML][yaml] schema in a file called `Taskfile.yml`:
|
||||
|
||||
```yaml title="Taskfile.yml"
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
hello:
|
||||
cmds:
|
||||
- echo 'Hello World from Task!'
|
||||
silent: true
|
||||
```
|
||||
|
||||
And call it by running `task hello` from your terminal.
|
||||
|
||||
The above example is just the start, you can take a look at the [usage](/usage)
|
||||
guide to check the full schema documentation and Task features.
|
||||
|
||||
## Features
|
||||
|
||||
- [Easy installation](/installation): just download a single binary, add to
|
||||
@@ -50,6 +32,15 @@ guide to check the full schema documentation and Task features.
|
||||
of files haven't changed since last run (based either on its timestamp or
|
||||
content).
|
||||
|
||||
## Documentation
|
||||
|
||||
- If you're new to Task, we recommend taking a look at our [getting started
|
||||
guide][getting-started] for an quick introduction.
|
||||
- You can also browse our [usage documentation][usage] for more details on how
|
||||
all the features work.
|
||||
- Or use our quick reference documentation for the [Taskfile schema][schema] or
|
||||
[CLI][cli].
|
||||
|
||||
## Gold Sponsors
|
||||
|
||||
<table class="gold-sponsors">
|
||||
@@ -70,4 +61,8 @@ guide to check the full schema documentation and Task features.
|
||||
[snapcraft]: https://snapcraft.io/
|
||||
[scoop]: https://scoop.sh/
|
||||
[sh]: https://github.com/mvdan/sh
|
||||
[getting-started]: /getting-started/
|
||||
[usage]: /usage/
|
||||
[schema]: /reference/schema/
|
||||
[cli]: /reference/cli/
|
||||
{/* prettier-ignore-end */}
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
position: 4
|
||||
position: 5
|
||||
label: Reference
|
||||
|
||||
@@ -16,10 +16,10 @@ task [--flags] [tasks...] [-- CLI_ARGS...]
|
||||
If `--` is given, all remaining arguments will be assigned to a special
|
||||
`CLI_ARGS` variable
|
||||
|
||||
## Flags
|
||||
|
||||
:::
|
||||
|
||||
## Flags
|
||||
|
||||
| Short | Flag | Type | Default | Description |
|
||||
| ----- | --------------------------- | -------- | -------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `-c` | `--color` | `bool` | `true` | Colored output. Enabled by default. Set flag to `false` or use `NO_COLOR=1` to disable. |
|
||||
@@ -45,7 +45,7 @@ If `--` is given, all remaining arguments will be assigned to a special
|
||||
| `-y` | `--yes` | `bool` | `false` | Assume "yes" as answer to all prompts. |
|
||||
| | `--status` | `bool` | `false` | Exits with non-zero exit code if any of the given tasks is not up-to-date. |
|
||||
| | `--summary` | `bool` | `false` | Show summary about a task. |
|
||||
| `-t` | `--taskfile` | `string` | `Taskfile.yml` or `Taskfile.yaml` | |
|
||||
| `-t` | `--taskfile` | `string` | | Taskfile path to run.<br />Check the list of default filenames [here](../usage/#supported-file-names). |
|
||||
| `-v` | `--verbose` | `bool` | `false` | Enables verbose mode. |
|
||||
| | `--version` | `bool` | `false` | Show Task version. |
|
||||
| `-w` | `--watch` | `bool` | `false` | Enables watch of the given task.
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
---
|
||||
slug: /styleguide/
|
||||
sidebar_position: 10
|
||||
sidebar_position: 11
|
||||
---
|
||||
|
||||
# Style guide
|
||||
# Style Guide
|
||||
|
||||
This is the official style guide for `Taskfile.yml` files. It provides basic
|
||||
instructions for keeping your Taskfiles clean and familiar to other users.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
slug: /taskfile-versions/
|
||||
sidebar_position: 5
|
||||
sidebar_position: 6
|
||||
---
|
||||
|
||||
# Taskfile Versions
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
slug: /usage/
|
||||
sidebar_position: 3
|
||||
sidebar_position: 4
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
@@ -8,56 +8,29 @@ import TabItem from '@theme/TabItem';
|
||||
|
||||
# Usage
|
||||
|
||||
## Getting started
|
||||
## Running Taskfiles
|
||||
|
||||
Create a file called `Taskfile.yml` in the root of your project. The `cmds`
|
||||
attribute should contain the commands of a task. The example below allows
|
||||
compiling a Go app and uses [esbuild](https://esbuild.github.io/) to concat and
|
||||
minify multiple CSS files into a single one.
|
||||
Specific Taskfiles can be called by specifying the `--taskfile` flag. If you
|
||||
don't specify a Taskfile, Task will automatically look for a file with one of
|
||||
the [supported file names](#supported-file-names) in the current directory. If
|
||||
you want to search in a different directory, you can use the `--dir` flag.
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
### Supported file names
|
||||
|
||||
tasks:
|
||||
build:
|
||||
cmds:
|
||||
- go build -v -i main.go
|
||||
Task looks for files with the following names, in order of priority:
|
||||
|
||||
assets:
|
||||
cmds:
|
||||
- esbuild --bundle --minify css/index.css > public/bundle.css
|
||||
```
|
||||
- `Taskfile.yml`
|
||||
- `taskfile.yml`
|
||||
- `Taskfile.yaml`
|
||||
- `taskfile.yaml`
|
||||
- `Taskfile.dist.yml`
|
||||
- `taskfile.dist.yml`
|
||||
- `Taskfile.dist.yaml`
|
||||
- `taskfile.dist.yaml`
|
||||
|
||||
Running the tasks is as simple as running:
|
||||
|
||||
```shell
|
||||
task assets build
|
||||
```
|
||||
|
||||
Task uses [mvdan.cc/sh](https://mvdan.cc/sh/), a native Go sh interpreter. So
|
||||
you can write sh/bash commands, and it will work even on Windows, where `sh` or
|
||||
`bash` are usually not available. Just remember any executable called must be
|
||||
available by the OS or in PATH.
|
||||
|
||||
If you omit a task name, "default" will be assumed.
|
||||
|
||||
## Supported file names
|
||||
|
||||
Task will look for the following file names, in order of priority:
|
||||
|
||||
- Taskfile.yml
|
||||
- taskfile.yml
|
||||
- Taskfile.yaml
|
||||
- taskfile.yaml
|
||||
- Taskfile.dist.yml
|
||||
- taskfile.dist.yml
|
||||
- Taskfile.dist.yaml
|
||||
- taskfile.dist.yaml
|
||||
|
||||
The intention of having the `.dist` variants is to allow projects to have one
|
||||
committed version (`.dist`) while still allowing individual users to override
|
||||
the Taskfile by adding an additional `Taskfile.yml` (which would be on
|
||||
`.gitignore`).
|
||||
The `.dist` variants allow projects to have one committed file (`.dist`) while
|
||||
still allowing individual users to override the Taskfile by adding an additional
|
||||
`Taskfile.yml` (which would be in your `.gitignore`).
|
||||
|
||||
### Running a Taskfile from a subdirectory
|
||||
|
||||
@@ -263,11 +236,7 @@ Taskfile.
|
||||
|
||||
### OS-specific Taskfiles
|
||||
|
||||
With `version: '2'`, task automatically includes any `Taskfile_{{OS}}.yml` if it
|
||||
exists (for example: `Taskfile_windows.yml`, `Taskfile_linux.yml` or
|
||||
`Taskfile_darwin.yml`). Since this behavior was a bit too implicit, it was
|
||||
removed on version 3, but you still can have a similar behavior by explicitly
|
||||
importing these files:
|
||||
You can include OS-specific Taskfiles by using a templating function:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
@@ -442,7 +411,7 @@ If you run `task -a` it will print:
|
||||
task: Found multiple tasks (greet) included by "lib"
|
||||
```
|
||||
|
||||
If you the included Taskfile has a task with the same name as a task in the main Taskfile,
|
||||
If the included Taskfile has a task with the same name as a task in the main Taskfile,
|
||||
you may want to exclude it from the flattened tasks.
|
||||
|
||||
You can do this by using the [`excludes` option](#exclude-tasks-from-being-included).
|
||||
@@ -1443,6 +1412,27 @@ darwin/amd64
|
||||
darwin/arm64
|
||||
```
|
||||
|
||||
You can also use references to other variables as long as they are also lists:
|
||||
|
||||
```yaml
|
||||
version: "3"
|
||||
|
||||
vars:
|
||||
OS_VAR: ["windows", "linux", "darwin"]
|
||||
ARCH_VAR: ["amd64", "arm64"]
|
||||
|
||||
tasks:
|
||||
default:
|
||||
cmds:
|
||||
- for:
|
||||
matrix:
|
||||
OS:
|
||||
ref: .OS_VAR
|
||||
ARCH:
|
||||
ref: .ARCH_VAR
|
||||
cmd: echo "{{.ITEM.OS}}/{{.ITEM.ARCH}}"
|
||||
```
|
||||
|
||||
### Looping over your task's sources
|
||||
|
||||
You are also able to loop over the sources of your task:
|
||||
|
||||
@@ -2437,9 +2437,9 @@
|
||||
"@types/react" "*"
|
||||
|
||||
"@types/react@*", "@types/react@^19.0.0":
|
||||
version "19.0.8"
|
||||
resolved "https://registry.yarnpkg.com/@types/react/-/react-19.0.8.tgz#7098e6159f2a61e4f4cef2c1223c044a9bec590e"
|
||||
integrity sha512-9P/o1IGdfmQxrujGbIMDyYaaCykhLKc0NGCtYcECNUr9UAaDe4gwvV9bR6tvd5Br1SG0j+PBpbKr2UYY8CwqSw==
|
||||
version "19.0.10"
|
||||
resolved "https://registry.yarnpkg.com/@types/react/-/react-19.0.10.tgz#d0c66dafd862474190fe95ce11a68de69ed2b0eb"
|
||||
integrity sha512-JuRQ9KXLEjaUNjTWpzuR231Z2WpIwczOkBEIvbHNCzQefFIT0L8IqE6NV6ULLyC1SI/i234JnDoMkfg+RjQj2g==
|
||||
dependencies:
|
||||
csstype "^3.0.2"
|
||||
|
||||
@@ -5497,9 +5497,9 @@ markdown-table@^2.0.0:
|
||||
repeat-string "^1.0.0"
|
||||
|
||||
markdown-table@^3.0.0:
|
||||
version "3.0.3"
|
||||
resolved "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.3.tgz"
|
||||
integrity sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw==
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/markdown-table/-/markdown-table-3.0.4.tgz#fe44d6d410ff9d6f2ea1797a3f60aa4d2b631c2a"
|
||||
integrity sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==
|
||||
|
||||
math-intrinsics@^1.1.0:
|
||||
version "1.1.0"
|
||||
@@ -5521,17 +5521,7 @@ mdast-util-directive@^3.0.0:
|
||||
stringify-entities "^4.0.0"
|
||||
unist-util-visit-parents "^6.0.0"
|
||||
|
||||
mdast-util-find-and-replace@^3.0.0:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.1.tgz"
|
||||
integrity sha512-SG21kZHGC3XRTSUhtofZkBzZTJNM5ecCi0SK2IMKmSXR8vO3peL+kb1O0z7Zl83jKtutG4k5Wv/W7V3/YHvzPA==
|
||||
dependencies:
|
||||
"@types/mdast" "^4.0.0"
|
||||
escape-string-regexp "^5.0.0"
|
||||
unist-util-is "^6.0.0"
|
||||
unist-util-visit-parents "^6.0.0"
|
||||
|
||||
mdast-util-find-and-replace@^3.0.1:
|
||||
mdast-util-find-and-replace@^3.0.0, mdast-util-find-and-replace@^3.0.1:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.2.tgz#70a3174c894e14df722abf43bc250cbae44b11df"
|
||||
integrity sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==
|
||||
@@ -5572,9 +5562,9 @@ mdast-util-frontmatter@^2.0.0:
|
||||
micromark-extension-frontmatter "^2.0.0"
|
||||
|
||||
mdast-util-gfm-autolink-literal@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.0.tgz"
|
||||
integrity sha512-FyzMsduZZHSc3i0Px3PQcBT4WJY/X/RCtEJKuybiC6sjPqLv7h1yqAkmILZtuxMSsUyaLUWNp71+vQH2zqp5cg==
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.1.tgz#abd557630337bd30a6d5a4bd8252e1c2dc0875d5"
|
||||
integrity sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==
|
||||
dependencies:
|
||||
"@types/mdast" "^4.0.0"
|
||||
ccount "^2.0.0"
|
||||
@@ -5583,9 +5573,9 @@ mdast-util-gfm-autolink-literal@^2.0.0:
|
||||
micromark-util-character "^2.0.0"
|
||||
|
||||
mdast-util-gfm-footnote@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.0.0.tgz"
|
||||
integrity sha512-5jOT2boTSVkMnQ7LTrd6n/18kqwjmuYqo7JUPe+tRCY6O7dAuTFMtTPauYYrMPpox9hlN0uOx/FL8XvEfG9/mQ==
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.1.0.tgz#7778e9d9ca3df7238cc2bd3fa2b1bf6a65b19403"
|
||||
integrity sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==
|
||||
dependencies:
|
||||
"@types/mdast" "^4.0.0"
|
||||
devlop "^1.1.0"
|
||||
@@ -5595,7 +5585,7 @@ mdast-util-gfm-footnote@^2.0.0:
|
||||
|
||||
mdast-util-gfm-strikethrough@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz"
|
||||
resolved "https://registry.yarnpkg.com/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz#d44ef9e8ed283ac8c1165ab0d0dfd058c2764c16"
|
||||
integrity sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==
|
||||
dependencies:
|
||||
"@types/mdast" "^4.0.0"
|
||||
@@ -5604,7 +5594,7 @@ mdast-util-gfm-strikethrough@^2.0.0:
|
||||
|
||||
mdast-util-gfm-table@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz"
|
||||
resolved "https://registry.yarnpkg.com/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz#7a435fb6223a72b0862b33afbd712b6dae878d38"
|
||||
integrity sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==
|
||||
dependencies:
|
||||
"@types/mdast" "^4.0.0"
|
||||
@@ -5615,7 +5605,7 @@ mdast-util-gfm-table@^2.0.0:
|
||||
|
||||
mdast-util-gfm-task-list-item@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz"
|
||||
resolved "https://registry.yarnpkg.com/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz#e68095d2f8a4303ef24094ab642e1047b991a936"
|
||||
integrity sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==
|
||||
dependencies:
|
||||
"@types/mdast" "^4.0.0"
|
||||
@@ -5624,9 +5614,9 @@ mdast-util-gfm-task-list-item@^2.0.0:
|
||||
mdast-util-to-markdown "^2.0.0"
|
||||
|
||||
mdast-util-gfm@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.0.0.tgz"
|
||||
integrity sha512-dgQEX5Amaq+DuUqf26jJqSK9qgixgd6rYDHAv4aTBuA92cTknZlKpPfa86Z/s8Dj8xsAQpFfBmPUHWJBWqS4Bw==
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/mdast-util-gfm/-/mdast-util-gfm-3.1.0.tgz#2cdf63b92c2a331406b0fb0db4c077c1b0331751"
|
||||
integrity sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==
|
||||
dependencies:
|
||||
mdast-util-from-markdown "^2.0.0"
|
||||
mdast-util-gfm-autolink-literal "^2.0.0"
|
||||
@@ -5822,9 +5812,9 @@ micromark-extension-frontmatter@^2.0.0:
|
||||
micromark-util-types "^2.0.0"
|
||||
|
||||
micromark-extension-gfm-autolink-literal@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.0.0.tgz"
|
||||
integrity sha512-rTHfnpt/Q7dEAK1Y5ii0W8bhfJlVJFnJMHIPisfPK3gpVNuOP0VnRl96+YJ3RYWV/P4gFeQoGKNlT3RhuvpqAg==
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz#6286aee9686c4462c1e3552a9d505feddceeb935"
|
||||
integrity sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==
|
||||
dependencies:
|
||||
micromark-util-character "^2.0.0"
|
||||
micromark-util-sanitize-uri "^2.0.0"
|
||||
@@ -5832,9 +5822,9 @@ micromark-extension-gfm-autolink-literal@^2.0.0:
|
||||
micromark-util-types "^2.0.0"
|
||||
|
||||
micromark-extension-gfm-footnote@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.0.0.tgz"
|
||||
integrity sha512-6Rzu0CYRKDv3BfLAUnZsSlzx3ak6HAoI85KTiijuKIz5UxZxbUI+pD6oHgw+6UtQuiRwnGRhzMmPRv4smcz0fg==
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz#4dab56d4e398b9853f6fe4efac4fc9361f3e0750"
|
||||
integrity sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==
|
||||
dependencies:
|
||||
devlop "^1.0.0"
|
||||
micromark-core-commonmark "^2.0.0"
|
||||
@@ -5846,9 +5836,9 @@ micromark-extension-gfm-footnote@^2.0.0:
|
||||
micromark-util-types "^2.0.0"
|
||||
|
||||
micromark-extension-gfm-strikethrough@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.0.0.tgz"
|
||||
integrity sha512-c3BR1ClMp5fxxmwP6AoOY2fXO9U8uFMKs4ADD66ahLTNcwzSCyRVU4k7LPV5Nxo/VJiR4TdzxRQY2v3qIUceCw==
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.1.0.tgz#86106df8b3a692b5f6a92280d3879be6be46d923"
|
||||
integrity sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==
|
||||
dependencies:
|
||||
devlop "^1.0.0"
|
||||
micromark-util-chunked "^2.0.0"
|
||||
@@ -5858,9 +5848,9 @@ micromark-extension-gfm-strikethrough@^2.0.0:
|
||||
micromark-util-types "^2.0.0"
|
||||
|
||||
micromark-extension-gfm-table@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.0.0.tgz"
|
||||
integrity sha512-PoHlhypg1ItIucOaHmKE8fbin3vTLpDOUg8KAr8gRCF1MOZI9Nquq2i/44wFvviM4WuxJzc3demT8Y3dkfvYrw==
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.1.tgz#fac70bcbf51fe65f5f44033118d39be8a9b5940b"
|
||||
integrity sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==
|
||||
dependencies:
|
||||
devlop "^1.0.0"
|
||||
micromark-factory-space "^2.0.0"
|
||||
@@ -5870,15 +5860,15 @@ micromark-extension-gfm-table@^2.0.0:
|
||||
|
||||
micromark-extension-gfm-tagfilter@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz"
|
||||
resolved "https://registry.yarnpkg.com/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz#f26d8a7807b5985fba13cf61465b58ca5ff7dc57"
|
||||
integrity sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==
|
||||
dependencies:
|
||||
micromark-util-types "^2.0.0"
|
||||
|
||||
micromark-extension-gfm-task-list-item@^2.0.0:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.0.1.tgz"
|
||||
integrity sha512-cY5PzGcnULaN5O7T+cOzfMoHjBW7j+T9D2sucA5d/KbsBTPcYdebm9zUd9zzdgJGCwahV+/W78Z3nbulBYVbTw==
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.1.0.tgz#bcc34d805639829990ec175c3eea12bb5b781f2c"
|
||||
integrity sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==
|
||||
dependencies:
|
||||
devlop "^1.0.0"
|
||||
micromark-factory-space "^2.0.0"
|
||||
@@ -5888,7 +5878,7 @@ micromark-extension-gfm-task-list-item@^2.0.0:
|
||||
|
||||
micromark-extension-gfm@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz"
|
||||
resolved "https://registry.yarnpkg.com/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz#3e13376ab95dd7a5cfd0e29560dfe999657b3c5b"
|
||||
integrity sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==
|
||||
dependencies:
|
||||
micromark-extension-gfm-autolink-literal "^2.0.0"
|
||||
@@ -7720,9 +7710,9 @@ remark-frontmatter@^5.0.0:
|
||||
unified "^11.0.0"
|
||||
|
||||
remark-gfm@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.0.tgz"
|
||||
integrity sha512-U92vJgBPkbw4Zfu/IiW2oTZLSL3Zpv+uI7My2eq8JxKgqraFdU8YUGicEJCEgSbeaG+QDFqIcwwfMTOEelPxuA==
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/remark-gfm/-/remark-gfm-4.0.1.tgz#33227b2a74397670d357bf05c098eaf8513f0d6b"
|
||||
integrity sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==
|
||||
dependencies:
|
||||
"@types/mdast" "^4.0.0"
|
||||
mdast-util-gfm "^3.0.0"
|
||||
@@ -7774,7 +7764,7 @@ remark-rehype@^11.0.0:
|
||||
|
||||
remark-stringify@^11.0.0:
|
||||
version "11.0.0"
|
||||
resolved "https://registry.npmjs.org/remark-stringify/-/remark-stringify-11.0.0.tgz"
|
||||
resolved "https://registry.yarnpkg.com/remark-stringify/-/remark-stringify-11.0.0.tgz#4c5b01dd711c269df1aaae11743eb7e2e7636fd3"
|
||||
integrity sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==
|
||||
dependencies:
|
||||
"@types/mdast" "^4.0.0"
|
||||
@@ -8530,9 +8520,9 @@ typedarray-to-buffer@^3.1.5:
|
||||
is-typedarray "^1.0.0"
|
||||
|
||||
typescript@^5.3.3:
|
||||
version "5.7.3"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.7.3.tgz#919b44a7dbb8583a9b856d162be24a54bf80073e"
|
||||
integrity sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==
|
||||
version "5.8.2"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.8.2.tgz#8170b3702f74b79db2e5a96207c15e65807999e4"
|
||||
integrity sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==
|
||||
|
||||
undici-types@~6.20.0:
|
||||
version "6.20.0"
|
||||
|
||||
Reference in New Issue
Block a user