mirror of
https://github.com/go-task/task.git
synced 2026-06-21 14:51:39 +00:00
Compare commits
31 Commits
v3.44.0
...
split-exec
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5128a98ee2 | ||
|
|
8353dffc7a | ||
|
|
6e80b401e6 | ||
|
|
1402e2baaf | ||
|
|
4b99f60039 | ||
|
|
4bdfe5ce3b | ||
|
|
26ef693417 | ||
|
|
952f32d388 | ||
|
|
e72c35f79f | ||
|
|
72991d4f04 | ||
|
|
6f965e3043 | ||
|
|
1c6d686356 | ||
|
|
dac5aa1954 | ||
|
|
303bd6ccb2 | ||
|
|
f736cfaaf1 | ||
|
|
53f97889bc | ||
|
|
fe2da74ea3 | ||
|
|
64fb66895b | ||
|
|
d2bd834c81 | ||
|
|
8a43ca5d8f | ||
|
|
a10a9faabf | ||
|
|
3d3ed0e403 | ||
|
|
47dc87a2c9 | ||
|
|
3b0a746f85 | ||
|
|
281edfe5b3 | ||
|
|
7289ffce0b | ||
|
|
61e1af50ff | ||
|
|
715a143735 | ||
|
|
a0b1605634 | ||
|
|
69fc13bd13 | ||
|
|
b42a52ba77 |
29
.github/workflows/release-nightly.yml
vendored
Normal file
29
.github/workflows/release-nightly.yml
vendored
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
name: Realease nightly
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
schedule:
|
||||||
|
- cron: 0 0 * * *
|
||||||
|
jobs:
|
||||||
|
goreleaser:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Set up Go
|
||||||
|
uses: actions/setup-go@v5
|
||||||
|
with:
|
||||||
|
go-version: 1.24.x
|
||||||
|
|
||||||
|
- name: Run GoReleaser
|
||||||
|
uses: goreleaser/goreleaser-action@v6
|
||||||
|
with:
|
||||||
|
distribution: goreleaser-pro
|
||||||
|
version: latest
|
||||||
|
args: release --clean --nightly -f .goreleaser-nightly.yml
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{secrets.GH_PAT}}
|
||||||
|
GORELEASER_KEY: ${{secrets.GORELEASER_KEY}}
|
||||||
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
@@ -24,7 +24,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
distribution: goreleaser-pro
|
distribution: goreleaser-pro
|
||||||
version: latest
|
version: latest
|
||||||
args: release --clean
|
args: release --clean --draft
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{secrets.GH_PAT}}
|
GITHUB_TOKEN: ${{secrets.GH_PAT}}
|
||||||
GORELEASER_KEY: ${{secrets.GORELEASER_KEY}}
|
GORELEASER_KEY: ${{secrets.GORELEASER_KEY}}
|
||||||
|
|||||||
15
.goreleaser-nightly.yml
Normal file
15
.goreleaser-nightly.yml
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
# yaml-language-server: $schema=https://goreleaser.com/static/schema.json
|
||||||
|
version: 2
|
||||||
|
pro: true
|
||||||
|
|
||||||
|
release:
|
||||||
|
name_template: 'v{{.Version}}'
|
||||||
|
|
||||||
|
nightly:
|
||||||
|
publish_release: true
|
||||||
|
keep_single_release: true
|
||||||
|
version_template: "{{incminor .Version}}-nightly"
|
||||||
|
|
||||||
|
includes:
|
||||||
|
- from_file:
|
||||||
|
path: ./.goreleaser.yml
|
||||||
@@ -30,13 +30,14 @@ builds:
|
|||||||
flags:
|
flags:
|
||||||
- -trimpath
|
- -trimpath
|
||||||
ldflags:
|
ldflags:
|
||||||
- -s -w # Don't set main.version.
|
- "-s -w"
|
||||||
|
- "{{if .IsNightly}}-X github.com/go-task/task/v3/internal/version.version={{.Version}}{{end}}"
|
||||||
|
|
||||||
gomod:
|
gomod:
|
||||||
proxy: true
|
proxy: true
|
||||||
|
|
||||||
archives:
|
archives:
|
||||||
- name_template: "{{.Binary}}_{{.Os}}_{{.Arch}}"
|
- name_template: '{{.Binary}}_{{.Os}}_{{.Arch}}'
|
||||||
files:
|
files:
|
||||||
- README.md
|
- README.md
|
||||||
- LICENSE
|
- LICENSE
|
||||||
@@ -45,27 +46,29 @@ archives:
|
|||||||
- goos: windows
|
- goos: windows
|
||||||
formats: [zip]
|
formats: [zip]
|
||||||
|
|
||||||
release:
|
git:
|
||||||
draft: true
|
ignore_tags:
|
||||||
|
- "{{if not .IsNightly}}nightly{{end}}"
|
||||||
|
|
||||||
snapshot:
|
snapshot:
|
||||||
version_template: "{{.Version}}"
|
version_template: '{{.Version}}'
|
||||||
|
|
||||||
checksum:
|
checksum:
|
||||||
name_template: "task_checksums.txt"
|
name_template: 'task_checksums.txt'
|
||||||
|
|
||||||
nfpms:
|
nfpms:
|
||||||
- vendor: Task
|
- vendor: Task
|
||||||
homepage: https://taskfile.dev
|
homepage: https://taskfile.dev
|
||||||
maintainer: The Task authors <task@taskfile.dev>
|
maintainer: The Task authors <task@taskfile.dev>
|
||||||
description: Simple task runner written in Go
|
description: Simple task runner written in Go
|
||||||
|
section: golang
|
||||||
license: MIT
|
license: MIT
|
||||||
conflicts:
|
conflicts:
|
||||||
- taskwarrior
|
- taskwarrior
|
||||||
formats:
|
formats:
|
||||||
- deb
|
- deb
|
||||||
- rpm
|
- rpm
|
||||||
file_name_template: "{{.ProjectName}}_{{.Os}}_{{.Arch}}"
|
file_name_template: '{{.ProjectName}}_{{.Os}}_{{.Arch}}'
|
||||||
contents:
|
contents:
|
||||||
- src: completion/bash/task.bash
|
- src: completion/bash/task.bash
|
||||||
dst: /etc/bash_completion.d/task
|
dst: /etc/bash_completion.d/task
|
||||||
@@ -83,8 +86,7 @@ brews:
|
|||||||
repository:
|
repository:
|
||||||
owner: go-task
|
owner: go-task
|
||||||
name: homebrew-tap
|
name: homebrew-tap
|
||||||
test:
|
test: system "#{bin}/task", "--help"
|
||||||
system "#{bin}/task", "--help"
|
|
||||||
install: |-
|
install: |-
|
||||||
bin.install "task"
|
bin.install "task"
|
||||||
bash_completion.install "completion/bash/task.bash" => "task"
|
bash_completion.install "completion/bash/task.bash" => "task"
|
||||||
@@ -107,7 +109,7 @@ winget:
|
|||||||
commit_author:
|
commit_author:
|
||||||
name: task-bot
|
name: task-bot
|
||||||
email: 106601941+task-bot@users.noreply.github.com
|
email: 106601941+task-bot@users.noreply.github.com
|
||||||
commit_msg_template: "chore: bump {{.PackageIdentifier}} to {{.Tag}}"
|
commit_msg_template: 'chore: release {{.PackageIdentifier}} {{.Tag}}'
|
||||||
release_notes_url: https://github.com/go-task/task/releases/tag/{{.Tag}}
|
release_notes_url: https://github.com/go-task/task/releases/tag/{{.Tag}}
|
||||||
tags:
|
tags:
|
||||||
- build
|
- build
|
||||||
@@ -121,13 +123,15 @@ winget:
|
|||||||
- task-runner
|
- task-runner
|
||||||
- taskfile
|
- taskfile
|
||||||
- tool
|
- tool
|
||||||
skip_upload: true
|
|
||||||
repository:
|
repository:
|
||||||
owner: microsoft
|
owner: go-task
|
||||||
name: winget-pkgs
|
name: winget-pkgs
|
||||||
|
branch: 'chore/task-{{.Version}}'
|
||||||
pull_request:
|
pull_request:
|
||||||
enabled: true
|
enabled: true
|
||||||
|
draft: false
|
||||||
|
check_boxes: true
|
||||||
base:
|
base:
|
||||||
owner: go-task
|
owner: microsoft
|
||||||
name: winget-pkgs
|
name: winget-pkgs
|
||||||
branch: "bump-task-to-{{.Tag}}"
|
branch: master
|
||||||
|
|||||||
11
CHANGELOG.md
11
CHANGELOG.md
@@ -1,5 +1,16 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## v3.44.1 - 2025-07-23
|
||||||
|
|
||||||
|
- Internal tasks will no longer be shown as suggestions since they cannot be
|
||||||
|
called (#2309, #2323 by @maxmzkrcensys)
|
||||||
|
- Fixed install script for some ARM platforms (#1516, #2291 by @trulede).
|
||||||
|
- Fixed a regression where fingerprinting was not working correctly if the path
|
||||||
|
to you Taskfile contained a space (#2321, #2322 by @pd93).
|
||||||
|
- Reverted a breaking change to `randInt` (#2312, #2316 by @pd93).
|
||||||
|
- Made new variables `TEST_NAME` and `TEST_DIR` available in fixture tests
|
||||||
|
(#2265 by @pd93).
|
||||||
|
|
||||||
## v3.44.0 - 2025-06-08
|
## v3.44.0 - 2025-06-08
|
||||||
|
|
||||||
- Added `uuid`, `randInt` and `randIntN` template functions (#1346, #2225 by
|
- Added `uuid`, `randInt` and `randIntN` template functions (#1346, #2225 by
|
||||||
|
|||||||
@@ -53,9 +53,12 @@ tasks:
|
|||||||
generate:fixtures:
|
generate:fixtures:
|
||||||
desc: Runs tests and generates golden fixture files
|
desc: Runs tests and generates golden fixture files
|
||||||
aliases: [gen:fixtures, g:fixtures]
|
aliases: [gen:fixtures, g:fixtures]
|
||||||
|
env:
|
||||||
|
GOLDIE_UPDATE: 'true'
|
||||||
|
GOLDIE_TEMPLATE: 'true'
|
||||||
cmds:
|
cmds:
|
||||||
- find ./testdata -name '*.golden' -delete
|
- find ./testdata -name '*.golden' -delete
|
||||||
- go test -update ./...
|
- go test ./...
|
||||||
|
|
||||||
install:mockery:
|
install:mockery:
|
||||||
desc: Installs mockgen; a tool to generate mock files
|
desc: Installs mockgen; a tool to generate mock files
|
||||||
@@ -87,6 +90,7 @@ tasks:
|
|||||||
sources:
|
sources:
|
||||||
- './**/*.go'
|
- './**/*.go'
|
||||||
- .golangci.yml
|
- .golangci.yml
|
||||||
|
- go.mod
|
||||||
cmds:
|
cmds:
|
||||||
- golangci-lint run
|
- golangci-lint run
|
||||||
|
|
||||||
@@ -95,6 +99,7 @@ tasks:
|
|||||||
sources:
|
sources:
|
||||||
- './**/*.go'
|
- './**/*.go'
|
||||||
- .golangci.yml
|
- .golangci.yml
|
||||||
|
- go.mod
|
||||||
cmds:
|
cmds:
|
||||||
- golangci-lint run --fix
|
- golangci-lint run --fix
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import (
|
|||||||
"github.com/go-task/task/v3/internal/flags"
|
"github.com/go-task/task/v3/internal/flags"
|
||||||
"github.com/go-task/task/v3/internal/logger"
|
"github.com/go-task/task/v3/internal/logger"
|
||||||
"github.com/go-task/task/v3/internal/version"
|
"github.com/go-task/task/v3/internal/version"
|
||||||
|
"github.com/go-task/task/v3/taskfile"
|
||||||
"github.com/go-task/task/v3/taskfile/ast"
|
"github.com/go-task/task/v3/taskfile/ast"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -110,16 +111,63 @@ func run() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
e := task.NewExecutor(
|
if err := experiments.Validate(); err != nil {
|
||||||
flags.WithFlags(),
|
log.Warnf("%s\n", err.Error())
|
||||||
task.WithVersionCheck(true),
|
}
|
||||||
|
|
||||||
|
// Create a new root node for the given entrypoint
|
||||||
|
node, err := taskfile.NewRootNode(
|
||||||
|
flags.Entrypoint,
|
||||||
|
flags.Dir,
|
||||||
|
flags.Insecure,
|
||||||
)
|
)
|
||||||
if err := e.Setup(); err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tempDir, err := task.NewTempDir(node.Dir())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
reader := taskfile.NewReader(
|
||||||
|
flags.WithFlags(),
|
||||||
|
taskfile.WithTempDir(tempDir.Remote),
|
||||||
|
taskfile.WithDebugFunc(func(s string) {
|
||||||
|
log.VerboseOutf(logger.Magenta, s)
|
||||||
|
}),
|
||||||
|
taskfile.WithPromptFunc(func(s string) error {
|
||||||
|
return log.Prompt(logger.Yellow, s, "n", "y", "yes")
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
|
||||||
|
ctx, cf := context.WithTimeout(context.Background(), flags.Timeout)
|
||||||
|
defer cf()
|
||||||
|
graph, err := reader.Read(ctx, node)
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, context.DeadlineExceeded) {
|
||||||
|
return &errors.TaskfileNetworkTimeoutError{URI: node.Location(), Timeout: flags.Timeout}
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
executor, err := task.NewExecutor(graph,
|
||||||
|
flags.WithFlags(),
|
||||||
|
task.WithDir(node.Dir()),
|
||||||
|
task.WithTempDir(tempDir),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the download flag is specified, we should stop execution as soon as
|
||||||
|
// taskfile is downloaded
|
||||||
|
if flags.Download {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
if flags.ClearCache {
|
if flags.ClearCache {
|
||||||
cachePath := filepath.Join(e.TempDir.Remote, "remote")
|
cachePath := filepath.Join(executor.TempDir.Remote, "remote")
|
||||||
return os.RemoveAll(cachePath)
|
return os.RemoveAll(cachePath)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,9 +179,9 @@ func run() error {
|
|||||||
)
|
)
|
||||||
if listOptions.ShouldListTasks() {
|
if listOptions.ShouldListTasks() {
|
||||||
if flags.Silent {
|
if flags.Silent {
|
||||||
return e.ListTaskNames(flags.ListAll)
|
return executor.ListTaskNames(flags.ListAll)
|
||||||
}
|
}
|
||||||
foundTasks, err := e.ListTasks(listOptions)
|
foundTasks, err := executor.ListTasks(listOptions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -165,17 +213,17 @@ func run() error {
|
|||||||
globals.Set("CLI_SILENT", ast.Var{Value: flags.Silent})
|
globals.Set("CLI_SILENT", ast.Var{Value: flags.Silent})
|
||||||
globals.Set("CLI_VERBOSE", ast.Var{Value: flags.Verbose})
|
globals.Set("CLI_VERBOSE", ast.Var{Value: flags.Verbose})
|
||||||
globals.Set("CLI_OFFLINE", ast.Var{Value: flags.Offline})
|
globals.Set("CLI_OFFLINE", ast.Var{Value: flags.Offline})
|
||||||
e.Taskfile.Vars.Merge(globals, nil)
|
executor.Taskfile.Vars.Merge(globals, nil)
|
||||||
|
|
||||||
if !flags.Watch {
|
if !flags.Watch {
|
||||||
e.InterceptInterruptSignals()
|
executor.InterceptInterruptSignals()
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx := context.Background()
|
ctx = context.Background()
|
||||||
|
|
||||||
if flags.Status {
|
if flags.Status {
|
||||||
return e.Status(ctx, calls...)
|
return executor.Status(ctx, calls...)
|
||||||
}
|
}
|
||||||
|
|
||||||
return e.Run(ctx, calls...)
|
return executor.Run(ctx, calls...)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package errors
|
package errors
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@@ -46,8 +47,9 @@ func (err *TaskRunError) Code() int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (err *TaskRunError) TaskExitCode() int {
|
func (err *TaskRunError) TaskExitCode() int {
|
||||||
if c, ok := interp.IsExitStatus(err.Err); ok {
|
var exit interp.ExitStatus
|
||||||
return int(c)
|
if errors.As(err.Err, &exit) {
|
||||||
|
return int(exit)
|
||||||
}
|
}
|
||||||
return err.Code()
|
return err.Code()
|
||||||
}
|
}
|
||||||
|
|||||||
150
executor.go
150
executor.go
@@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -26,27 +27,21 @@ type (
|
|||||||
// within them.
|
// within them.
|
||||||
Executor struct {
|
Executor struct {
|
||||||
// Flags
|
// Flags
|
||||||
Dir string
|
Dir string
|
||||||
Entrypoint string
|
TempDir *TempDir
|
||||||
TempDir TempDir
|
Force bool
|
||||||
Force bool
|
ForceAll bool
|
||||||
ForceAll bool
|
Watch bool
|
||||||
Insecure bool
|
Verbose bool
|
||||||
Download bool
|
Silent bool
|
||||||
Offline bool
|
AssumeYes bool
|
||||||
Timeout time.Duration
|
AssumeTerm bool // Used for testing
|
||||||
CacheExpiryDuration time.Duration
|
Dry bool
|
||||||
Watch bool
|
Summary bool
|
||||||
Verbose bool
|
Parallel bool
|
||||||
Silent bool
|
Color bool
|
||||||
AssumeYes bool
|
Concurrency int
|
||||||
AssumeTerm bool // Used for testing
|
Interval time.Duration
|
||||||
Dry bool
|
|
||||||
Summary bool
|
|
||||||
Parallel bool
|
|
||||||
Color bool
|
|
||||||
Concurrency int
|
|
||||||
Interval time.Duration
|
|
||||||
|
|
||||||
// I/O
|
// I/O
|
||||||
Stdin io.Reader
|
Stdin io.Reader
|
||||||
@@ -72,17 +67,17 @@ type (
|
|||||||
executionHashesMutex sync.Mutex
|
executionHashesMutex sync.Mutex
|
||||||
watchedDirs *xsync.MapOf[string, bool]
|
watchedDirs *xsync.MapOf[string, bool]
|
||||||
}
|
}
|
||||||
TempDir struct {
|
|
||||||
Remote string
|
|
||||||
Fingerprint string
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewExecutor creates a new [Executor] and applies the given functional options
|
// NewExecutor creates a new [Executor] and applies the given functional options
|
||||||
// to it.
|
// to it.
|
||||||
func NewExecutor(opts ...ExecutorOption) *Executor {
|
func NewExecutor(graph *ast.TaskfileGraph, opts ...ExecutorOption) (*Executor, error) {
|
||||||
|
tf, err := graph.Merge()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
e := &Executor{
|
e := &Executor{
|
||||||
Timeout: time.Second * 10,
|
Taskfile: tf,
|
||||||
Stdin: os.Stdin,
|
Stdin: os.Stdin,
|
||||||
Stdout: os.Stdout,
|
Stdout: os.Stdout,
|
||||||
Stderr: os.Stderr,
|
Stderr: os.Stderr,
|
||||||
@@ -100,7 +95,10 @@ func NewExecutor(opts ...ExecutorOption) *Executor {
|
|||||||
executionHashesMutex: sync.Mutex{},
|
executionHashesMutex: sync.Mutex{},
|
||||||
}
|
}
|
||||||
e.Options(opts...)
|
e.Options(opts...)
|
||||||
return e
|
if err := e.setup(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return e, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Options loops through the given [ExecutorOption] functions and applies them
|
// Options loops through the given [ExecutorOption] functions and applies them
|
||||||
@@ -122,33 +120,23 @@ type dirOption struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (o *dirOption) ApplyToExecutor(e *Executor) {
|
func (o *dirOption) ApplyToExecutor(e *Executor) {
|
||||||
e.Dir = o.dir
|
absDir, err := filepath.Abs(o.dir)
|
||||||
}
|
if err != nil {
|
||||||
|
e.Dir = o.dir
|
||||||
// WithEntrypoint sets the entrypoint (main Taskfile) of the [Executor]. By
|
return
|
||||||
// default, Task will search for one of the default Taskfiles in the given
|
}
|
||||||
// directory.
|
e.Dir = absDir
|
||||||
func WithEntrypoint(entrypoint string) ExecutorOption {
|
|
||||||
return &entrypointOption{entrypoint}
|
|
||||||
}
|
|
||||||
|
|
||||||
type entrypointOption struct {
|
|
||||||
entrypoint string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o *entrypointOption) ApplyToExecutor(e *Executor) {
|
|
||||||
e.Entrypoint = o.entrypoint
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithTempDir sets the temporary directory that will be used by [Executor] for
|
// WithTempDir sets the temporary directory that will be used by [Executor] for
|
||||||
// storing temporary files like checksums and cached remote files. By default,
|
// storing temporary files like checksums and cached remote files. By default,
|
||||||
// the temporary directory is set to the user's temporary directory.
|
// the temporary directory is set to the user's temporary directory.
|
||||||
func WithTempDir(tempDir TempDir) ExecutorOption {
|
func WithTempDir(tempDir *TempDir) ExecutorOption {
|
||||||
return &tempDirOption{tempDir}
|
return &tempDirOption{tempDir}
|
||||||
}
|
}
|
||||||
|
|
||||||
type tempDirOption struct {
|
type tempDirOption struct {
|
||||||
tempDir TempDir
|
tempDir *TempDir
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *tempDirOption) ApplyToExecutor(e *Executor) {
|
func (o *tempDirOption) ApplyToExecutor(e *Executor) {
|
||||||
@@ -183,76 +171,6 @@ func (o *forceAllOption) ApplyToExecutor(e *Executor) {
|
|||||||
e.ForceAll = o.forceAll
|
e.ForceAll = o.forceAll
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithInsecure allows the [Executor] to make insecure connections when reading
|
|
||||||
// remote taskfiles. By default, insecure connections are rejected.
|
|
||||||
func WithInsecure(insecure bool) ExecutorOption {
|
|
||||||
return &insecureOption{insecure}
|
|
||||||
}
|
|
||||||
|
|
||||||
type insecureOption struct {
|
|
||||||
insecure bool
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o *insecureOption) ApplyToExecutor(e *Executor) {
|
|
||||||
e.Insecure = o.insecure
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithDownload forces the [Executor] to download a fresh copy of the taskfile
|
|
||||||
// from the remote source.
|
|
||||||
func WithDownload(download bool) ExecutorOption {
|
|
||||||
return &downloadOption{download}
|
|
||||||
}
|
|
||||||
|
|
||||||
type downloadOption struct {
|
|
||||||
download bool
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o *downloadOption) ApplyToExecutor(e *Executor) {
|
|
||||||
e.Download = o.download
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithOffline stops the [Executor] from being able to make network connections.
|
|
||||||
// It will still be able to read local files and cached copies of remote files.
|
|
||||||
func WithOffline(offline bool) ExecutorOption {
|
|
||||||
return &offlineOption{offline}
|
|
||||||
}
|
|
||||||
|
|
||||||
type offlineOption struct {
|
|
||||||
offline bool
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o *offlineOption) ApplyToExecutor(e *Executor) {
|
|
||||||
e.Offline = o.offline
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithTimeout sets the [Executor]'s timeout for fetching remote taskfiles. By
|
|
||||||
// default, the timeout is set to 10 seconds.
|
|
||||||
func WithTimeout(timeout time.Duration) ExecutorOption {
|
|
||||||
return &timeoutOption{timeout}
|
|
||||||
}
|
|
||||||
|
|
||||||
type timeoutOption struct {
|
|
||||||
timeout time.Duration
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o *timeoutOption) ApplyToExecutor(e *Executor) {
|
|
||||||
e.Timeout = o.timeout
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithCacheExpiryDuration sets the duration after which the cache is considered
|
|
||||||
// expired. By default, the cache is considered expired after 24 hours.
|
|
||||||
func WithCacheExpiryDuration(duration time.Duration) ExecutorOption {
|
|
||||||
return &cacheExpiryDurationOption{duration: duration}
|
|
||||||
}
|
|
||||||
|
|
||||||
type cacheExpiryDurationOption struct {
|
|
||||||
duration time.Duration
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o *cacheExpiryDurationOption) ApplyToExecutor(r *Executor) {
|
|
||||||
r.CacheExpiryDuration = o.duration
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithWatch tells the [Executor] to keep running in the background and watch
|
// WithWatch tells the [Executor] to keep running in the background and watch
|
||||||
// for changes to the fingerprint of the tasks that are run. When changes are
|
// for changes to the fingerprint of the tasks that are run. When changes are
|
||||||
// detected, a new task run is triggered.
|
// detected, a new task run is triggered.
|
||||||
|
|||||||
@@ -4,18 +4,13 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
|
||||||
"slices"
|
"slices"
|
||||||
"strings"
|
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/Masterminds/semver/v3"
|
"github.com/Masterminds/semver/v3"
|
||||||
"github.com/sajari/fuzzy"
|
"github.com/sajari/fuzzy"
|
||||||
|
|
||||||
"github.com/go-task/task/v3/errors"
|
"github.com/go-task/task/v3/errors"
|
||||||
"github.com/go-task/task/v3/internal/env"
|
|
||||||
"github.com/go-task/task/v3/internal/execext"
|
|
||||||
"github.com/go-task/task/v3/internal/filepathext"
|
|
||||||
"github.com/go-task/task/v3/internal/logger"
|
"github.com/go-task/task/v3/internal/logger"
|
||||||
"github.com/go-task/task/v3/internal/output"
|
"github.com/go-task/task/v3/internal/output"
|
||||||
"github.com/go-task/task/v3/internal/version"
|
"github.com/go-task/task/v3/internal/version"
|
||||||
@@ -23,18 +18,8 @@ import (
|
|||||||
"github.com/go-task/task/v3/taskfile/ast"
|
"github.com/go-task/task/v3/taskfile/ast"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (e *Executor) Setup() error {
|
func (e *Executor) setup() error {
|
||||||
e.setupLogger()
|
e.setupLogger()
|
||||||
node, err := e.getRootNode()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := e.setupTempDir(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := e.readTaskfile(node); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
e.setupFuzzyModel()
|
e.setupFuzzyModel()
|
||||||
e.setupStdFiles()
|
e.setupStdFiles()
|
||||||
if err := e.setupOutput(); err != nil {
|
if err := e.setupOutput(); err != nil {
|
||||||
@@ -54,46 +39,6 @@ func (e *Executor) Setup() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Executor) getRootNode() (taskfile.Node, error) {
|
|
||||||
node, err := taskfile.NewRootNode(e.Entrypoint, e.Dir, e.Insecure, e.Timeout)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
e.Dir = node.Dir()
|
|
||||||
return node, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *Executor) readTaskfile(node taskfile.Node) error {
|
|
||||||
ctx, cf := context.WithTimeout(context.Background(), e.Timeout)
|
|
||||||
defer cf()
|
|
||||||
debugFunc := func(s string) {
|
|
||||||
e.Logger.VerboseOutf(logger.Magenta, s)
|
|
||||||
}
|
|
||||||
promptFunc := func(s string) error {
|
|
||||||
return e.Logger.Prompt(logger.Yellow, s, "n", "y", "yes")
|
|
||||||
}
|
|
||||||
reader := taskfile.NewReader(
|
|
||||||
taskfile.WithInsecure(e.Insecure),
|
|
||||||
taskfile.WithDownload(e.Download),
|
|
||||||
taskfile.WithOffline(e.Offline),
|
|
||||||
taskfile.WithTempDir(e.TempDir.Remote),
|
|
||||||
taskfile.WithCacheExpiryDuration(e.CacheExpiryDuration),
|
|
||||||
taskfile.WithDebugFunc(debugFunc),
|
|
||||||
taskfile.WithPromptFunc(promptFunc),
|
|
||||||
)
|
|
||||||
graph, err := reader.Read(ctx, node)
|
|
||||||
if err != nil {
|
|
||||||
if errors.Is(err, context.DeadlineExceeded) {
|
|
||||||
return &errors.TaskfileNetworkTimeoutError{URI: node.Location(), Timeout: e.Timeout}
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if e.Taskfile, err = graph.Merge(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *Executor) setupFuzzyModel() {
|
func (e *Executor) setupFuzzyModel() {
|
||||||
if e.Taskfile == nil {
|
if e.Taskfile == nil {
|
||||||
return
|
return
|
||||||
@@ -104,6 +49,9 @@ func (e *Executor) setupFuzzyModel() {
|
|||||||
|
|
||||||
var words []string
|
var words []string
|
||||||
for name, task := range e.Taskfile.Tasks.All(nil) {
|
for name, task := range e.Taskfile.Tasks.All(nil) {
|
||||||
|
if task.Internal {
|
||||||
|
continue
|
||||||
|
}
|
||||||
words = append(words, name)
|
words = append(words, name)
|
||||||
words = slices.Concat(words, task.Aliases)
|
words = slices.Concat(words, task.Aliases)
|
||||||
}
|
}
|
||||||
@@ -112,52 +60,6 @@ func (e *Executor) setupFuzzyModel() {
|
|||||||
e.fuzzyModel = model
|
e.fuzzyModel = model
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Executor) setupTempDir() error {
|
|
||||||
if e.TempDir != (TempDir{}) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
tempDir := env.GetTaskEnv("TEMP_DIR")
|
|
||||||
if tempDir == "" {
|
|
||||||
e.TempDir = TempDir{
|
|
||||||
Remote: filepathext.SmartJoin(e.Dir, ".task"),
|
|
||||||
Fingerprint: filepathext.SmartJoin(e.Dir, ".task"),
|
|
||||||
}
|
|
||||||
} else if filepath.IsAbs(tempDir) || strings.HasPrefix(tempDir, "~") {
|
|
||||||
tempDir, err := execext.ExpandLiteral(tempDir)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
projectDir, _ := filepath.Abs(e.Dir)
|
|
||||||
projectName := filepath.Base(projectDir)
|
|
||||||
e.TempDir = TempDir{
|
|
||||||
Remote: tempDir,
|
|
||||||
Fingerprint: filepathext.SmartJoin(tempDir, projectName),
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
e.TempDir = TempDir{
|
|
||||||
Remote: filepathext.SmartJoin(e.Dir, tempDir),
|
|
||||||
Fingerprint: filepathext.SmartJoin(e.Dir, tempDir),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
remoteDir := env.GetTaskEnv("REMOTE_DIR")
|
|
||||||
if remoteDir != "" {
|
|
||||||
if filepath.IsAbs(remoteDir) || strings.HasPrefix(remoteDir, "~") {
|
|
||||||
remoteTempDir, err := execext.ExpandLiteral(remoteDir)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
e.TempDir.Remote = remoteTempDir
|
|
||||||
} else {
|
|
||||||
e.TempDir.Remote = filepathext.SmartJoin(e.Dir, ".task")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *Executor) setupStdFiles() {
|
func (e *Executor) setupStdFiles() {
|
||||||
if e.Stdin == nil {
|
if e.Stdin == nil {
|
||||||
e.Stdin = os.Stdin
|
e.Stdin = os.Stdin
|
||||||
@@ -203,7 +105,7 @@ func (e *Executor) setupCompiler() error {
|
|||||||
|
|
||||||
e.Compiler = &Compiler{
|
e.Compiler = &Compiler{
|
||||||
Dir: e.Dir,
|
Dir: e.Dir,
|
||||||
Entrypoint: e.Entrypoint,
|
Entrypoint: e.Taskfile.Location,
|
||||||
UserWorkingDir: e.UserWorkingDir,
|
UserWorkingDir: e.UserWorkingDir,
|
||||||
TaskfileEnv: e.Taskfile.Env,
|
TaskfileEnv: e.Taskfile.Env,
|
||||||
TaskfileVars: e.Taskfile.Vars,
|
TaskfileVars: e.Taskfile.Vars,
|
||||||
331
executor_test.go
331
executor_test.go
@@ -7,6 +7,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"slices"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/sebdah/goldie/v2"
|
"github.com/sebdah/goldie/v2"
|
||||||
@@ -15,6 +16,7 @@ import (
|
|||||||
"github.com/go-task/task/v3"
|
"github.com/go-task/task/v3"
|
||||||
"github.com/go-task/task/v3/experiments"
|
"github.com/go-task/task/v3/experiments"
|
||||||
"github.com/go-task/task/v3/internal/filepathext"
|
"github.com/go-task/task/v3/internal/filepathext"
|
||||||
|
"github.com/go-task/task/v3/taskfile"
|
||||||
"github.com/go-task/task/v3/taskfile/ast"
|
"github.com/go-task/task/v3/taskfile/ast"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -34,7 +36,12 @@ type (
|
|||||||
task string
|
task string
|
||||||
vars map[string]any
|
vars map[string]any
|
||||||
input string
|
input string
|
||||||
|
nodeDir string
|
||||||
|
nodeEntrypoint string
|
||||||
|
nodeInsecure bool
|
||||||
|
readerOpts []taskfile.ReaderOption
|
||||||
executorOpts []task.ExecutorOption
|
executorOpts []task.ExecutorOption
|
||||||
|
wantReaderError bool
|
||||||
wantSetupError bool
|
wantSetupError bool
|
||||||
wantRunError bool
|
wantRunError bool
|
||||||
wantStatusError bool
|
wantStatusError bool
|
||||||
@@ -47,10 +54,12 @@ type (
|
|||||||
func NewExecutorTest(t *testing.T, opts ...ExecutorTestOption) {
|
func NewExecutorTest(t *testing.T, opts ...ExecutorTestOption) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
tt := &ExecutorTest{
|
tt := &ExecutorTest{
|
||||||
task: "default",
|
task: "default",
|
||||||
vars: map[string]any{},
|
vars: map[string]any{},
|
||||||
|
nodeDir: ".",
|
||||||
TaskTest: TaskTest{
|
TaskTest: TaskTest{
|
||||||
experiments: map[*experiments.Experiment]int{},
|
experiments: map[*experiments.Experiment]int{},
|
||||||
|
fixtureTemplateData: map[string]any{},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
// Apply the functional options
|
// Apply the functional options
|
||||||
@@ -144,11 +153,52 @@ func (tt *ExecutorTest) run(t *testing.T) {
|
|||||||
f := func(t *testing.T) {
|
f := func(t *testing.T) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
opts := append(
|
// Create a new root node for the given entrypoint
|
||||||
|
node, err := taskfile.NewRootNode(
|
||||||
|
tt.nodeEntrypoint,
|
||||||
|
tt.nodeDir,
|
||||||
|
tt.nodeInsecure,
|
||||||
|
)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// Create a golden fixture file for the output
|
||||||
|
g := goldie.New(t,
|
||||||
|
goldie.WithFixtureDir(filepath.Join(node.Dir(), "testdata")),
|
||||||
|
)
|
||||||
|
|
||||||
|
// Set up a temporary directory for the taskfile reader and task executor
|
||||||
|
tempDir, err := task.NewTempDir(node.Dir())
|
||||||
|
require.NoError(t, err)
|
||||||
|
tt.readerOpts = append(tt.readerOpts, taskfile.WithTempDir(tempDir.Remote))
|
||||||
|
|
||||||
|
// Set up the taskfile reader
|
||||||
|
reader := taskfile.NewReader(tt.readerOpts...)
|
||||||
|
graph, err := reader.Read(ctx, node)
|
||||||
|
if tt.wantReaderError {
|
||||||
|
require.Error(t, err)
|
||||||
|
tt.writeFixtureErrReader(t, g, err)
|
||||||
|
tt.writeFixtureBuffer(t, g, buf)
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
require.NoError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
executorOpts := slices.Concat(
|
||||||
|
// Apply the node directory and temp directory to the executor options
|
||||||
|
// by default, but allow them to by overridden by the test options
|
||||||
|
[]task.ExecutorOption{
|
||||||
|
task.WithDir(node.Dir()),
|
||||||
|
task.WithTempDir(tempDir),
|
||||||
|
},
|
||||||
|
// Apply the executor options from the test
|
||||||
tt.executorOpts,
|
tt.executorOpts,
|
||||||
task.WithStdout(&buf),
|
// Force the input/output streams to be set to the test buffer
|
||||||
task.WithStderr(&buf),
|
[]task.ExecutorOption{
|
||||||
|
task.WithStdout(&buf),
|
||||||
|
task.WithStderr(&buf),
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
// If the test has input, create a reader for it and add it to the
|
// If the test has input, create a reader for it and add it to the
|
||||||
@@ -156,19 +206,12 @@ func (tt *ExecutorTest) run(t *testing.T) {
|
|||||||
if tt.input != "" {
|
if tt.input != "" {
|
||||||
var reader bytes.Buffer
|
var reader bytes.Buffer
|
||||||
reader.WriteString(tt.input)
|
reader.WriteString(tt.input)
|
||||||
opts = append(opts, task.WithStdin(&reader))
|
executorOpts = append(executorOpts, task.WithStdin(&reader))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set up the task executor
|
// Set up the task executor
|
||||||
e := task.NewExecutor(opts...)
|
executor, err := task.NewExecutor(graph, executorOpts...)
|
||||||
|
if tt.wantSetupError {
|
||||||
// Create a golden fixture file for the output
|
|
||||||
g := goldie.New(t,
|
|
||||||
goldie.WithFixtureDir(filepath.Join(e.Dir, "testdata")),
|
|
||||||
)
|
|
||||||
|
|
||||||
// Call setup and check for errors
|
|
||||||
if err := e.Setup(); tt.wantSetupError {
|
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
tt.writeFixtureErrSetup(t, g, err)
|
tt.writeFixtureErrSetup(t, g, err)
|
||||||
tt.writeFixtureBuffer(t, g, buf)
|
tt.writeFixtureBuffer(t, g, buf)
|
||||||
@@ -188,8 +231,7 @@ func (tt *ExecutorTest) run(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Run the task and check for errors
|
// Run the task and check for errors
|
||||||
ctx := context.Background()
|
if err := executor.Run(ctx, call); tt.wantRunError {
|
||||||
if err := e.Run(ctx, call); tt.wantRunError {
|
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
tt.writeFixtureErrRun(t, g, err)
|
tt.writeFixtureErrRun(t, g, err)
|
||||||
tt.writeFixtureBuffer(t, g, buf)
|
tt.writeFixtureBuffer(t, g, buf)
|
||||||
@@ -200,7 +242,7 @@ func (tt *ExecutorTest) run(t *testing.T) {
|
|||||||
|
|
||||||
// If the status flag is set, run the status check
|
// If the status flag is set, run the status check
|
||||||
if tt.wantStatusError {
|
if tt.wantStatusError {
|
||||||
if err := e.Status(ctx, call); err != nil {
|
if err := executor.Status(ctx, call); err != nil {
|
||||||
tt.writeFixtureStatus(t, g, err.Error())
|
tt.writeFixtureStatus(t, g, err.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -219,20 +261,17 @@ func (tt *ExecutorTest) run(t *testing.T) {
|
|||||||
func TestEmptyTask(t *testing.T) {
|
func TestEmptyTask(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
NewExecutorTest(t,
|
NewExecutorTest(t,
|
||||||
WithExecutorOptions(
|
WithNodeDir("testdata/empty_task"),
|
||||||
task.WithDir("testdata/empty_task"),
|
WithExecutorOptions(),
|
||||||
),
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestEmptyTaskfile(t *testing.T) {
|
func TestEmptyTaskfile(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
NewExecutorTest(t,
|
NewExecutorTest(t,
|
||||||
WithExecutorOptions(
|
WithNodeDir("testdata/empty_taskfile"),
|
||||||
task.WithDir("testdata/empty_taskfile"),
|
WithReaderError(),
|
||||||
),
|
WithFixtureTemplating(),
|
||||||
WithSetupError(),
|
|
||||||
WithPostProcessFn(PPRemoveAbsolutePaths),
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -240,15 +279,15 @@ func TestEnv(t *testing.T) {
|
|||||||
t.Setenv("QUX", "from_os")
|
t.Setenv("QUX", "from_os")
|
||||||
NewExecutorTest(t,
|
NewExecutorTest(t,
|
||||||
WithName("env precedence disabled"),
|
WithName("env precedence disabled"),
|
||||||
|
WithNodeDir("testdata/env"),
|
||||||
WithExecutorOptions(
|
WithExecutorOptions(
|
||||||
task.WithDir("testdata/env"),
|
|
||||||
task.WithSilent(true),
|
task.WithSilent(true),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
NewExecutorTest(t,
|
NewExecutorTest(t,
|
||||||
WithName("env precedence enabled"),
|
WithName("env precedence enabled"),
|
||||||
|
WithNodeDir("testdata/env"),
|
||||||
WithExecutorOptions(
|
WithExecutorOptions(
|
||||||
task.WithDir("testdata/env"),
|
|
||||||
task.WithSilent(true),
|
task.WithSilent(true),
|
||||||
),
|
),
|
||||||
WithExperiment(&experiments.EnvPrecedence, 1),
|
WithExperiment(&experiments.EnvPrecedence, 1),
|
||||||
@@ -258,8 +297,8 @@ func TestEnv(t *testing.T) {
|
|||||||
func TestVars(t *testing.T) {
|
func TestVars(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
NewExecutorTest(t,
|
NewExecutorTest(t,
|
||||||
|
WithNodeDir("testdata/vars"),
|
||||||
WithExecutorOptions(
|
WithExecutorOptions(
|
||||||
task.WithDir("testdata/vars"),
|
|
||||||
task.WithSilent(true),
|
task.WithSilent(true),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
@@ -269,25 +308,19 @@ func TestRequires(t *testing.T) {
|
|||||||
t.Parallel()
|
t.Parallel()
|
||||||
NewExecutorTest(t,
|
NewExecutorTest(t,
|
||||||
WithName("required var missing"),
|
WithName("required var missing"),
|
||||||
WithExecutorOptions(
|
WithNodeDir("testdata/requires"),
|
||||||
task.WithDir("testdata/requires"),
|
|
||||||
),
|
|
||||||
WithTask("missing-var"),
|
WithTask("missing-var"),
|
||||||
WithRunError(),
|
WithRunError(),
|
||||||
)
|
)
|
||||||
NewExecutorTest(t,
|
NewExecutorTest(t,
|
||||||
WithName("required var ok"),
|
WithName("required var ok"),
|
||||||
WithExecutorOptions(
|
WithNodeDir("testdata/requires"),
|
||||||
task.WithDir("testdata/requires"),
|
|
||||||
),
|
|
||||||
WithTask("missing-var"),
|
WithTask("missing-var"),
|
||||||
WithVar("FOO", "bar"),
|
WithVar("FOO", "bar"),
|
||||||
)
|
)
|
||||||
NewExecutorTest(t,
|
NewExecutorTest(t,
|
||||||
WithName("fails validation"),
|
WithName("fails validation"),
|
||||||
WithExecutorOptions(
|
WithNodeDir("testdata/requires"),
|
||||||
task.WithDir("testdata/requires"),
|
|
||||||
),
|
|
||||||
WithTask("validation-var"),
|
WithTask("validation-var"),
|
||||||
WithVar("ENV", "dev"),
|
WithVar("ENV", "dev"),
|
||||||
WithVar("FOO", "bar"),
|
WithVar("FOO", "bar"),
|
||||||
@@ -295,48 +328,37 @@ func TestRequires(t *testing.T) {
|
|||||||
)
|
)
|
||||||
NewExecutorTest(t,
|
NewExecutorTest(t,
|
||||||
WithName("passes validation"),
|
WithName("passes validation"),
|
||||||
WithExecutorOptions(
|
WithNodeDir("testdata/requires"),
|
||||||
task.WithDir("testdata/requires"),
|
|
||||||
),
|
|
||||||
WithTask("validation-var"),
|
WithTask("validation-var"),
|
||||||
WithVar("FOO", "one"),
|
WithVar("FOO", "one"),
|
||||||
WithVar("ENV", "dev"),
|
WithVar("ENV", "dev"),
|
||||||
)
|
)
|
||||||
NewExecutorTest(t,
|
NewExecutorTest(t,
|
||||||
WithName("required var missing + fails validation"),
|
WithName("required var missing + fails validation"),
|
||||||
WithExecutorOptions(
|
WithNodeDir("testdata/requires"),
|
||||||
task.WithDir("testdata/requires"),
|
|
||||||
),
|
|
||||||
WithTask("validation-var"),
|
WithTask("validation-var"),
|
||||||
WithRunError(),
|
WithRunError(),
|
||||||
)
|
)
|
||||||
NewExecutorTest(t,
|
NewExecutorTest(t,
|
||||||
WithName("required var missing + fails validation"),
|
WithName("required var missing + fails validation"),
|
||||||
WithExecutorOptions(
|
WithNodeDir("testdata/requires"),
|
||||||
task.WithDir("testdata/requires"),
|
|
||||||
),
|
|
||||||
WithTask("validation-var-dynamic"),
|
WithTask("validation-var-dynamic"),
|
||||||
WithVar("FOO", "one"),
|
WithVar("FOO", "one"),
|
||||||
WithVar("ENV", "dev"),
|
WithVar("ENV", "dev"),
|
||||||
)
|
)
|
||||||
NewExecutorTest(t,
|
NewExecutorTest(t,
|
||||||
WithName("require before compile"),
|
WithName("require before compile"),
|
||||||
WithExecutorOptions(
|
WithNodeDir("testdata/requires"),
|
||||||
task.WithDir("testdata/requires"),
|
|
||||||
),
|
|
||||||
WithTask("require-before-compile"),
|
WithTask("require-before-compile"),
|
||||||
WithRunError(),
|
WithRunError(),
|
||||||
)
|
)
|
||||||
NewExecutorTest(t,
|
NewExecutorTest(t,
|
||||||
WithName("var defined in task"),
|
WithName("var defined in task"),
|
||||||
WithExecutorOptions(
|
WithNodeDir("testdata/requires"),
|
||||||
task.WithDir("testdata/requires"),
|
|
||||||
),
|
|
||||||
WithTask("var-defined-in-task"),
|
WithTask("var-defined-in-task"),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: mock fs
|
|
||||||
func TestSpecialVars(t *testing.T) {
|
func TestSpecialVars(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
@@ -357,17 +379,18 @@ func TestSpecialVars(t *testing.T) {
|
|||||||
"included:print-taskfile-dir",
|
"included:print-taskfile-dir",
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, dir := range []string{dir, subdir} {
|
for _, executorDir := range []string{dir, subdir} {
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
|
name := fmt.Sprintf("%s-%s", executorDir, test)
|
||||||
NewExecutorTest(t,
|
NewExecutorTest(t,
|
||||||
WithName(fmt.Sprintf("%s-%s", dir, test)),
|
WithName(name),
|
||||||
|
WithNodeDir(executorDir),
|
||||||
WithExecutorOptions(
|
WithExecutorOptions(
|
||||||
task.WithDir(dir),
|
|
||||||
task.WithSilent(true),
|
task.WithSilent(true),
|
||||||
task.WithVersionCheck(true),
|
task.WithVersionCheck(true),
|
||||||
),
|
),
|
||||||
WithTask(test),
|
WithTask(test),
|
||||||
WithPostProcessFn(PPRemoveAbsolutePaths),
|
WithFixtureTemplating(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -376,8 +399,8 @@ func TestSpecialVars(t *testing.T) {
|
|||||||
func TestConcurrency(t *testing.T) {
|
func TestConcurrency(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
NewExecutorTest(t,
|
NewExecutorTest(t,
|
||||||
|
WithNodeDir("testdata/concurrency"),
|
||||||
WithExecutorOptions(
|
WithExecutorOptions(
|
||||||
task.WithDir("testdata/concurrency"),
|
|
||||||
task.WithConcurrency(1),
|
task.WithConcurrency(1),
|
||||||
),
|
),
|
||||||
WithPostProcessFn(PPSortedLines),
|
WithPostProcessFn(PPSortedLines),
|
||||||
@@ -387,8 +410,8 @@ func TestConcurrency(t *testing.T) {
|
|||||||
func TestParams(t *testing.T) {
|
func TestParams(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
NewExecutorTest(t,
|
NewExecutorTest(t,
|
||||||
|
WithNodeDir("testdata/params"),
|
||||||
WithExecutorOptions(
|
WithExecutorOptions(
|
||||||
task.WithDir("testdata/params"),
|
|
||||||
task.WithSilent(true),
|
task.WithSilent(true),
|
||||||
),
|
),
|
||||||
WithPostProcessFn(PPSortedLines),
|
WithPostProcessFn(PPSortedLines),
|
||||||
@@ -398,15 +421,14 @@ func TestParams(t *testing.T) {
|
|||||||
func TestDeps(t *testing.T) {
|
func TestDeps(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
NewExecutorTest(t,
|
NewExecutorTest(t,
|
||||||
|
WithNodeDir("testdata/deps"),
|
||||||
WithExecutorOptions(
|
WithExecutorOptions(
|
||||||
task.WithDir("testdata/deps"),
|
|
||||||
task.WithSilent(true),
|
task.WithSilent(true),
|
||||||
),
|
),
|
||||||
WithPostProcessFn(PPSortedLines),
|
WithPostProcessFn(PPSortedLines),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: mock fs
|
|
||||||
func TestStatus(t *testing.T) {
|
func TestStatus(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
@@ -429,8 +451,8 @@ func TestStatus(t *testing.T) {
|
|||||||
// gen-foo creates foo.txt, and will always fail it's status check.
|
// gen-foo creates foo.txt, and will always fail it's status check.
|
||||||
NewExecutorTest(t,
|
NewExecutorTest(t,
|
||||||
WithName("run gen-foo 1 silent"),
|
WithName("run gen-foo 1 silent"),
|
||||||
|
WithNodeDir(dir),
|
||||||
WithExecutorOptions(
|
WithExecutorOptions(
|
||||||
task.WithDir(dir),
|
|
||||||
task.WithSilent(true),
|
task.WithSilent(true),
|
||||||
),
|
),
|
||||||
WithTask("gen-foo"),
|
WithTask("gen-foo"),
|
||||||
@@ -441,8 +463,8 @@ func TestStatus(t *testing.T) {
|
|||||||
// only exists after the first run.
|
// only exists after the first run.
|
||||||
NewExecutorTest(t,
|
NewExecutorTest(t,
|
||||||
WithName("run gen-bar 1 silent"),
|
WithName("run gen-bar 1 silent"),
|
||||||
|
WithNodeDir(dir),
|
||||||
WithExecutorOptions(
|
WithExecutorOptions(
|
||||||
task.WithDir(dir),
|
|
||||||
task.WithSilent(true),
|
task.WithSilent(true),
|
||||||
),
|
),
|
||||||
WithTask("gen-bar"),
|
WithTask("gen-bar"),
|
||||||
@@ -451,8 +473,8 @@ func TestStatus(t *testing.T) {
|
|||||||
// if e.Verbose is set to true.
|
// if e.Verbose is set to true.
|
||||||
NewExecutorTest(t,
|
NewExecutorTest(t,
|
||||||
WithName("run gen-baz silent"),
|
WithName("run gen-baz silent"),
|
||||||
|
WithNodeDir(dir),
|
||||||
WithExecutorOptions(
|
WithExecutorOptions(
|
||||||
task.WithDir(dir),
|
|
||||||
task.WithSilent(true),
|
task.WithSilent(true),
|
||||||
),
|
),
|
||||||
WithTask("gen-silent-baz"),
|
WithTask("gen-silent-baz"),
|
||||||
@@ -467,8 +489,8 @@ func TestStatus(t *testing.T) {
|
|||||||
// Run gen-bar a second time to produce a checksum file that matches bar.txt
|
// Run gen-bar a second time to produce a checksum file that matches bar.txt
|
||||||
NewExecutorTest(t,
|
NewExecutorTest(t,
|
||||||
WithName("run gen-bar 2 silent"),
|
WithName("run gen-bar 2 silent"),
|
||||||
|
WithNodeDir(dir),
|
||||||
WithExecutorOptions(
|
WithExecutorOptions(
|
||||||
task.WithDir(dir),
|
|
||||||
task.WithSilent(true),
|
task.WithSilent(true),
|
||||||
),
|
),
|
||||||
WithTask("gen-bar"),
|
WithTask("gen-bar"),
|
||||||
@@ -476,8 +498,8 @@ func TestStatus(t *testing.T) {
|
|||||||
// Run gen-bar a third time, to make sure we've triggered the status check.
|
// Run gen-bar a third time, to make sure we've triggered the status check.
|
||||||
NewExecutorTest(t,
|
NewExecutorTest(t,
|
||||||
WithName("run gen-bar 3 silent"),
|
WithName("run gen-bar 3 silent"),
|
||||||
|
WithNodeDir(dir),
|
||||||
WithExecutorOptions(
|
WithExecutorOptions(
|
||||||
task.WithDir(dir),
|
|
||||||
task.WithSilent(true),
|
task.WithSilent(true),
|
||||||
),
|
),
|
||||||
WithTask("gen-bar"),
|
WithTask("gen-bar"),
|
||||||
@@ -489,8 +511,8 @@ func TestStatus(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
NewExecutorTest(t,
|
NewExecutorTest(t,
|
||||||
WithName("run gen-bar 4 silent"),
|
WithName("run gen-bar 4 silent"),
|
||||||
|
WithNodeDir(dir),
|
||||||
WithExecutorOptions(
|
WithExecutorOptions(
|
||||||
task.WithDir(dir),
|
|
||||||
task.WithSilent(true),
|
task.WithSilent(true),
|
||||||
),
|
),
|
||||||
WithTask("gen-bar"),
|
WithTask("gen-bar"),
|
||||||
@@ -498,60 +520,48 @@ func TestStatus(t *testing.T) {
|
|||||||
// all: not up-to-date
|
// all: not up-to-date
|
||||||
NewExecutorTest(t,
|
NewExecutorTest(t,
|
||||||
WithName("run gen-foo 2"),
|
WithName("run gen-foo 2"),
|
||||||
WithExecutorOptions(
|
WithNodeDir(dir),
|
||||||
task.WithDir(dir),
|
|
||||||
),
|
|
||||||
WithTask("gen-foo"),
|
WithTask("gen-foo"),
|
||||||
)
|
)
|
||||||
// status: not up-to-date
|
// status: not up-to-date
|
||||||
NewExecutorTest(t,
|
NewExecutorTest(t,
|
||||||
WithName("run gen-foo 3"),
|
WithName("run gen-foo 3"),
|
||||||
WithExecutorOptions(
|
WithNodeDir(dir),
|
||||||
task.WithDir(dir),
|
|
||||||
),
|
|
||||||
WithTask("gen-foo"),
|
WithTask("gen-foo"),
|
||||||
)
|
)
|
||||||
// sources: not up-to-date
|
// sources: not up-to-date
|
||||||
NewExecutorTest(t,
|
NewExecutorTest(t,
|
||||||
WithName("run gen-bar 5"),
|
WithName("run gen-bar 5"),
|
||||||
WithExecutorOptions(
|
WithNodeDir(dir),
|
||||||
task.WithDir(dir),
|
|
||||||
),
|
|
||||||
WithTask("gen-bar"),
|
WithTask("gen-bar"),
|
||||||
)
|
)
|
||||||
// all: up-to-date
|
// all: up-to-date
|
||||||
NewExecutorTest(t,
|
NewExecutorTest(t,
|
||||||
WithName("run gen-bar 6"),
|
WithName("run gen-bar 6"),
|
||||||
WithExecutorOptions(
|
WithNodeDir(dir),
|
||||||
task.WithDir(dir),
|
|
||||||
),
|
|
||||||
WithTask("gen-bar"),
|
WithTask("gen-bar"),
|
||||||
)
|
)
|
||||||
// sources: not up-to-date, no output produced.
|
// sources: not up-to-date, no output produced.
|
||||||
NewExecutorTest(t,
|
NewExecutorTest(t,
|
||||||
WithName("run gen-baz 2"),
|
WithName("run gen-baz 2"),
|
||||||
WithExecutorOptions(
|
WithNodeDir(dir),
|
||||||
task.WithDir(dir),
|
|
||||||
),
|
|
||||||
WithTask("gen-silent-baz"),
|
WithTask("gen-silent-baz"),
|
||||||
)
|
)
|
||||||
// up-to-date, no output produced
|
// up-to-date, no output produced
|
||||||
NewExecutorTest(t,
|
NewExecutorTest(t,
|
||||||
WithName("run gen-baz 3"),
|
WithName("run gen-baz 3"),
|
||||||
WithExecutorOptions(
|
WithNodeDir(dir),
|
||||||
task.WithDir(dir),
|
|
||||||
),
|
|
||||||
WithTask("gen-silent-baz"),
|
WithTask("gen-silent-baz"),
|
||||||
)
|
)
|
||||||
// up-to-date, output produced due to Verbose mode.
|
// up-to-date, output produced due to Verbose mode.
|
||||||
NewExecutorTest(t,
|
NewExecutorTest(t,
|
||||||
WithName("run gen-baz 4 verbose"),
|
WithName("run gen-baz 4 verbose"),
|
||||||
|
WithNodeDir(dir),
|
||||||
WithExecutorOptions(
|
WithExecutorOptions(
|
||||||
task.WithDir(dir),
|
|
||||||
task.WithVerbose(true),
|
task.WithVerbose(true),
|
||||||
),
|
),
|
||||||
WithTask("gen-silent-baz"),
|
WithTask("gen-silent-baz"),
|
||||||
WithPostProcessFn(PPRemoveAbsolutePaths),
|
WithFixtureTemplating(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -560,32 +570,24 @@ func TestPrecondition(t *testing.T) {
|
|||||||
const dir = "testdata/precondition"
|
const dir = "testdata/precondition"
|
||||||
NewExecutorTest(t,
|
NewExecutorTest(t,
|
||||||
WithName("a precondition has been met"),
|
WithName("a precondition has been met"),
|
||||||
WithExecutorOptions(
|
WithNodeDir(dir),
|
||||||
task.WithDir(dir),
|
|
||||||
),
|
|
||||||
WithTask("foo"),
|
WithTask("foo"),
|
||||||
)
|
)
|
||||||
NewExecutorTest(t,
|
NewExecutorTest(t,
|
||||||
WithName("a precondition was not met"),
|
WithName("a precondition was not met"),
|
||||||
WithExecutorOptions(
|
WithNodeDir(dir),
|
||||||
task.WithDir(dir),
|
|
||||||
),
|
|
||||||
WithTask("impossible"),
|
WithTask("impossible"),
|
||||||
WithRunError(),
|
WithRunError(),
|
||||||
)
|
)
|
||||||
NewExecutorTest(t,
|
NewExecutorTest(t,
|
||||||
WithName("precondition in dependency fails the task"),
|
WithName("precondition in dependency fails the task"),
|
||||||
WithExecutorOptions(
|
WithNodeDir(dir),
|
||||||
task.WithDir(dir),
|
|
||||||
),
|
|
||||||
WithTask("depends_on_impossible"),
|
WithTask("depends_on_impossible"),
|
||||||
WithRunError(),
|
WithRunError(),
|
||||||
)
|
)
|
||||||
NewExecutorTest(t,
|
NewExecutorTest(t,
|
||||||
WithName("precondition in cmd fails the task"),
|
WithName("precondition in cmd fails the task"),
|
||||||
WithExecutorOptions(
|
WithNodeDir(dir),
|
||||||
task.WithDir(dir),
|
|
||||||
),
|
|
||||||
WithTask("executes_failing_task_as_cmd"),
|
WithTask("executes_failing_task_as_cmd"),
|
||||||
WithRunError(),
|
WithRunError(),
|
||||||
)
|
)
|
||||||
@@ -596,25 +598,21 @@ func TestAlias(t *testing.T) {
|
|||||||
|
|
||||||
NewExecutorTest(t,
|
NewExecutorTest(t,
|
||||||
WithName("alias"),
|
WithName("alias"),
|
||||||
WithExecutorOptions(
|
WithNodeDir("testdata/alias"),
|
||||||
task.WithDir("testdata/alias"),
|
|
||||||
),
|
|
||||||
WithTask("f"),
|
WithTask("f"),
|
||||||
)
|
)
|
||||||
|
|
||||||
NewExecutorTest(t,
|
NewExecutorTest(t,
|
||||||
WithName("duplicate alias"),
|
WithName("duplicate alias"),
|
||||||
WithExecutorOptions(
|
WithNodeDir("testdata/alias"),
|
||||||
task.WithDir("testdata/alias"),
|
|
||||||
),
|
|
||||||
WithTask("x"),
|
WithTask("x"),
|
||||||
WithRunError(),
|
WithRunError(),
|
||||||
)
|
)
|
||||||
|
|
||||||
NewExecutorTest(t,
|
NewExecutorTest(t,
|
||||||
WithName("alias summary"),
|
WithName("alias summary"),
|
||||||
|
WithNodeDir("testdata/alias"),
|
||||||
WithExecutorOptions(
|
WithExecutorOptions(
|
||||||
task.WithDir("testdata/alias"),
|
|
||||||
task.WithSummary(true),
|
task.WithSummary(true),
|
||||||
),
|
),
|
||||||
WithTask("f"),
|
WithTask("f"),
|
||||||
@@ -626,16 +624,14 @@ func TestLabel(t *testing.T) {
|
|||||||
|
|
||||||
NewExecutorTest(t,
|
NewExecutorTest(t,
|
||||||
WithName("up to date"),
|
WithName("up to date"),
|
||||||
WithExecutorOptions(
|
WithNodeDir("testdata/label_uptodate"),
|
||||||
task.WithDir("testdata/label_uptodate"),
|
|
||||||
),
|
|
||||||
WithTask("foo"),
|
WithTask("foo"),
|
||||||
)
|
)
|
||||||
|
|
||||||
NewExecutorTest(t,
|
NewExecutorTest(t,
|
||||||
WithName("summary"),
|
WithName("summary"),
|
||||||
|
WithNodeDir("testdata/label_summary"),
|
||||||
WithExecutorOptions(
|
WithExecutorOptions(
|
||||||
task.WithDir("testdata/label_summary"),
|
|
||||||
task.WithSummary(true),
|
task.WithSummary(true),
|
||||||
),
|
),
|
||||||
WithTask("foo"),
|
WithTask("foo"),
|
||||||
@@ -643,26 +639,20 @@ func TestLabel(t *testing.T) {
|
|||||||
|
|
||||||
NewExecutorTest(t,
|
NewExecutorTest(t,
|
||||||
WithName("status"),
|
WithName("status"),
|
||||||
WithExecutorOptions(
|
WithNodeDir("testdata/label_status"),
|
||||||
task.WithDir("testdata/label_status"),
|
|
||||||
),
|
|
||||||
WithTask("foo"),
|
WithTask("foo"),
|
||||||
WithStatusError(),
|
WithStatusError(),
|
||||||
)
|
)
|
||||||
|
|
||||||
NewExecutorTest(t,
|
NewExecutorTest(t,
|
||||||
WithName("var"),
|
WithName("var"),
|
||||||
WithExecutorOptions(
|
WithNodeDir("testdata/label_var"),
|
||||||
task.WithDir("testdata/label_var"),
|
|
||||||
),
|
|
||||||
WithTask("foo"),
|
WithTask("foo"),
|
||||||
)
|
)
|
||||||
|
|
||||||
NewExecutorTest(t,
|
NewExecutorTest(t,
|
||||||
WithName("label in summary"),
|
WithName("label in summary"),
|
||||||
WithExecutorOptions(
|
WithNodeDir("testdata/label_summary"),
|
||||||
task.WithDir("testdata/label_summary"),
|
|
||||||
),
|
|
||||||
WithTask("foo"),
|
WithTask("foo"),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -689,8 +679,8 @@ func TestPromptInSummary(t *testing.T) {
|
|||||||
|
|
||||||
opts := []ExecutorTestOption{
|
opts := []ExecutorTestOption{
|
||||||
WithName(test.name),
|
WithName(test.name),
|
||||||
|
WithNodeDir("testdata/prompt"),
|
||||||
WithExecutorOptions(
|
WithExecutorOptions(
|
||||||
task.WithDir("testdata/prompt"),
|
|
||||||
task.WithAssumeTerm(true),
|
task.WithAssumeTerm(true),
|
||||||
),
|
),
|
||||||
WithTask("foo"),
|
WithTask("foo"),
|
||||||
@@ -708,8 +698,8 @@ func TestPromptWithIndirectTask(t *testing.T) {
|
|||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
NewExecutorTest(t,
|
NewExecutorTest(t,
|
||||||
|
WithNodeDir("testdata/prompt"),
|
||||||
WithExecutorOptions(
|
WithExecutorOptions(
|
||||||
task.WithDir("testdata/prompt"),
|
|
||||||
task.WithAssumeTerm(true),
|
task.WithAssumeTerm(true),
|
||||||
),
|
),
|
||||||
WithTask("bar"),
|
WithTask("bar"),
|
||||||
@@ -722,8 +712,8 @@ func TestPromptAssumeYes(t *testing.T) {
|
|||||||
|
|
||||||
NewExecutorTest(t,
|
NewExecutorTest(t,
|
||||||
WithName("--yes flag should skip prompt"),
|
WithName("--yes flag should skip prompt"),
|
||||||
|
WithNodeDir("testdata/prompt"),
|
||||||
WithExecutorOptions(
|
WithExecutorOptions(
|
||||||
task.WithDir("testdata/prompt"),
|
|
||||||
task.WithAssumeTerm(true),
|
task.WithAssumeTerm(true),
|
||||||
task.WithAssumeYes(true),
|
task.WithAssumeYes(true),
|
||||||
),
|
),
|
||||||
@@ -733,8 +723,8 @@ func TestPromptAssumeYes(t *testing.T) {
|
|||||||
|
|
||||||
NewExecutorTest(t,
|
NewExecutorTest(t,
|
||||||
WithName("task should raise errors.TaskCancelledError"),
|
WithName("task should raise errors.TaskCancelledError"),
|
||||||
|
WithNodeDir("testdata/prompt"),
|
||||||
WithExecutorOptions(
|
WithExecutorOptions(
|
||||||
task.WithDir("testdata/prompt"),
|
|
||||||
task.WithAssumeTerm(true),
|
task.WithAssumeTerm(true),
|
||||||
),
|
),
|
||||||
WithTask("foo"),
|
WithTask("foo"),
|
||||||
@@ -771,13 +761,13 @@ func TestForCmds(t *testing.T) {
|
|||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
opts := []ExecutorTestOption{
|
opts := []ExecutorTestOption{
|
||||||
WithName(test.name),
|
WithName(test.name),
|
||||||
|
WithNodeDir("testdata/for/cmds"),
|
||||||
WithExecutorOptions(
|
WithExecutorOptions(
|
||||||
task.WithDir("testdata/for/cmds"),
|
|
||||||
task.WithSilent(true),
|
task.WithSilent(true),
|
||||||
task.WithForce(true),
|
task.WithForce(true),
|
||||||
),
|
),
|
||||||
WithTask(test.name),
|
WithTask(test.name),
|
||||||
WithPostProcessFn(PPRemoveAbsolutePaths),
|
WithFixtureTemplating(),
|
||||||
}
|
}
|
||||||
if test.wantErr {
|
if test.wantErr {
|
||||||
opts = append(opts, WithRunError())
|
opts = append(opts, WithRunError())
|
||||||
@@ -814,15 +804,15 @@ func TestForDeps(t *testing.T) {
|
|||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
opts := []ExecutorTestOption{
|
opts := []ExecutorTestOption{
|
||||||
WithName(test.name),
|
WithName(test.name),
|
||||||
|
WithNodeDir("testdata/for/deps"),
|
||||||
WithExecutorOptions(
|
WithExecutorOptions(
|
||||||
task.WithDir("testdata/for/deps"),
|
|
||||||
task.WithSilent(true),
|
task.WithSilent(true),
|
||||||
task.WithForce(true),
|
task.WithForce(true),
|
||||||
// Force output of each dep to be grouped together to prevent interleaving
|
// Force output of each dep to be grouped together to prevent interleaving
|
||||||
task.WithOutputStyle(ast.Output{Name: "group"}),
|
task.WithOutputStyle(ast.Output{Name: "group"}),
|
||||||
),
|
),
|
||||||
WithTask(test.name),
|
WithTask(test.name),
|
||||||
WithPostProcessFn(PPRemoveAbsolutePaths),
|
WithFixtureTemplating(),
|
||||||
WithPostProcessFn(PPSortedLines),
|
WithPostProcessFn(PPSortedLines),
|
||||||
}
|
}
|
||||||
if test.wantErr {
|
if test.wantErr {
|
||||||
@@ -860,8 +850,8 @@ func TestReference(t *testing.T) {
|
|||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
NewExecutorTest(t,
|
NewExecutorTest(t,
|
||||||
WithName(test.name),
|
WithName(test.name),
|
||||||
|
WithNodeDir("testdata/var_references"),
|
||||||
WithExecutorOptions(
|
WithExecutorOptions(
|
||||||
task.WithDir("testdata/var_references"),
|
|
||||||
task.WithSilent(true),
|
task.WithSilent(true),
|
||||||
task.WithForce(true),
|
task.WithForce(true),
|
||||||
),
|
),
|
||||||
@@ -928,8 +918,8 @@ func TestVarInheritance(t *testing.T) {
|
|||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
NewExecutorTest(t,
|
NewExecutorTest(t,
|
||||||
WithName(test.name),
|
WithName(test.name),
|
||||||
|
WithNodeDir(fmt.Sprintf("testdata/var_inheritance/v3/%s", test.name)),
|
||||||
WithExecutorOptions(
|
WithExecutorOptions(
|
||||||
task.WithDir(fmt.Sprintf("testdata/var_inheritance/v3/%s", test.name)),
|
|
||||||
task.WithSilent(true),
|
task.WithSilent(true),
|
||||||
task.WithForce(true),
|
task.WithForce(true),
|
||||||
),
|
),
|
||||||
@@ -943,20 +933,23 @@ func TestFuzzyModel(t *testing.T) {
|
|||||||
|
|
||||||
NewExecutorTest(t,
|
NewExecutorTest(t,
|
||||||
WithName("fuzzy"),
|
WithName("fuzzy"),
|
||||||
WithExecutorOptions(
|
WithNodeDir("testdata/fuzzy"),
|
||||||
task.WithDir("testdata/fuzzy"),
|
|
||||||
),
|
|
||||||
WithTask("instal"),
|
WithTask("instal"),
|
||||||
WithRunError(),
|
WithRunError(),
|
||||||
)
|
)
|
||||||
|
|
||||||
NewExecutorTest(t,
|
NewExecutorTest(t,
|
||||||
WithName("not-fuzzy"),
|
WithName("not-fuzzy"),
|
||||||
WithExecutorOptions(
|
WithNodeDir("testdata/fuzzy"),
|
||||||
task.WithDir("testdata/fuzzy"),
|
|
||||||
),
|
|
||||||
WithTask("install"),
|
WithTask("install"),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
NewExecutorTest(t,
|
||||||
|
WithName("intern"),
|
||||||
|
WithNodeDir("testdata/fuzzy"),
|
||||||
|
WithTask("intern"),
|
||||||
|
WithRunError(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestIncludeChecksum(t *testing.T) {
|
func TestIncludeChecksum(t *testing.T) {
|
||||||
@@ -964,17 +957,65 @@ func TestIncludeChecksum(t *testing.T) {
|
|||||||
|
|
||||||
NewExecutorTest(t,
|
NewExecutorTest(t,
|
||||||
WithName("correct"),
|
WithName("correct"),
|
||||||
WithExecutorOptions(
|
WithNodeDir("testdata/includes_checksum/correct"),
|
||||||
task.WithDir("testdata/includes_checksum/correct"),
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
NewExecutorTest(t,
|
NewExecutorTest(t,
|
||||||
WithName("incorrect"),
|
WithName("incorrect"),
|
||||||
WithExecutorOptions(
|
WithNodeDir("testdata/includes_checksum/incorrect"),
|
||||||
task.WithDir("testdata/includes_checksum/incorrect"),
|
WithReaderError(),
|
||||||
),
|
WithFixtureTemplating(),
|
||||||
WithSetupError(),
|
|
||||||
WithPostProcessFn(PPRemoveAbsolutePaths),
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestWildcard(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
call string
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "basic wildcard",
|
||||||
|
call: "wildcard-foo",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "double wildcard",
|
||||||
|
call: "foo-wildcard-bar",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "store wildcard",
|
||||||
|
call: "start-foo",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "matches exactly",
|
||||||
|
call: "matches-exactly-*",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "no matches",
|
||||||
|
call: "no-match",
|
||||||
|
wantErr: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "multiple matches",
|
||||||
|
call: "wildcard-foo-bar",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range tests {
|
||||||
|
opts := []ExecutorTestOption{
|
||||||
|
WithName(test.name),
|
||||||
|
WithNodeDir("testdata/wildcards"),
|
||||||
|
WithExecutorOptions(
|
||||||
|
task.WithSilent(true),
|
||||||
|
task.WithForce(true),
|
||||||
|
),
|
||||||
|
WithTask(test.call),
|
||||||
|
}
|
||||||
|
if test.wantErr {
|
||||||
|
opts = append(opts, WithRunError())
|
||||||
|
}
|
||||||
|
NewExecutorTest(t, opts...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,7 +2,9 @@ package task_test
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"context"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"slices"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/sebdah/goldie/v2"
|
"github.com/sebdah/goldie/v2"
|
||||||
@@ -10,6 +12,7 @@ import (
|
|||||||
|
|
||||||
"github.com/go-task/task/v3"
|
"github.com/go-task/task/v3"
|
||||||
"github.com/go-task/task/v3/experiments"
|
"github.com/go-task/task/v3/experiments"
|
||||||
|
"github.com/go-task/task/v3/taskfile"
|
||||||
"github.com/go-task/task/v3/taskfile/ast"
|
"github.com/go-task/task/v3/taskfile/ast"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -26,12 +29,17 @@ type (
|
|||||||
// running `task gen:fixtures`.
|
// running `task gen:fixtures`.
|
||||||
FormatterTest struct {
|
FormatterTest struct {
|
||||||
TaskTest
|
TaskTest
|
||||||
task string
|
task string
|
||||||
vars map[string]any
|
vars map[string]any
|
||||||
executorOpts []task.ExecutorOption
|
nodeDir string
|
||||||
listOptions task.ListOptions
|
nodeEntrypoint string
|
||||||
wantSetupError bool
|
nodeInsecure bool
|
||||||
wantListError bool
|
readerOpts []taskfile.ReaderOption
|
||||||
|
executorOpts []task.ExecutorOption
|
||||||
|
listOptions task.ListOptions
|
||||||
|
wantReaderError bool
|
||||||
|
wantSetupError bool
|
||||||
|
wantListError bool
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -41,10 +49,12 @@ type (
|
|||||||
func NewFormatterTest(t *testing.T, opts ...FormatterTestOption) {
|
func NewFormatterTest(t *testing.T, opts ...FormatterTestOption) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
tt := &FormatterTest{
|
tt := &FormatterTest{
|
||||||
task: "default",
|
task: "default",
|
||||||
vars: map[string]any{},
|
vars: map[string]any{},
|
||||||
|
nodeDir: ".",
|
||||||
TaskTest: TaskTest{
|
TaskTest: TaskTest{
|
||||||
experiments: map[*experiments.Experiment]int{},
|
experiments: map[*experiments.Experiment]int{},
|
||||||
|
fixtureTemplateData: map[string]any{},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
// Apply the functional options
|
// Apply the functional options
|
||||||
@@ -113,23 +123,57 @@ func (tt *FormatterTest) run(t *testing.T) {
|
|||||||
f := func(t *testing.T) {
|
f := func(t *testing.T) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
opts := append(
|
// Create a new root node for the given entrypoint
|
||||||
tt.executorOpts,
|
node, err := taskfile.NewRootNode(
|
||||||
task.WithStdout(&buf),
|
tt.nodeEntrypoint,
|
||||||
task.WithStderr(&buf),
|
tt.nodeDir,
|
||||||
|
tt.nodeInsecure,
|
||||||
)
|
)
|
||||||
|
require.NoError(t, err)
|
||||||
// Set up the task executor
|
|
||||||
e := task.NewExecutor(opts...)
|
|
||||||
|
|
||||||
// Create a golden fixture file for the output
|
// Create a golden fixture file for the output
|
||||||
g := goldie.New(t,
|
g := goldie.New(t,
|
||||||
goldie.WithFixtureDir(filepath.Join(e.Dir, "testdata")),
|
goldie.WithFixtureDir(filepath.Join(node.Dir(), "testdata")),
|
||||||
)
|
)
|
||||||
|
|
||||||
// Call setup and check for errors
|
// Set up a temporary directory for the taskfile reader and task executor
|
||||||
if err := e.Setup(); tt.wantSetupError {
|
tempDir, err := task.NewTempDir(node.Dir())
|
||||||
|
require.NoError(t, err)
|
||||||
|
tt.readerOpts = append(tt.readerOpts, taskfile.WithTempDir(tempDir.Remote))
|
||||||
|
|
||||||
|
// Set up the taskfile reader
|
||||||
|
reader := taskfile.NewReader(tt.readerOpts...)
|
||||||
|
graph, err := reader.Read(ctx, node)
|
||||||
|
if tt.wantReaderError {
|
||||||
|
require.Error(t, err)
|
||||||
|
tt.writeFixtureErrReader(t, g, err)
|
||||||
|
tt.writeFixtureBuffer(t, g, buf)
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
require.NoError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
executorOpts := slices.Concat(
|
||||||
|
// Apply the node directory and temp directory to the executor options
|
||||||
|
// by default, but allow them to by overridden by the test options
|
||||||
|
[]task.ExecutorOption{
|
||||||
|
task.WithDir(node.Dir()),
|
||||||
|
task.WithTempDir(tempDir),
|
||||||
|
},
|
||||||
|
// Apply the executor options from the test
|
||||||
|
tt.executorOpts,
|
||||||
|
// Force the input/output streams to be set to the test buffer
|
||||||
|
[]task.ExecutorOption{
|
||||||
|
task.WithStdout(&buf),
|
||||||
|
task.WithStderr(&buf),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
// Set up the task executor
|
||||||
|
executor, err := task.NewExecutor(graph, executorOpts...)
|
||||||
|
if tt.wantSetupError {
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
tt.writeFixtureErrSetup(t, g, err)
|
tt.writeFixtureErrSetup(t, g, err)
|
||||||
tt.writeFixtureBuffer(t, g, buf)
|
tt.writeFixtureBuffer(t, g, buf)
|
||||||
@@ -145,7 +189,7 @@ func (tt *FormatterTest) run(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Run the formatter and check for errors
|
// Run the formatter and check for errors
|
||||||
if _, err := e.ListTasks(tt.listOptions); tt.wantListError {
|
if _, err := executor.ListTasks(tt.listOptions); tt.wantListError {
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
tt.writeFixtureErrList(t, g, err)
|
tt.writeFixtureErrList(t, g, err)
|
||||||
tt.writeFixtureBuffer(t, g, buf)
|
tt.writeFixtureBuffer(t, g, buf)
|
||||||
@@ -169,9 +213,7 @@ func TestNoLabelInList(t *testing.T) {
|
|||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
NewFormatterTest(t,
|
NewFormatterTest(t,
|
||||||
WithExecutorOptions(
|
WithNodeDir("testdata/label_list"),
|
||||||
task.WithDir("testdata/label_list"),
|
|
||||||
),
|
|
||||||
WithListOptions(task.ListOptions{
|
WithListOptions(task.ListOptions{
|
||||||
ListOnlyTasksWithDescriptions: true,
|
ListOnlyTasksWithDescriptions: true,
|
||||||
}),
|
}),
|
||||||
@@ -183,9 +225,7 @@ func TestListAllShowsNoDesc(t *testing.T) {
|
|||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
NewFormatterTest(t,
|
NewFormatterTest(t,
|
||||||
WithExecutorOptions(
|
WithNodeDir("testdata/list_mixed_desc"),
|
||||||
task.WithDir("testdata/list_mixed_desc"),
|
|
||||||
),
|
|
||||||
WithListOptions(task.ListOptions{
|
WithListOptions(task.ListOptions{
|
||||||
ListAllTasks: true,
|
ListAllTasks: true,
|
||||||
}),
|
}),
|
||||||
@@ -197,9 +237,7 @@ func TestListCanListDescOnly(t *testing.T) {
|
|||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
NewFormatterTest(t,
|
NewFormatterTest(t,
|
||||||
WithExecutorOptions(
|
WithNodeDir("testdata/list_mixed_desc"),
|
||||||
task.WithDir("testdata/list_mixed_desc"),
|
|
||||||
),
|
|
||||||
WithListOptions(task.ListOptions{
|
WithListOptions(task.ListOptions{
|
||||||
ListOnlyTasksWithDescriptions: true,
|
ListOnlyTasksWithDescriptions: true,
|
||||||
}),
|
}),
|
||||||
@@ -210,9 +248,7 @@ func TestListDescInterpolation(t *testing.T) {
|
|||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
NewFormatterTest(t,
|
NewFormatterTest(t,
|
||||||
WithExecutorOptions(
|
WithNodeDir("testdata/list_desc_interpolation"),
|
||||||
task.WithDir("testdata/list_desc_interpolation"),
|
|
||||||
),
|
|
||||||
WithListOptions(task.ListOptions{
|
WithListOptions(task.ListOptions{
|
||||||
ListOnlyTasksWithDescriptions: true,
|
ListOnlyTasksWithDescriptions: true,
|
||||||
}),
|
}),
|
||||||
@@ -222,19 +258,11 @@ func TestListDescInterpolation(t *testing.T) {
|
|||||||
func TestJsonListFormat(t *testing.T) {
|
func TestJsonListFormat(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
fp, err := filepath.Abs("testdata/json_list_format/Taskfile.yml")
|
|
||||||
require.NoError(t, err)
|
|
||||||
NewFormatterTest(t,
|
NewFormatterTest(t,
|
||||||
WithExecutorOptions(
|
WithNodeDir("testdata/json_list_format"),
|
||||||
task.WithDir("testdata/json_list_format"),
|
|
||||||
),
|
|
||||||
WithListOptions(task.ListOptions{
|
WithListOptions(task.ListOptions{
|
||||||
FormatTaskListAsJSON: true,
|
FormatTaskListAsJSON: true,
|
||||||
}),
|
}),
|
||||||
WithFixtureTemplateData(struct {
|
WithFixtureTemplating(),
|
||||||
TaskfileLocation string
|
|
||||||
}{
|
|
||||||
TaskfileLocation: fp,
|
|
||||||
}),
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
20
go.mod
20
go.mod
@@ -4,8 +4,8 @@ go 1.23.0
|
|||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/Ladicle/tabwriter v1.0.0
|
github.com/Ladicle/tabwriter v1.0.0
|
||||||
github.com/Masterminds/semver/v3 v3.3.1
|
github.com/Masterminds/semver/v3 v3.4.0
|
||||||
github.com/alecthomas/chroma/v2 v2.18.0
|
github.com/alecthomas/chroma/v2 v2.20.0
|
||||||
github.com/chainguard-dev/git-urls v1.0.2
|
github.com/chainguard-dev/git-urls v1.0.2
|
||||||
github.com/davecgh/go-spew v1.1.1
|
github.com/davecgh/go-spew v1.1.1
|
||||||
github.com/dominikbraun/graph v0.23.0
|
github.com/dominikbraun/graph v0.23.0
|
||||||
@@ -13,23 +13,23 @@ require (
|
|||||||
github.com/fatih/color v1.18.0
|
github.com/fatih/color v1.18.0
|
||||||
github.com/fsnotify/fsnotify v1.9.0
|
github.com/fsnotify/fsnotify v1.9.0
|
||||||
github.com/go-git/go-billy/v5 v5.6.2
|
github.com/go-git/go-billy/v5 v5.6.2
|
||||||
github.com/go-git/go-git/v5 v5.16.0
|
github.com/go-git/go-git/v5 v5.16.2
|
||||||
github.com/go-task/slim-sprig/v3 v3.0.0
|
github.com/go-task/slim-sprig/v3 v3.0.0
|
||||||
github.com/go-task/template v0.1.0
|
github.com/go-task/template v0.2.0
|
||||||
github.com/google/uuid v1.6.0
|
github.com/google/uuid v1.6.0
|
||||||
github.com/joho/godotenv v1.5.1
|
github.com/joho/godotenv v1.5.1
|
||||||
github.com/mitchellh/hashstructure/v2 v2.0.2
|
github.com/mitchellh/hashstructure/v2 v2.0.2
|
||||||
github.com/otiai10/copy v1.14.1
|
github.com/otiai10/copy v1.14.1
|
||||||
github.com/puzpuzpuz/xsync/v3 v3.5.1
|
github.com/puzpuzpuz/xsync/v3 v3.5.1
|
||||||
github.com/sajari/fuzzy v1.0.0
|
github.com/sajari/fuzzy v1.0.0
|
||||||
github.com/sebdah/goldie/v2 v2.5.5
|
github.com/sebdah/goldie/v2 v2.7.1
|
||||||
github.com/spf13/pflag v1.0.6
|
github.com/spf13/pflag v1.0.7
|
||||||
github.com/stretchr/testify v1.10.0
|
github.com/stretchr/testify v1.10.0
|
||||||
github.com/zeebo/xxh3 v1.0.2
|
github.com/zeebo/xxh3 v1.0.2
|
||||||
golang.org/x/sync v0.14.0
|
golang.org/x/sync v0.16.0
|
||||||
golang.org/x/term v0.32.0
|
golang.org/x/term v0.33.0
|
||||||
gopkg.in/yaml.v3 v3.0.1
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
mvdan.cc/sh/v3 v3.11.0
|
mvdan.cc/sh/v3 v3.12.0
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
@@ -56,6 +56,6 @@ require (
|
|||||||
github.com/xanzy/ssh-agent v0.3.3 // indirect
|
github.com/xanzy/ssh-agent v0.3.3 // indirect
|
||||||
golang.org/x/crypto v0.37.0 // indirect
|
golang.org/x/crypto v0.37.0 // indirect
|
||||||
golang.org/x/net v0.39.0 // indirect
|
golang.org/x/net v0.39.0 // indirect
|
||||||
golang.org/x/sys v0.33.0 // indirect
|
golang.org/x/sys v0.34.0 // indirect
|
||||||
gopkg.in/warnings.v0 v0.1.2 // indirect
|
gopkg.in/warnings.v0 v0.1.2 // indirect
|
||||||
)
|
)
|
||||||
|
|||||||
42
go.sum
42
go.sum
@@ -2,8 +2,8 @@ dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk=
|
|||||||
dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
|
dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
|
||||||
github.com/Ladicle/tabwriter v1.0.0 h1:DZQqPvMumBDwVNElso13afjYLNp0Z7pHqHnu0r4t9Dg=
|
github.com/Ladicle/tabwriter v1.0.0 h1:DZQqPvMumBDwVNElso13afjYLNp0Z7pHqHnu0r4t9Dg=
|
||||||
github.com/Ladicle/tabwriter v1.0.0/go.mod h1:c4MdCjxQyTbGuQO/gvqJ+IA/89UEwrsD6hUCW98dyp4=
|
github.com/Ladicle/tabwriter v1.0.0/go.mod h1:c4MdCjxQyTbGuQO/gvqJ+IA/89UEwrsD6hUCW98dyp4=
|
||||||
github.com/Masterminds/semver/v3 v3.3.1 h1:QtNSWtVZ3nBfk8mAOu/B6v7FMJ+NHTIgUPi7rj+4nv4=
|
github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0=
|
||||||
github.com/Masterminds/semver/v3 v3.3.1/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
|
github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
|
||||||
github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
|
github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
|
||||||
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
|
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
|
||||||
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
|
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
|
||||||
@@ -11,8 +11,10 @@ github.com/ProtonMail/go-crypto v1.1.6 h1:ZcV+Ropw6Qn0AX9brlQLAUXfqLBc7Bl+f/DmNx
|
|||||||
github.com/ProtonMail/go-crypto v1.1.6/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE=
|
github.com/ProtonMail/go-crypto v1.1.6/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE=
|
||||||
github.com/alecthomas/assert/v2 v2.11.0 h1:2Q9r3ki8+JYXvGsDyBXwH3LcJ+WK5D0gc5E8vS6K3D0=
|
github.com/alecthomas/assert/v2 v2.11.0 h1:2Q9r3ki8+JYXvGsDyBXwH3LcJ+WK5D0gc5E8vS6K3D0=
|
||||||
github.com/alecthomas/assert/v2 v2.11.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k=
|
github.com/alecthomas/assert/v2 v2.11.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k=
|
||||||
github.com/alecthomas/chroma/v2 v2.18.0 h1:6h53Q4hW83SuF+jcsp7CVhLsMozzvQvO8HBbKQW+gn4=
|
github.com/alecthomas/chroma/v2 v2.19.0 h1:Im+SLRgT8maArxv81mULDWN8oKxkzboH07CHesxElq4=
|
||||||
github.com/alecthomas/chroma/v2 v2.18.0/go.mod h1:RVX6AvYm4VfYe/zsk7mjHueLDZor3aWCNE14TFlepBk=
|
github.com/alecthomas/chroma/v2 v2.19.0/go.mod h1:RVX6AvYm4VfYe/zsk7mjHueLDZor3aWCNE14TFlepBk=
|
||||||
|
github.com/alecthomas/chroma/v2 v2.20.0 h1:sfIHpxPyR07/Oylvmcai3X/exDlE8+FA820NTz+9sGw=
|
||||||
|
github.com/alecthomas/chroma/v2 v2.20.0/go.mod h1:e7tViK0xh/Nf4BYHl00ycY6rV7b8iXBksI9E359yNmA=
|
||||||
github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc=
|
github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc=
|
||||||
github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=
|
github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=
|
||||||
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8=
|
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8=
|
||||||
@@ -52,14 +54,14 @@ github.com/go-git/go-billy/v5 v5.6.2 h1:6Q86EsPXMa7c3YZ3aLAQsMA0VlWmy43r6FHqa/UN
|
|||||||
github.com/go-git/go-billy/v5 v5.6.2/go.mod h1:rcFC2rAsp/erv7CMz9GczHcuD0D32fWzH+MJAU+jaUU=
|
github.com/go-git/go-billy/v5 v5.6.2/go.mod h1:rcFC2rAsp/erv7CMz9GczHcuD0D32fWzH+MJAU+jaUU=
|
||||||
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4=
|
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4=
|
||||||
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII=
|
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII=
|
||||||
github.com/go-git/go-git/v5 v5.16.0 h1:k3kuOEpkc0DeY7xlL6NaaNg39xdgQbtH5mwCafHO9AQ=
|
github.com/go-git/go-git/v5 v5.16.2 h1:fT6ZIOjE5iEnkzKyxTHK1W4HGAsPhqEqiSAssSO77hM=
|
||||||
github.com/go-git/go-git/v5 v5.16.0/go.mod h1:4Ge4alE/5gPs30F2H1esi2gPd69R0C39lolkucHBOp8=
|
github.com/go-git/go-git/v5 v5.16.2/go.mod h1:4Ge4alE/5gPs30F2H1esi2gPd69R0C39lolkucHBOp8=
|
||||||
github.com/go-quicktest/qt v1.101.0 h1:O1K29Txy5P2OK0dGo59b7b0LR6wKfIhttaAhHUyn7eI=
|
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-quicktest/qt v1.101.0/go.mod h1:14Bz/f7NwaXPtdYEgzsx46kqSxVwTbzVZsDC26tQJow=
|
||||||
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
|
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
|
||||||
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
|
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
|
||||||
github.com/go-task/template v0.1.0 h1:ym/r2G937RZA1bsgiWedNnY9e5kxDT+3YcoAnuIetTE=
|
github.com/go-task/template v0.2.0 h1:xW7ek0o65FUSTbKcSNeg2Vyf/I7wYXFgLUznptvviBE=
|
||||||
github.com/go-task/template v0.1.0/go.mod h1:RgwRaZK+kni/hJJ7/AaOE2lPQFPbAdji/DyhC6pxo4k=
|
github.com/go-task/template v0.2.0/go.mod h1:dbdoUb6qKnHQi1y6o+IdIrs0J4o/SEhSTA6bbzZmdtc=
|
||||||
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ=
|
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/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw=
|
||||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||||
@@ -109,16 +111,16 @@ github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0t
|
|||||||
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
|
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
|
||||||
github.com/sajari/fuzzy v1.0.0 h1:+FmwVvJErsd0d0hAPlj4CxqxUtQY/fOoY0DwX4ykpRY=
|
github.com/sajari/fuzzy v1.0.0 h1:+FmwVvJErsd0d0hAPlj4CxqxUtQY/fOoY0DwX4ykpRY=
|
||||||
github.com/sajari/fuzzy v1.0.0/go.mod h1:OjYR6KxoWOe9+dOlXeiCJd4dIbED4Oo8wpS89o0pwOo=
|
github.com/sajari/fuzzy v1.0.0/go.mod h1:OjYR6KxoWOe9+dOlXeiCJd4dIbED4Oo8wpS89o0pwOo=
|
||||||
github.com/sebdah/goldie/v2 v2.5.5 h1:rx1mwF95RxZ3/83sdS4Yp7t2C5TCokvWP4TBRbAyEWY=
|
github.com/sebdah/goldie/v2 v2.7.1 h1:PkBHymaYdtvEkZV7TmyqKxdmn5/Vcj+8TpATWZjnG5E=
|
||||||
github.com/sebdah/goldie/v2 v2.5.5/go.mod h1:oZ9fp0+se1eapSRjfYbsV/0Hqhbuu3bJVvKI/NNtssI=
|
github.com/sebdah/goldie/v2 v2.7.1/go.mod h1:oZ9fp0+se1eapSRjfYbsV/0Hqhbuu3bJVvKI/NNtssI=
|
||||||
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||||
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8=
|
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8=
|
||||||
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4=
|
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4=
|
||||||
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||||
github.com/skeema/knownhosts v1.3.1 h1:X2osQ+RAjK76shCbvhHHHVl3ZlgDm8apHEHFqRjnBY8=
|
github.com/skeema/knownhosts v1.3.1 h1:X2osQ+RAjK76shCbvhHHHVl3ZlgDm8apHEHFqRjnBY8=
|
||||||
github.com/skeema/knownhosts v1.3.1/go.mod h1:r7KTdC8l4uxWRyK2TpQZ/1o5HaSzh06ePQNxPwTcfiY=
|
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.7 h1:vN6T9TfwStFPFM5XzjsvmzZkLuaLX+HS+0SeFLRgU6M=
|
||||||
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
github.com/spf13/pflag v1.0.7/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
|
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
|
||||||
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
||||||
@@ -141,8 +143,8 @@ golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbR
|
|||||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY=
|
golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY=
|
||||||
golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E=
|
golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E=
|
||||||
golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ=
|
golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw=
|
||||||
golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
golang.org/x/sync v0.16.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-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-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
@@ -152,11 +154,11 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
|
golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA=
|
||||||
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.32.0 h1:DR4lr0TjUs3epypdhTOkMmuF5CDFJ/8pOnbzMZPQ7bg=
|
golang.org/x/term v0.33.0 h1:NuFncQrRcaRvVmgRkvM3j/F00gWIAlcmlB8ACEKmGIg=
|
||||||
golang.org/x/term v0.32.0/go.mod h1:uZG1FhGx848Sqfsq4/DlJr3xGGsYMu/L5GW4abiaEPQ=
|
golang.org/x/term v0.33.0/go.mod h1:s18+ql9tYWp1IfpV9DmCtQDDSRBUjKaw9M1eAv5UeF0=
|
||||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0=
|
golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0=
|
||||||
golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU=
|
golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU=
|
||||||
@@ -171,5 +173,5 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|||||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
mvdan.cc/sh/v3 v3.11.0 h1:q5h+XMDRfUGUedCqFFsjoFjrhwf2Mvtt1rkMvVz0blw=
|
mvdan.cc/sh/v3 v3.12.0 h1:ejKUR7ONP5bb+UGHGEG/k9V5+pRVIyD+LsZz7o8KHrI=
|
||||||
mvdan.cc/sh/v3 v3.11.0/go.mod h1:LRM+1NjoYCzuq/WZ6y44x14YNAI0NK7FLPeQSaFagGg=
|
mvdan.cc/sh/v3 v3.12.0/go.mod h1:Se6Cj17eYSn+sNooLZiEUnNNmNxg0imoYlTu4CyaGyg=
|
||||||
|
|||||||
@@ -64,21 +64,15 @@ get_binaries() {
|
|||||||
case "$PLATFORM" in
|
case "$PLATFORM" in
|
||||||
darwin/amd64) BINARIES="task" ;;
|
darwin/amd64) BINARIES="task" ;;
|
||||||
darwin/arm64) BINARIES="task" ;;
|
darwin/arm64) BINARIES="task" ;;
|
||||||
darwin/armv5) BINARIES="task" ;;
|
darwin/arm) BINARIES="task" ;;
|
||||||
darwin/armv6) BINARIES="task" ;;
|
|
||||||
darwin/armv7) BINARIES="task" ;;
|
|
||||||
linux/386) BINARIES="task" ;;
|
linux/386) BINARIES="task" ;;
|
||||||
linux/amd64) BINARIES="task" ;;
|
linux/amd64) BINARIES="task" ;;
|
||||||
linux/arm64) BINARIES="task" ;;
|
linux/arm64) BINARIES="task" ;;
|
||||||
linux/armv5) BINARIES="task" ;;
|
linux/arm) BINARIES="task" ;;
|
||||||
linux/armv6) BINARIES="task" ;;
|
|
||||||
linux/armv7) BINARIES="task" ;;
|
|
||||||
windows/386) BINARIES="task" ;;
|
windows/386) BINARIES="task" ;;
|
||||||
windows/amd64) BINARIES="task" ;;
|
windows/amd64) BINARIES="task" ;;
|
||||||
windows/arm64) BINARIES="task" ;;
|
windows/arm64) BINARIES="task" ;;
|
||||||
windows/armv5) BINARIES="task" ;;
|
windows/arm) BINARIES="task" ;;
|
||||||
windows/armv6) BINARIES="task" ;;
|
|
||||||
windows/armv7) BINARIES="task" ;;
|
|
||||||
*)
|
*)
|
||||||
log_crit "platform $PLATFORM is not supported. Make sure this script is up-to-date and file request at https://github.com/${PREFIX}/issues/new"
|
log_crit "platform $PLATFORM is not supported. Make sure this script is up-to-date and file request at https://github.com/${PREFIX}/issues/new"
|
||||||
exit 1
|
exit 1
|
||||||
|
|||||||
@@ -90,6 +90,15 @@ func RunCommand(ctx context.Context, opts *RunCommandOptions) error {
|
|||||||
return r.Run(ctx, p)
|
return r.Run(ctx, p)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func escape(s string) string {
|
||||||
|
s = filepath.ToSlash(s)
|
||||||
|
s = strings.ReplaceAll(s, " ", `\ `)
|
||||||
|
s = strings.ReplaceAll(s, "&", `\&`)
|
||||||
|
s = strings.ReplaceAll(s, "(", `\(`)
|
||||||
|
s = strings.ReplaceAll(s, ")", `\)`)
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
// ExpandLiteral is a wrapper around [expand.Literal]. It will escape the input
|
// ExpandLiteral is a wrapper around [expand.Literal]. It will escape the input
|
||||||
// string, expand any shell symbols (such as '~') and resolve any environment
|
// string, expand any shell symbols (such as '~') and resolve any environment
|
||||||
// variables.
|
// variables.
|
||||||
@@ -115,6 +124,7 @@ func ExpandLiteral(s string) (string, error) {
|
|||||||
// variables. It also expands brace expressions ({a.b}) and globs (*/**) and
|
// variables. It also expands brace expressions ({a.b}) and globs (*/**) and
|
||||||
// returns the results as a list of strings.
|
// returns the results as a list of strings.
|
||||||
func ExpandFields(s string) ([]string, error) {
|
func ExpandFields(s string) ([]string, error) {
|
||||||
|
s = escape(s)
|
||||||
p := syntax.NewParser()
|
p := syntax.NewParser()
|
||||||
var words []*syntax.Word
|
var words []*syntax.Word
|
||||||
err := p.Words(strings.NewReader(s), func(w *syntax.Word) bool {
|
err := p.Words(strings.NewReader(s), func(w *syntax.Word) bool {
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import (
|
|||||||
"github.com/go-task/task/v3/experiments"
|
"github.com/go-task/task/v3/experiments"
|
||||||
"github.com/go-task/task/v3/internal/env"
|
"github.com/go-task/task/v3/internal/env"
|
||||||
"github.com/go-task/task/v3/internal/sort"
|
"github.com/go-task/task/v3/internal/sort"
|
||||||
|
"github.com/go-task/task/v3/taskfile"
|
||||||
"github.com/go-task/task/v3/taskfile/ast"
|
"github.com/go-task/task/v3/taskfile/ast"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -201,7 +202,7 @@ func Validate() error {
|
|||||||
|
|
||||||
// WithFlags is a special internal functional option that is used to pass flags
|
// WithFlags is a special internal functional option that is used to pass flags
|
||||||
// from the CLI into any constructor that accepts functional options.
|
// from the CLI into any constructor that accepts functional options.
|
||||||
func WithFlags() task.ExecutorOption {
|
func WithFlags() *flagsOption {
|
||||||
return &flagsOption{}
|
return &flagsOption{}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -228,14 +229,8 @@ func (o *flagsOption) ApplyToExecutor(e *task.Executor) {
|
|||||||
|
|
||||||
e.Options(
|
e.Options(
|
||||||
task.WithDir(dir),
|
task.WithDir(dir),
|
||||||
task.WithEntrypoint(Entrypoint),
|
|
||||||
task.WithForce(Force),
|
task.WithForce(Force),
|
||||||
task.WithForceAll(ForceAll),
|
task.WithForceAll(ForceAll),
|
||||||
task.WithInsecure(Insecure),
|
|
||||||
task.WithDownload(Download),
|
|
||||||
task.WithOffline(Offline),
|
|
||||||
task.WithTimeout(Timeout),
|
|
||||||
task.WithCacheExpiryDuration(CacheExpiryDuration),
|
|
||||||
task.WithWatch(Watch),
|
task.WithWatch(Watch),
|
||||||
task.WithVerbose(Verbose),
|
task.WithVerbose(Verbose),
|
||||||
task.WithSilent(Silent),
|
task.WithSilent(Silent),
|
||||||
@@ -251,3 +246,12 @@ func (o *flagsOption) ApplyToExecutor(e *task.Executor) {
|
|||||||
task.WithVersionCheck(true),
|
task.WithVersionCheck(true),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (o *flagsOption) ApplyToReader(r *taskfile.Reader) {
|
||||||
|
r.Options(
|
||||||
|
taskfile.WithInsecure(Insecure),
|
||||||
|
taskfile.WithDownload(Download),
|
||||||
|
taskfile.WithOffline(Offline),
|
||||||
|
taskfile.WithCacheExpiryDuration(CacheExpiryDuration),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|||||||
@@ -41,7 +41,6 @@ func init() {
|
|||||||
"toYaml": toYaml,
|
"toYaml": toYaml,
|
||||||
"mustToYaml": mustToYaml,
|
"mustToYaml": mustToYaml,
|
||||||
"uuid": uuid.New,
|
"uuid": uuid.New,
|
||||||
"randInt": rand.Int,
|
|
||||||
"randIntN": rand.IntN,
|
"randIntN": rand.IntN,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
3.44.0
|
3.44.1
|
||||||
|
|||||||
2
package-lock.json
generated
2
package-lock.json
generated
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@go-task/cli",
|
"name": "@go-task/cli",
|
||||||
"version": "3.44.0",
|
"version": "3.44.1",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@go-task/cli",
|
"name": "@go-task/cli",
|
||||||
"version": "3.44.0",
|
"version": "3.44.1",
|
||||||
"description": "A task runner / simpler Make alternative written in Go",
|
"description": "A task runner / simpler Make alternative written in Go",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"postinstall": "go-npm install",
|
"postinstall": "go-npm install",
|
||||||
|
|||||||
9
task.go
9
task.go
@@ -220,13 +220,13 @@ func (e *Executor) RunTask(ctx context.Context, call *Call) error {
|
|||||||
e.Logger.VerboseErrf(logger.Yellow, "task: error cleaning status on error: %v\n", err2)
|
e.Logger.VerboseErrf(logger.Yellow, "task: error cleaning status on error: %v\n", err2)
|
||||||
}
|
}
|
||||||
|
|
||||||
exitCode, isExitError := interp.IsExitStatus(err)
|
var exitCode interp.ExitStatus
|
||||||
if isExitError {
|
if errors.As(err, &exitCode) {
|
||||||
if t.IgnoreError {
|
if t.IgnoreError {
|
||||||
e.Logger.VerboseErrf(logger.Yellow, "task: task error ignored: %v\n", err)
|
e.Logger.VerboseErrf(logger.Yellow, "task: task error ignored: %v\n", err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
deferredExitCode = exitCode
|
deferredExitCode = uint8(exitCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
if call.Indirect {
|
if call.Indirect {
|
||||||
@@ -356,7 +356,8 @@ func (e *Executor) runCommand(ctx context.Context, t *ast.Task, call *Call, i in
|
|||||||
if closeErr := closer(err); closeErr != nil {
|
if closeErr := closer(err); closeErr != nil {
|
||||||
e.Logger.Errf(logger.Red, "task: unable to close writer: %v\n", closeErr)
|
e.Logger.Errf(logger.Red, "task: unable to close writer: %v\n", closeErr)
|
||||||
}
|
}
|
||||||
if _, isExitError := interp.IsExitStatus(err); isExitError && cmd.IgnoreError {
|
var exitCode interp.ExitStatus
|
||||||
|
if errors.As(err, &exitCode) && cmd.IgnoreError {
|
||||||
e.Logger.VerboseErrf(logger.Yellow, "task: [%s] command error ignored: %v\n", t.Name(), err)
|
e.Logger.VerboseErrf(logger.Yellow, "task: [%s] command error ignored: %v\n", t.Name(), err)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
4575
task_test.go
4575
task_test.go
File diff suppressed because it is too large
Load Diff
@@ -3,7 +3,6 @@ package taskfile
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
|
||||||
|
|
||||||
giturls "github.com/chainguard-dev/git-urls"
|
giturls "github.com/chainguard-dev/git-urls"
|
||||||
|
|
||||||
@@ -33,7 +32,6 @@ func NewRootNode(
|
|||||||
entrypoint string,
|
entrypoint string,
|
||||||
dir string,
|
dir string,
|
||||||
insecure bool,
|
insecure bool,
|
||||||
timeout time.Duration,
|
|
||||||
) (Node, error) {
|
) (Node, error) {
|
||||||
dir = fsext.DefaultDir(entrypoint, dir)
|
dir = fsext.DefaultDir(entrypoint, dir)
|
||||||
// If the entrypoint is "-", we read from stdin
|
// If the entrypoint is "-", we read from stdin
|
||||||
|
|||||||
78
temp_dir.go
Normal file
78
temp_dir.go
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
package task
|
||||||
|
|
||||||
|
import (
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/go-task/task/v3/internal/env"
|
||||||
|
"github.com/go-task/task/v3/internal/execext"
|
||||||
|
"github.com/go-task/task/v3/internal/filepathext"
|
||||||
|
)
|
||||||
|
|
||||||
|
type TempDir struct {
|
||||||
|
Remote string
|
||||||
|
Fingerprint string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewTempDir(dir string) (*TempDir, error) {
|
||||||
|
tempDir, err := setupTempDirFingerprint(dir)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = setupTempDirRemote(dir, tempDir)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return tempDir, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func setupTempDirFingerprint(dir string) (*TempDir, error) {
|
||||||
|
tempDir := env.GetTaskEnv("TEMP_DIR")
|
||||||
|
|
||||||
|
if tempDir == "" {
|
||||||
|
return &TempDir{
|
||||||
|
Remote: filepathext.SmartJoin(dir, ".task"),
|
||||||
|
Fingerprint: filepathext.SmartJoin(dir, ".task"),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if filepath.IsAbs(tempDir) || strings.HasPrefix(tempDir, "~") {
|
||||||
|
tempDir, err := execext.ExpandLiteral(tempDir)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
projectDir, _ := filepath.Abs(dir)
|
||||||
|
projectName := filepath.Base(projectDir)
|
||||||
|
return &TempDir{
|
||||||
|
Remote: tempDir,
|
||||||
|
Fingerprint: filepathext.SmartJoin(tempDir, projectName),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return &TempDir{
|
||||||
|
Remote: filepathext.SmartJoin(dir, tempDir),
|
||||||
|
Fingerprint: filepathext.SmartJoin(dir, tempDir),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func setupTempDirRemote(dir string, tempDir *TempDir) error {
|
||||||
|
remoteDir := env.GetTaskEnv("REMOTE_DIR")
|
||||||
|
|
||||||
|
if remoteDir == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if filepath.IsAbs(remoteDir) || strings.HasPrefix(remoteDir, "~") {
|
||||||
|
remoteTempDir, err := execext.ExpandLiteral(remoteDir)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
tempDir.Remote = remoteTempDir
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
tempDir.Remote = filepathext.SmartJoin(dir, ".task")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
1
testdata/empty_taskfile/testdata/TestEmptyTaskfile-err-reader.golden
vendored
Normal file
1
testdata/empty_taskfile/testdata/TestEmptyTaskfile-err-reader.golden
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
task: Missing schema version in Taskfile "{{.TEST_DIR}}/testdata/empty_taskfile/Taskfile.yml"
|
||||||
@@ -1 +0,0 @@
|
|||||||
task: Missing schema version in Taskfile "/testdata/empty_taskfile/Taskfile.yml"
|
|
||||||
@@ -1,2 +1,2 @@
|
|||||||
task: Failed to parse /testdata/for/cmds/Taskfile.yml:
|
task: Failed to parse {{.TEST_DIR}}/testdata/for/cmds/Taskfile.yml:
|
||||||
matrix reference ".NOT_A_LIST" must resolve to a list
|
matrix reference ".NOT_A_LIST" must resolve to a list
|
||||||
@@ -1,2 +1,2 @@
|
|||||||
matrix reference ".NOT_A_LIST" must resolve to a list
|
matrix reference ".NOT_A_LIST" must resolve to a list
|
||||||
task: Failed to parse /testdata/for/deps/Taskfile.yml:
|
task: Failed to parse {{.TEST_DIR}}/testdata/for/deps/Taskfile.yml:
|
||||||
|
|||||||
5
testdata/fuzzy/Taskfile.yml
vendored
5
testdata/fuzzy/Taskfile.yml
vendored
@@ -2,3 +2,8 @@ version: 3
|
|||||||
|
|
||||||
tasks:
|
tasks:
|
||||||
install: echo 'install'
|
install: echo 'install'
|
||||||
|
|
||||||
|
internal:
|
||||||
|
internal: true
|
||||||
|
cmds:
|
||||||
|
- echo "internal"
|
||||||
|
|||||||
1
testdata/fuzzy/testdata/TestFuzzyModel-intern-err-run.golden
vendored
Normal file
1
testdata/fuzzy/testdata/TestFuzzyModel-intern-err-run.golden
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
task: Task "intern" does not exist
|
||||||
1
testdata/fuzzy/testdata/TestFuzzyModel-intern.golden
vendored
Normal file
1
testdata/fuzzy/testdata/TestFuzzyModel-intern.golden
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
task: No tasks with description available. Try --list-all to list all tasks
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
task: The checksum of the Taskfile at "{{.TEST_DIR}}/testdata/includes_checksum/included.yml" does not match!
|
||||||
|
got: "c97f39eb96fe3fa5fe2a610d244b8449897b06f0c93821484af02e0999781bf5"
|
||||||
|
want: "foo"
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
task: The checksum of the Taskfile at "/testdata/includes_checksum/included.yml" does not match!
|
|
||||||
got: "c97f39eb96fe3fa5fe2a610d244b8449897b06f0c93821484af02e0999781bf5"
|
|
||||||
want: "foo"
|
|
||||||
@@ -10,9 +10,9 @@
|
|||||||
"location": {
|
"location": {
|
||||||
"line": 4,
|
"line": 4,
|
||||||
"column": 3,
|
"column": 3,
|
||||||
"taskfile": "{{ .TaskfileLocation }}"
|
"taskfile": "{{.TEST_DIR}}/testdata/json_list_format/Taskfile.yml"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"location": "{{ .TaskfileLocation }}"
|
"location": "{{.TEST_DIR}}/testdata/json_list_format/Taskfile.yml"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
/testdata/special_vars
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/testdata/special_vars/included
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/testdata/special_vars/included/Taskfile.yml
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/testdata/special_vars
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/testdata/special_vars/foo
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/testdata/special_vars
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/testdata/special_vars/Taskfile.yml
|
|
||||||
@@ -1 +1 @@
|
|||||||
/testdata/special_vars
|
{{.TEST_DIR}}/testdata/special_vars
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
/testdata/special_vars/included
|
{{.TEST_DIR}}/testdata/special_vars/included
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
/testdata/special_vars/included/Taskfile.yml
|
{{.TEST_DIR}}/testdata/special_vars/included/Taskfile.yml
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
/testdata/special_vars
|
{{.TEST_DIR}}/testdata/special_vars
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
/testdata/special_vars/foo
|
{{.TEST_DIR}}/testdata/special_vars/foo
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
/testdata/special_vars
|
{{.TEST_DIR}}/testdata/special_vars
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
/testdata/special_vars/Taskfile.yml
|
{{.TEST_DIR}}/testdata/special_vars/Taskfile.yml
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
{{.TEST_DIR}}/testdata/special_vars
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{{.TEST_DIR}}/testdata/special_vars/included
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{{.TEST_DIR}}/testdata/special_vars/included/Taskfile.yml
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{{.TEST_DIR}}/testdata/special_vars
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{{.TEST_DIR}}/testdata/special_vars/foo
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{{.TEST_DIR}}/testdata/special_vars
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{{.TEST_DIR}}/testdata/special_vars/Taskfile.yml
|
||||||
1
testdata/wildcards/testdata/TestWildcard-basic_wildcard.golden
vendored
Normal file
1
testdata/wildcards/testdata/TestWildcard-basic_wildcard.golden
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
Hello foo
|
||||||
1
testdata/wildcards/testdata/TestWildcard-double_wildcard.golden
vendored
Normal file
1
testdata/wildcards/testdata/TestWildcard-double_wildcard.golden
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
Hello foo bar
|
||||||
1
testdata/wildcards/testdata/TestWildcard-matches_exactly.golden
vendored
Normal file
1
testdata/wildcards/testdata/TestWildcard-matches_exactly.golden
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
I don't consume matches: []
|
||||||
1
testdata/wildcards/testdata/TestWildcard-multiple_matches.golden
vendored
Normal file
1
testdata/wildcards/testdata/TestWildcard-multiple_matches.golden
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
Hello foo-bar
|
||||||
1
testdata/wildcards/testdata/TestWildcard-no_matches-err-run.golden
vendored
Normal file
1
testdata/wildcards/testdata/TestWildcard-no_matches-err-run.golden
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
task: Task "no-match" does not exist
|
||||||
1
testdata/wildcards/testdata/TestWildcard-no_matches.golden
vendored
Normal file
1
testdata/wildcards/testdata/TestWildcard-no_matches.golden
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
task: No tasks with description available. Try --list-all to list all tasks
|
||||||
1
testdata/wildcards/testdata/TestWildcard-store_wildcard.golden
vendored
Normal file
1
testdata/wildcards/testdata/TestWildcard-store_wildcard.golden
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
Starting foo
|
||||||
@@ -5,6 +5,17 @@ sidebar_position: 14
|
|||||||
|
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## v3.44.1 - 2025-07-23
|
||||||
|
|
||||||
|
- Internal tasks will no longer be shown as suggestions since they cannot be
|
||||||
|
called (#2309, #2323 by @maxmzkrcensys)
|
||||||
|
- Fixed install script for some ARM platforms (#1516, #2291 by @trulede).
|
||||||
|
- Fixed a regression where fingerprinting was not working correctly if the path
|
||||||
|
to you Taskfile contained a space (#2321, #2322 by @pd93).
|
||||||
|
- Reverted a breaking change to `randInt` (#2312, #2316 by @pd93).
|
||||||
|
- Made new variables `TEST_NAME` and `TEST_DIR` available in fixture tests
|
||||||
|
(#2265 by @pd93).
|
||||||
|
|
||||||
## v3.44.0 - 2025-06-08
|
## v3.44.0 - 2025-06-08
|
||||||
|
|
||||||
- Added `uuid`, `randInt` and `randIntN` template functions (#1346, #2225 by
|
- Added `uuid`, `randInt` and `randIntN` template functions (#1346, #2225 by
|
||||||
|
|||||||
@@ -36,6 +36,14 @@ repository [[package](https://formulae.brew.sh/formula/go-task)]
|
|||||||
brew install go-task
|
brew install go-task
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### [Macports][macports] ![][macos] ![][community] \{#macports}
|
||||||
|
|
||||||
|
Task repository is tracked by Macports [[package](https://ports.macports.org/port/go-task/details/)] [[source](https://github.com/macports/macports-ports/blob/master/devel/go-task/Portfile)]:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
port install go-task
|
||||||
|
```
|
||||||
|
|
||||||
### [Snap][snapcraft] ![][macos] ![][linux] \{#snap}
|
### [Snap][snapcraft] ![][macos] ![][linux] \{#snap}
|
||||||
|
|
||||||
Task is available on [Snapcraft][snapcraft] [[source](https://github.com/go-task/snap/blob/main/snap/snapcraft.yaml)], but keep in mind that your Linux
|
Task is available on [Snapcraft][snapcraft] [[source](https://github.com/go-task/snap/blob/main/snap/snapcraft.yaml)], but keep in mind that your Linux
|
||||||
@@ -104,6 +112,14 @@ pacman -S go-task
|
|||||||
dnf install go-task
|
dnf install go-task
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### FreeBSD ([Ports][freebsdports]) ![][freebsd] ![][community] \{#freebsd}
|
||||||
|
|
||||||
|
[[package](https://cgit.freebsd.org/ports/tree/devel/task)] [[source](https://cgit.freebsd.org/ports/tree/devel/task/Makefile)]
|
||||||
|
|
||||||
|
```shell
|
||||||
|
pkg install task
|
||||||
|
```
|
||||||
|
|
||||||
### NixOS ([nix][nix]) ![][nixos] ![][linux] ![][community] \{#nix}
|
### NixOS ([nix][nix]) ![][nixos] ![][linux] ![][community] \{#nix}
|
||||||
|
|
||||||
[[source](https://github.com/NixOS/nixpkgs/blob/master/pkgs/by-name/go/go-task/package.nix)]
|
[[source](https://github.com/NixOS/nixpkgs/blob/master/pkgs/by-name/go/go-task/package.nix)]
|
||||||
@@ -304,6 +320,7 @@ task --completion fish > ~/.config/fish/completions/task.fish
|
|||||||
|
|
||||||
{/* prettier-ignore-start */}
|
{/* prettier-ignore-start */}
|
||||||
[homebrew]: https://brew.sh
|
[homebrew]: https://brew.sh
|
||||||
|
[macports]: https://macports.org
|
||||||
[snapcraft]: https://snapcraft.io/task
|
[snapcraft]: https://snapcraft.io/task
|
||||||
[winget]: https://github.com/microsoft/winget-cli
|
[winget]: https://github.com/microsoft/winget-cli
|
||||||
[choco]: https://chocolatey.org
|
[choco]: https://chocolatey.org
|
||||||
@@ -317,6 +334,7 @@ task --completion fish > ~/.config/fish/completions/task.fish
|
|||||||
[aqua]: https://aquaproj.github.io
|
[aqua]: https://aquaproj.github.io
|
||||||
[pacstall]: https://github.com/pacstall/pacstall
|
[pacstall]: https://github.com/pacstall/pacstall
|
||||||
[pkgx]: https://pkgx.sh
|
[pkgx]: https://pkgx.sh
|
||||||
|
[freebsdports]: https://ports.freebsd.org/cgi/ports.cgi
|
||||||
|
|
||||||
[go]: https://golang.org
|
[go]: https://golang.org
|
||||||
[godownloader]: https://github.com/goreleaser/godownloader
|
[godownloader]: https://github.com/goreleaser/godownloader
|
||||||
@@ -332,4 +350,5 @@ task --completion fish > ~/.config/fish/completions/task.fish
|
|||||||
[nixos]: https://img.shields.io/badge/NixOS-5277C3?logo=nixos&logoColor=fff
|
[nixos]: https://img.shields.io/badge/NixOS-5277C3?logo=nixos&logoColor=fff
|
||||||
[debian]: https://img.shields.io/badge/Debian-A81D33?logo=debian&logoColor=fff
|
[debian]: https://img.shields.io/badge/Debian-A81D33?logo=debian&logoColor=fff
|
||||||
[ubuntu]: https://img.shields.io/badge/Ubuntu-E95420?logo=ubuntu&logoColor=fff
|
[ubuntu]: https://img.shields.io/badge/Ubuntu-E95420?logo=ubuntu&logoColor=fff
|
||||||
|
[freebsd]: https://img.shields.io/badge/FreeBSD-990000?logo=freebsd&logoColor=fff
|
||||||
{/* prettier-ignore-end */}
|
{/* prettier-ignore-end */}
|
||||||
|
|||||||
@@ -400,7 +400,6 @@ Lastly, Task itself provides a few functions:
|
|||||||
| `fromYaml`\* | Decodes a YAML string into an object. |
|
| `fromYaml`\* | Decodes a YAML string into an object. |
|
||||||
| `toYaml`\* | Encodes an object as a YAML string. |
|
| `toYaml`\* | Encodes an object as a YAML string. |
|
||||||
| `uuid` | Generates a new pseudo-random UUIDv4 string. |
|
| `uuid` | Generates a new pseudo-random UUIDv4 string. |
|
||||||
| `randInt` | Generates a new pseudo-random, non-negative, 32bit integer. Generated numbers are not suitable for security-sensitive work. |
|
|
||||||
| `randIntN` | Generates a new pseudo-random, non-negative, 32bit integer in the half-open interval `[0,n)`. Generated numbers are not suitable for security-sensitive work. |
|
| `randIntN` | Generates a new pseudo-random, non-negative, 32bit integer in the half-open interval `[0,n)`. Generated numbers are not suitable for security-sensitive work. |
|
||||||
|
|
||||||
{/* prettier-ignore-start */}
|
{/* prettier-ignore-start */}
|
||||||
|
|||||||
@@ -64,21 +64,15 @@ get_binaries() {
|
|||||||
case "$PLATFORM" in
|
case "$PLATFORM" in
|
||||||
darwin/amd64) BINARIES="task" ;;
|
darwin/amd64) BINARIES="task" ;;
|
||||||
darwin/arm64) BINARIES="task" ;;
|
darwin/arm64) BINARIES="task" ;;
|
||||||
darwin/armv5) BINARIES="task" ;;
|
darwin/arm) BINARIES="task" ;;
|
||||||
darwin/armv6) BINARIES="task" ;;
|
|
||||||
darwin/armv7) BINARIES="task" ;;
|
|
||||||
linux/386) BINARIES="task" ;;
|
linux/386) BINARIES="task" ;;
|
||||||
linux/amd64) BINARIES="task" ;;
|
linux/amd64) BINARIES="task" ;;
|
||||||
linux/arm64) BINARIES="task" ;;
|
linux/arm64) BINARIES="task" ;;
|
||||||
linux/armv5) BINARIES="task" ;;
|
linux/arm) BINARIES="task" ;;
|
||||||
linux/armv6) BINARIES="task" ;;
|
|
||||||
linux/armv7) BINARIES="task" ;;
|
|
||||||
windows/386) BINARIES="task" ;;
|
windows/386) BINARIES="task" ;;
|
||||||
windows/amd64) BINARIES="task" ;;
|
windows/amd64) BINARIES="task" ;;
|
||||||
windows/arm64) BINARIES="task" ;;
|
windows/arm64) BINARIES="task" ;;
|
||||||
windows/armv5) BINARIES="task" ;;
|
windows/arm) BINARIES="task" ;;
|
||||||
windows/armv6) BINARIES="task" ;;
|
|
||||||
windows/armv7) BINARIES="task" ;;
|
|
||||||
*)
|
*)
|
||||||
log_crit "platform $PLATFORM is not supported. Make sure this script is up-to-date and file request at https://github.com/${PREFIX}/issues/new"
|
log_crit "platform $PLATFORM is not supported. Make sure this script is up-to-date and file request at https://github.com/${PREFIX}/issues/new"
|
||||||
exit 1
|
exit 1
|
||||||
|
|||||||
@@ -5,6 +5,17 @@ sidebar_position: 14
|
|||||||
|
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## v3.44.1 - 2025-07-23
|
||||||
|
|
||||||
|
- Internal tasks will no longer be shown as suggestions since they cannot be
|
||||||
|
called (#2309, #2323 by @maxmzkrcensys)
|
||||||
|
- Fixed install script for some ARM platforms (#1516, #2291 by @trulede).
|
||||||
|
- Fixed a regression where fingerprinting was not working correctly if the path
|
||||||
|
to you Taskfile contained a space (#2321, #2322 by @pd93).
|
||||||
|
- Reverted a breaking change to `randInt` (#2312, #2316 by @pd93).
|
||||||
|
- Made new variables `TEST_NAME` and `TEST_DIR` available in fixture tests
|
||||||
|
(#2265 by @pd93).
|
||||||
|
|
||||||
## v3.44.0 - 2025-06-08
|
## v3.44.0 - 2025-06-08
|
||||||
|
|
||||||
- Added `uuid`, `randInt` and `randIntN` template functions (#1346, #2225 by
|
- Added `uuid`, `randInt` and `randIntN` template functions (#1346, #2225 by
|
||||||
|
|||||||
@@ -36,6 +36,14 @@ repository [[package](https://formulae.brew.sh/formula/go-task)]
|
|||||||
brew install go-task
|
brew install go-task
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### [Macports][macports] ![][macos] ![][community] \{#macports}
|
||||||
|
|
||||||
|
Task repository is tracked by Macports [[package](https://ports.macports.org/port/go-task/details/)] [[source](https://github.com/macports/macports-ports/blob/master/devel/go-task/Portfile)]:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
port install go-task
|
||||||
|
```
|
||||||
|
|
||||||
### [Snap][snapcraft] ![][macos] ![][linux] \{#snap}
|
### [Snap][snapcraft] ![][macos] ![][linux] \{#snap}
|
||||||
|
|
||||||
Task is available on [Snapcraft][snapcraft] [[source](https://github.com/go-task/snap/blob/main/snap/snapcraft.yaml)], but keep in mind that your Linux
|
Task is available on [Snapcraft][snapcraft] [[source](https://github.com/go-task/snap/blob/main/snap/snapcraft.yaml)], but keep in mind that your Linux
|
||||||
@@ -104,6 +112,14 @@ pacman -S go-task
|
|||||||
dnf install go-task
|
dnf install go-task
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### FreeBSD ([Ports][freebsdports]) ![][freebsd] ![][community] \{#freebsd}
|
||||||
|
|
||||||
|
[[package](https://cgit.freebsd.org/ports/tree/devel/task)] [[source](https://cgit.freebsd.org/ports/tree/devel/task/Makefile)]
|
||||||
|
|
||||||
|
```shell
|
||||||
|
pkg install task
|
||||||
|
```
|
||||||
|
|
||||||
### NixOS ([nix][nix]) ![][nixos] ![][linux] ![][community] \{#nix}
|
### NixOS ([nix][nix]) ![][nixos] ![][linux] ![][community] \{#nix}
|
||||||
|
|
||||||
[[source](https://github.com/NixOS/nixpkgs/blob/master/pkgs/by-name/go/go-task/package.nix)]
|
[[source](https://github.com/NixOS/nixpkgs/blob/master/pkgs/by-name/go/go-task/package.nix)]
|
||||||
@@ -304,6 +320,7 @@ task --completion fish > ~/.config/fish/completions/task.fish
|
|||||||
|
|
||||||
{/* prettier-ignore-start */}
|
{/* prettier-ignore-start */}
|
||||||
[homebrew]: https://brew.sh
|
[homebrew]: https://brew.sh
|
||||||
|
[macports]: https://macports.org
|
||||||
[snapcraft]: https://snapcraft.io/task
|
[snapcraft]: https://snapcraft.io/task
|
||||||
[winget]: https://github.com/microsoft/winget-cli
|
[winget]: https://github.com/microsoft/winget-cli
|
||||||
[choco]: https://chocolatey.org
|
[choco]: https://chocolatey.org
|
||||||
@@ -317,6 +334,7 @@ task --completion fish > ~/.config/fish/completions/task.fish
|
|||||||
[aqua]: https://aquaproj.github.io
|
[aqua]: https://aquaproj.github.io
|
||||||
[pacstall]: https://github.com/pacstall/pacstall
|
[pacstall]: https://github.com/pacstall/pacstall
|
||||||
[pkgx]: https://pkgx.sh
|
[pkgx]: https://pkgx.sh
|
||||||
|
[freebsdports]: https://ports.freebsd.org/cgi/ports.cgi
|
||||||
|
|
||||||
[go]: https://golang.org
|
[go]: https://golang.org
|
||||||
[godownloader]: https://github.com/goreleaser/godownloader
|
[godownloader]: https://github.com/goreleaser/godownloader
|
||||||
@@ -332,4 +350,5 @@ task --completion fish > ~/.config/fish/completions/task.fish
|
|||||||
[nixos]: https://img.shields.io/badge/NixOS-5277C3?logo=nixos&logoColor=fff
|
[nixos]: https://img.shields.io/badge/NixOS-5277C3?logo=nixos&logoColor=fff
|
||||||
[debian]: https://img.shields.io/badge/Debian-A81D33?logo=debian&logoColor=fff
|
[debian]: https://img.shields.io/badge/Debian-A81D33?logo=debian&logoColor=fff
|
||||||
[ubuntu]: https://img.shields.io/badge/Ubuntu-E95420?logo=ubuntu&logoColor=fff
|
[ubuntu]: https://img.shields.io/badge/Ubuntu-E95420?logo=ubuntu&logoColor=fff
|
||||||
|
[freebsd]: https://img.shields.io/badge/FreeBSD-990000?logo=freebsd&logoColor=fff
|
||||||
{/* prettier-ignore-end */}
|
{/* prettier-ignore-end */}
|
||||||
|
|||||||
@@ -400,7 +400,6 @@ Lastly, Task itself provides a few functions:
|
|||||||
| `fromYaml`\* | Decodes a YAML string into an object. |
|
| `fromYaml`\* | Decodes a YAML string into an object. |
|
||||||
| `toYaml`\* | Encodes an object as a YAML string. |
|
| `toYaml`\* | Encodes an object as a YAML string. |
|
||||||
| `uuid` | Generates a new pseudo-random UUIDv4 string. |
|
| `uuid` | Generates a new pseudo-random UUIDv4 string. |
|
||||||
| `randInt` | Generates a new pseudo-random, non-negative, 32bit integer. Generated numbers are not suitable for security-sensitive work. |
|
|
||||||
| `randIntN` | Generates a new pseudo-random, non-negative, 32bit integer in the half-open interval `[0,n)`. Generated numbers are not suitable for security-sensitive work. |
|
| `randIntN` | Generates a new pseudo-random, non-negative, 32bit integer in the half-open interval `[0,n)`. Generated numbers are not suitable for security-sensitive work. |
|
||||||
|
|
||||||
{/* prettier-ignore-start */}
|
{/* prettier-ignore-start */}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user