mirror of
https://github.com/go-task/task.git
synced 2026-05-18 21:26:37 +02:00
Compare commits
27 Commits
better-gh-
...
v3.46.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fc378cfb92 | ||
|
|
9488a2a744 | ||
|
|
6ece2445ae | ||
|
|
9b95e758f4 | ||
|
|
28fee2c356 | ||
|
|
763e77467b | ||
|
|
f2385e625d | ||
|
|
e929cccd73 | ||
|
|
cb183349b7 | ||
|
|
2ebbb99f58 | ||
|
|
6660afc8d2 | ||
|
|
b710259bfa | ||
|
|
4ec6c453bd | ||
|
|
28408ef3f4 | ||
|
|
a2d34ffc4c | ||
|
|
1a190a118f | ||
|
|
18efa3982f | ||
|
|
655e83454e | ||
|
|
3ad4604c36 | ||
|
|
5a27d04655 | ||
|
|
ea933bcc55 | ||
|
|
e0d6b71971 | ||
|
|
d7ee855e49 | ||
|
|
511f35a456 | ||
|
|
5889ff6b65 | ||
|
|
85a98b5f90 | ||
|
|
89b6140166 |
112
.github/workflows/ci.yml
vendored
112
.github/workflows/ci.yml
vendored
@@ -1,112 +0,0 @@
|
||||
name: CI
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
tags:
|
||||
- v*
|
||||
branches:
|
||||
- main
|
||||
|
||||
concurrency:
|
||||
group: ci-${{ github.head_ref || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: 🔨 Build (${{ matrix.go-version }})
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
go-version: [1.24.x, 1.25.x]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: 📥 Checkout
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: ⬇️ Setup Go
|
||||
uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version: ${{ matrix.go-version }}
|
||||
|
||||
- name: 🔨 Build
|
||||
run: go build -v ./cmd/task
|
||||
|
||||
test:
|
||||
name: 🧪 Test (${{ matrix.go-version }}, ${{ matrix.platform }})
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
go-version: [1.24.x, 1.25.x]
|
||||
platform: [ubuntu-latest, macos-latest, windows-latest]
|
||||
runs-on: ${{ matrix.platform }}
|
||||
steps:
|
||||
- name: 📥 Checkout
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: ⬇️ Setup Go
|
||||
uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version: ${{ matrix.go-version }}
|
||||
|
||||
- name: ⬇️ Setup Task
|
||||
uses: go-task/setup-task@v1
|
||||
|
||||
- name: 🧪 Test
|
||||
run: task test --output group --output-group-begin '::group::{{.TASK}}' --output-group-end '::endgroup::'
|
||||
|
||||
lint:
|
||||
name: 🔍 Lint (${{ matrix.go-version }})
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
go-version: [1.24.x, 1.25.x]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: 📥 Checkout
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: ⬇️ Setup Go
|
||||
uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version: ${{ matrix.go-version }}
|
||||
|
||||
- name: 🔍 Lint
|
||||
uses: golangci/golangci-lint-action@v9
|
||||
with:
|
||||
version: v2.7.1
|
||||
|
||||
lint-jsonschema:
|
||||
name: 📋 Lint JSON Schema
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: 📥 Checkout
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: ⬇️ Setup Python
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: 3.14
|
||||
|
||||
- name: ⬇️ Install check-jsonschema
|
||||
run: python -m pip install 'check-jsonschema==0.27.3'
|
||||
|
||||
- name: 📋 Validate JSON Schema
|
||||
run: check-jsonschema --check-metaschema website/src/public/schema.json
|
||||
|
||||
ci-status:
|
||||
name: ✅ CI
|
||||
runs-on: ubuntu-latest
|
||||
needs: [build, test, lint, lint-jsonschema]
|
||||
if: always()
|
||||
steps:
|
||||
- name: ✅ Check CI status
|
||||
run: |
|
||||
if [[ "${{ needs.build.result }}" != "success" ]] || \
|
||||
[[ "${{ needs.test.result }}" != "success" ]] || \
|
||||
[[ "${{ needs.lint.result }}" != "success" ]] || \
|
||||
[[ "${{ needs.lint-jsonschema.result }}" != "success" ]]; then
|
||||
echo "CI failed"
|
||||
exit 1
|
||||
fi
|
||||
echo "CI passed"
|
||||
43
.github/workflows/lint.yml
vendored
Normal file
43
.github/workflows/lint.yml
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
name: Lint
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
tags:
|
||||
- v*
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
name: Lint
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [1.24.x, 1.25.x]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version: ${{matrix.go-version}}
|
||||
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: golangci-lint
|
||||
uses: golangci/golangci-lint-action@v9
|
||||
with:
|
||||
version: v2.7.2
|
||||
|
||||
lint-jsonschema:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: 3.14
|
||||
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: install check-jsonschema
|
||||
run: python -m pip install 'check-jsonschema==0.27.3'
|
||||
|
||||
- name: check-jsonschema (metaschema)
|
||||
run: check-jsonschema --check-metaschema website/src/public/schema.json
|
||||
38
.github/workflows/test.yml
vendored
Normal file
38
.github/workflows/test.yml
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
name: Test
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
tags:
|
||||
- v*
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
test:
|
||||
name: Test
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [1.24.x, 1.25.x]
|
||||
platform: [ubuntu-latest, macos-latest, windows-latest]
|
||||
runs-on: ${{matrix.platform}}
|
||||
steps:
|
||||
- name: Set up Go ${{matrix.go-version}}
|
||||
uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version: ${{matrix.go-version}}
|
||||
id: go
|
||||
|
||||
- name: Check out code into the Go module directory
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Download Go modules
|
||||
run: go mod download
|
||||
env:
|
||||
GOPROXY: https://proxy.golang.org
|
||||
|
||||
- name: Build
|
||||
run: go build -o ./bin/task -v ./cmd/task
|
||||
|
||||
- name: Test
|
||||
run: ./bin/task test --output=group --output-group-begin='::group::{{.TASK}}' --output-group-end='::endgroup::'
|
||||
@@ -169,6 +169,6 @@ cloudsmiths:
|
||||
rpm:
|
||||
- "any-distro/any-version"
|
||||
alpine:
|
||||
- "any-distro/any-version"
|
||||
- "alpine/any-version"
|
||||
component: main
|
||||
republish: true
|
||||
|
||||
66
CHANGELOG.md
66
CHANGELOG.md
@@ -1,39 +1,77 @@
|
||||
# Changelog
|
||||
|
||||
## Unreleased
|
||||
## v3.46.2 - 2025-12-18
|
||||
|
||||
- Fixed a regression on previous release that affected variables passed via
|
||||
command line (#2588, #2589 by @vmaerten).
|
||||
|
||||
## v3.46.1 - 2025-12-18
|
||||
|
||||
### ✨ Features
|
||||
|
||||
- A small behavior change was made to dependencies. Task will now wait for all
|
||||
dependencies to finish running before continuing, even if any of them fail.
|
||||
To opt for the previous behavior, set `failfast: true` either on your
|
||||
dependencies to finish running before continuing, even if any of them fail. To
|
||||
opt for the previous behavior, set `failfast: true` either on your
|
||||
`.taskrc.yml` or per task, or use the `--failfast` flag, which will also work
|
||||
for `--parallel` (#1246, #2525 by @andreynering).
|
||||
- Fix RPM upload to Cloudsmith by including the version in the filename to
|
||||
ensure unique filenames (#2507 by @vmaerten).
|
||||
- Fix `run: when_changed` to work properly for Taskfiles included multiple times
|
||||
(#2508, #2511 by @trulede).
|
||||
- The `--summary` flag now displays `vars:` (both global and task-level),
|
||||
`env:`, and `requires:` sections. Dynamic variables show their shell command
|
||||
(e.g., `sh: echo "hello"`) instead of the evaluated value (#2486 ,#2524 by
|
||||
@vmaerten).
|
||||
- Improved shell completion scripts (Zsh, Fish, PowerShell) by adding missing
|
||||
flags and dynamic experimental feature detection (#2532 by @vmaerten).
|
||||
- Improved performance of fuzzy task name matching by implementing lazy
|
||||
initialization. Added `--disable-fuzzy` flag and `disable-fuzzy` taskrc option
|
||||
to allow disabling fuzzy matching entirely (#2521, #2523 by @vmaerten).
|
||||
- Added LLM-optimized documentation via VitePress plugin, generating `llms.txt`
|
||||
and `llms-full.txt` for AI-powered development tools (#2513 by @vmaerten).
|
||||
- Fixed Zsh and Fish completions to stop suggesting task names after `--`
|
||||
separator, allowing proper CLI_ARGS completion (#1843, #1844 by
|
||||
@boiledfroginthewell).
|
||||
- Remote Taskfiles now accept `application/octet-stream` Content-Type (#2536,
|
||||
#1944 by @vmaerten).
|
||||
- Added `--trusted-hosts` CLI flag and `remote.trusted-hosts` config option to
|
||||
skip confirmation prompts for specified hosts when using Remote Taskfiles
|
||||
(#2491, #2473 by @maciejlech).
|
||||
- When running in GitHub Actions, Task now automatically emits error annotations
|
||||
on failure, improving visibility in workflow summaries (#2568 by @vmaerten).
|
||||
- The `--yes` flag is now accessible in templates via the new `CLI_ASSUME_YES`
|
||||
variable (#2577, #2479 by @semihbkgr).
|
||||
- Improved shell completion scripts (Zsh, Fish, PowerShell) by adding missing
|
||||
flags and dynamic experimental feature detection (#2532 by @vmaerten).
|
||||
- Remote Taskfiles now accept `application/octet-stream` Content-Type (#2536,
|
||||
#1944 by @vmaerten).
|
||||
- Shell completion now works when Task is installed or aliased under a different
|
||||
binary name via TASK_EXE environment variable (#2495, #2468 by @vmaerten).
|
||||
- Some small fixes and improvements were made to `task --init` and to the
|
||||
default Taskfile it generates (#2433 by @andreynering).
|
||||
- Added `--remote-cache-dir` flag and `remote.cache-dir` taskrc option to
|
||||
customize the cache directory for Remote Taskfiles (#2572 by @vmaerten).
|
||||
- Zsh completion now supports zstyle verbose option to show or hide task
|
||||
descriptions (#2571 by @vmaerten).
|
||||
- Task now automatically enables colored output in CI environments (GitHub
|
||||
Actions, GitLab CI, etc.) without requiring FORCE_COLOR=1 (#2569 by
|
||||
@vmaerten).
|
||||
- Added color taskrc option to explicitly enable or disable colored output
|
||||
globally (#2569 by @vmaerten).
|
||||
- Improved Git Remote Taskfiles by switching to go-getter: SSH authentication
|
||||
now works out of the box and `applyOf` is properly supported (#2512 by
|
||||
@vmaerten).
|
||||
|
||||
### 🐛 Fixes
|
||||
|
||||
- Fix RPM upload to Cloudsmith by including the version in the filename to
|
||||
ensure unique filenames (#2507 by @vmaerten).
|
||||
- Fix `run: when_changed` to work properly for Taskfiles included multiple times
|
||||
(#2508, #2511 by @trulede).
|
||||
- Fixed Zsh and Fish completions to stop suggesting task names after `--`
|
||||
separator, allowing proper CLI_ARGS completion (#1843, #1844 by
|
||||
@boiledfroginthewell).
|
||||
- Watch mode (`--watch`) now always runs the task, regardless of `run: once` or
|
||||
`run: when_changed` settings (#2566, #1388 by @trulede).
|
||||
- Fixed global variables (CLI_ARGS, CLI_FORCE, etc.) not being accessible in
|
||||
root-level vars section (#2403, #2397 by @trulede, @vmaerten).
|
||||
- Fixed a bug where `ignore_error` was ignored when using `task:` to call
|
||||
another task (#2552, #363 by @trulede).
|
||||
- Fixed Zsh completion not suggesting global tasks when using `-g`/`--global`
|
||||
flag (#1574, #2574 by @vmaerten).
|
||||
- Fixed Fish completion failing to parse task descriptions containing colons
|
||||
(e.g., URLs or namespaced functions) (#2101, #2573 by @vmaerten).
|
||||
- Fixed false positive "property 'for' is not allowed" warnings in IntelliJ when
|
||||
using `for` loops in Taskfiles (#2576 by @vmaerten).
|
||||
|
||||
## v3.45.5 - 2025-11-11
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
|
||||
"github.com/spf13/pflag"
|
||||
|
||||
@@ -28,19 +29,34 @@ func main() {
|
||||
Color: flags.Color,
|
||||
}
|
||||
if err, ok := err.(*errors.TaskRunError); ok && flags.ExitCode {
|
||||
emitCIErrorAnnotation(err)
|
||||
l.Errf(logger.Red, "%v\n", err)
|
||||
os.Exit(err.TaskExitCode())
|
||||
}
|
||||
if err, ok := err.(errors.TaskError); ok {
|
||||
emitCIErrorAnnotation(err)
|
||||
l.Errf(logger.Red, "%v\n", err)
|
||||
os.Exit(err.Code())
|
||||
}
|
||||
emitCIErrorAnnotation(err)
|
||||
l.Errf(logger.Red, "%v\n", err)
|
||||
os.Exit(errors.CodeUnknown)
|
||||
}
|
||||
os.Exit(errors.CodeOk)
|
||||
}
|
||||
|
||||
// emitCIErrorAnnotation emits an error annotation for supported CI providers.
|
||||
func emitCIErrorAnnotation(err error) {
|
||||
if isGA, _ := strconv.ParseBool(os.Getenv("GITHUB_ACTIONS")); !isGA {
|
||||
return
|
||||
}
|
||||
if e, ok := err.(*errors.TaskRunError); ok {
|
||||
fmt.Fprintf(os.Stdout, "::error title=Task '%s' failed::%v\n", e.TaskName, e.Err)
|
||||
return
|
||||
}
|
||||
fmt.Fprintf(os.Stdout, "::error title=Task failed::%v\n", err)
|
||||
}
|
||||
|
||||
func run() error {
|
||||
log := &logger.Logger{
|
||||
Stdout: os.Stdout,
|
||||
@@ -156,18 +172,23 @@ func run() error {
|
||||
calls = append(calls, &task.Call{Task: "default"})
|
||||
}
|
||||
|
||||
// Merge CLI variables first (e.g. FOO=bar) so they take priority over Taskfile defaults
|
||||
e.Taskfile.Vars.Merge(globals, nil)
|
||||
|
||||
// Then ReverseMerge special variables so they're available for templating
|
||||
cliArgsPostDashQuoted, err := args.ToQuotedString(cliArgsPostDash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
globals.Set("CLI_ARGS", ast.Var{Value: cliArgsPostDashQuoted})
|
||||
globals.Set("CLI_ARGS_LIST", ast.Var{Value: cliArgsPostDash})
|
||||
globals.Set("CLI_FORCE", ast.Var{Value: flags.Force || flags.ForceAll})
|
||||
globals.Set("CLI_SILENT", ast.Var{Value: flags.Silent})
|
||||
globals.Set("CLI_VERBOSE", ast.Var{Value: flags.Verbose})
|
||||
globals.Set("CLI_OFFLINE", ast.Var{Value: flags.Offline})
|
||||
e.Taskfile.Vars.Merge(globals, nil)
|
||||
|
||||
specialVars := ast.NewVars()
|
||||
specialVars.Set("CLI_ARGS", ast.Var{Value: cliArgsPostDashQuoted})
|
||||
specialVars.Set("CLI_ARGS_LIST", ast.Var{Value: cliArgsPostDash})
|
||||
specialVars.Set("CLI_FORCE", ast.Var{Value: flags.Force || flags.ForceAll})
|
||||
specialVars.Set("CLI_SILENT", ast.Var{Value: flags.Silent})
|
||||
specialVars.Set("CLI_VERBOSE", ast.Var{Value: flags.Verbose})
|
||||
specialVars.Set("CLI_OFFLINE", ast.Var{Value: flags.Offline})
|
||||
specialVars.Set("CLI_ASSUME_YES", ast.Var{Value: flags.AssumeYes})
|
||||
e.Taskfile.Vars.ReverseMerge(specialVars, nil)
|
||||
if !flags.Watch {
|
||||
e.InterceptInterruptSignals()
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ function _task()
|
||||
|
||||
# Handle special arguments of options.
|
||||
case "$prev" in
|
||||
-d|--dir)
|
||||
-d|--dir|--remote-cache-dir)
|
||||
_filedir -d
|
||||
return $?
|
||||
;;
|
||||
|
||||
@@ -54,7 +54,7 @@ function __task_get_tasks --description "Prints all available tasks with their d
|
||||
end
|
||||
|
||||
# Grab names and descriptions (if any) of the tasks
|
||||
set -l output (echo $rawOutput | sed -e '1d; s/\* \(.*\):\s*\(.*\)\s*(\(aliases.*\))/\1\t\2\t\3/' -e 's/\* \(.*\):\s*\(.*\)/\1\t\2/'| string split0)
|
||||
set -l output (echo $rawOutput | sed -e '1d; s/\* \(.*\):\s\{2,\}\(.*\)\s\{2,\}(\(aliases.*\))/\1\t\2\t\3/' -e 's/\* \(.*\):\s\{2,\}\(.*\)/\1\t\2/'| string split0)
|
||||
if test $output
|
||||
echo $output
|
||||
end
|
||||
@@ -106,9 +106,10 @@ complete -c $GO_TASK_PROGNAME -s y -l yes -d 'assume yes t
|
||||
complete -c $GO_TASK_PROGNAME -n "__task_is_experiment_enabled GENTLE_FORCE" -l force-all -d 'force execution of task and all dependencies'
|
||||
|
||||
# RemoteTaskfiles experiment - Options
|
||||
complete -c $GO_TASK_PROGNAME -n "__task_is_experiment_enabled REMOTE_TASKFILES" -l offline -d 'use only local or cached Taskfiles'
|
||||
complete -c $GO_TASK_PROGNAME -n "__task_is_experiment_enabled REMOTE_TASKFILES" -l timeout -d 'timeout for remote Taskfile downloads'
|
||||
complete -c $GO_TASK_PROGNAME -n "__task_is_experiment_enabled REMOTE_TASKFILES" -l expiry -d 'cache expiry duration'
|
||||
complete -c $GO_TASK_PROGNAME -n "__task_is_experiment_enabled REMOTE_TASKFILES" -l offline -d 'use only local or cached Taskfiles'
|
||||
complete -c $GO_TASK_PROGNAME -n "__task_is_experiment_enabled REMOTE_TASKFILES" -l timeout -d 'timeout for remote Taskfile downloads'
|
||||
complete -c $GO_TASK_PROGNAME -n "__task_is_experiment_enabled REMOTE_TASKFILES" -l expiry -d 'cache expiry duration'
|
||||
complete -c $GO_TASK_PROGNAME -n "__task_is_experiment_enabled REMOTE_TASKFILES" -l remote-cache-dir -d 'directory to cache remote Taskfiles' -xa "(__fish_complete_directories)"
|
||||
|
||||
# RemoteTaskfiles experiment - Operations
|
||||
complete -c $GO_TASK_PROGNAME -n "__task_is_experiment_enabled REMOTE_TASKFILES" -l download -d 'download remote Taskfile'
|
||||
|
||||
@@ -75,6 +75,7 @@ Register-ArgumentCompleter -CommandName task -ScriptBlock {
|
||||
$completions += [CompletionResult]::new('--offline', '--offline', [CompletionResultType]::ParameterName, 'use cached Taskfiles')
|
||||
$completions += [CompletionResult]::new('--timeout', '--timeout', [CompletionResultType]::ParameterName, 'download timeout')
|
||||
$completions += [CompletionResult]::new('--expiry', '--expiry', [CompletionResultType]::ParameterName, 'cache expiry')
|
||||
$completions += [CompletionResult]::new('--remote-cache-dir', '--remote-cache-dir', [CompletionResultType]::ParameterName, 'cache directory')
|
||||
# Operations
|
||||
$completions += [CompletionResult]::new('--download', '--download', [CompletionResultType]::ParameterName, 'download remote Taskfile')
|
||||
$completions += [CompletionResult]::new('--clear-cache', '--clear-cache', [CompletionResultType]::ParameterName, 'clear cache')
|
||||
|
||||
@@ -33,6 +33,10 @@ function __task_list() {
|
||||
cmd+=(--taskfile "$taskfile")
|
||||
fi
|
||||
|
||||
# Check if global flag is set
|
||||
if (( ${+opt_args[(i)-g|--global]} )); then
|
||||
cmd+=(--global)
|
||||
fi
|
||||
|
||||
if output=$("${cmd[@]}" $_GO_TASK_COMPLETION_LIST_OPTION 2>/dev/null); then
|
||||
enabled=1
|
||||
@@ -41,12 +45,27 @@ function __task_list() {
|
||||
(( enabled )) || return 0
|
||||
|
||||
scripts=()
|
||||
|
||||
# Read zstyle verbose option (default = true via -T)
|
||||
local show_desc
|
||||
zstyle -T ":completion:${curcontext}:" verbose && show_desc=true || show_desc=false
|
||||
|
||||
for item in "${(@)${(f)output}[2,-1]#\* }"; do
|
||||
task="${item%%:[[:space:]]*}"
|
||||
desc="${item##[^[:space:]]##[[:space:]]##}"
|
||||
scripts+=( "${task//:/\\:}:$desc" )
|
||||
|
||||
if [[ "$show_desc" == "true" ]]; then
|
||||
local desc="${item##[^[:space:]]##[[:space:]]##}"
|
||||
scripts+=( "${task//:/\\:}:$desc" )
|
||||
else
|
||||
scripts+=( "$task" )
|
||||
fi
|
||||
done
|
||||
_describe 'Task to run' scripts
|
||||
|
||||
if [[ "$show_desc" == "true" ]]; then
|
||||
_describe 'Task to run' scripts
|
||||
else
|
||||
compadd -Q -a scripts
|
||||
fi
|
||||
}
|
||||
|
||||
_task() {
|
||||
@@ -96,6 +115,7 @@ _task() {
|
||||
'(--offline --download)--offline[use only local or cached Taskfiles]'
|
||||
'(--timeout)--timeout[timeout for remote Taskfile downloads]:duration: '
|
||||
'(--expiry)--expiry[cache expiry duration]:duration: '
|
||||
'(--remote-cache-dir)--remote-cache-dir[directory to cache remote Taskfiles]:cache dir:_dirs'
|
||||
)
|
||||
fi
|
||||
|
||||
|
||||
14
executor.go
14
executor.go
@@ -37,6 +37,7 @@ type (
|
||||
TrustedHosts []string
|
||||
Timeout time.Duration
|
||||
CacheExpiryDuration time.Duration
|
||||
RemoteCacheDir string
|
||||
Watch bool
|
||||
Verbose bool
|
||||
Silent bool
|
||||
@@ -271,6 +272,19 @@ func (o *cacheExpiryDurationOption) ApplyToExecutor(r *Executor) {
|
||||
r.CacheExpiryDuration = o.duration
|
||||
}
|
||||
|
||||
// WithRemoteCacheDir sets the directory where remote taskfiles are cached.
|
||||
func WithRemoteCacheDir(dir string) ExecutorOption {
|
||||
return &remoteCacheDirOption{dir: dir}
|
||||
}
|
||||
|
||||
type remoteCacheDirOption struct {
|
||||
dir string
|
||||
}
|
||||
|
||||
func (o *remoteCacheDirOption) ApplyToExecutor(e *Executor) {
|
||||
e.RemoteCacheDir = o.dir
|
||||
}
|
||||
|
||||
// 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
|
||||
// detected, a new task run is triggered.
|
||||
|
||||
@@ -263,6 +263,23 @@ func TestVars(t *testing.T) {
|
||||
task.WithSilent(true),
|
||||
),
|
||||
)
|
||||
NewExecutorTest(t,
|
||||
WithName("cli-var-priority-default"),
|
||||
WithExecutorOptions(
|
||||
task.WithDir("testdata/vars"),
|
||||
task.WithSilent(true),
|
||||
),
|
||||
WithTask("cli-var-priority"),
|
||||
)
|
||||
NewExecutorTest(t,
|
||||
WithName("cli-var-priority-override"),
|
||||
WithExecutorOptions(
|
||||
task.WithDir("testdata/vars"),
|
||||
task.WithSilent(true),
|
||||
),
|
||||
WithTask("cli-var-priority"),
|
||||
WithVar("CLI_VAR", "from_cli"),
|
||||
)
|
||||
}
|
||||
|
||||
func TestRequires(t *testing.T) {
|
||||
|
||||
66
go.mod
66
go.mod
@@ -12,11 +12,10 @@ require (
|
||||
github.com/elliotchance/orderedmap/v3 v3.1.0
|
||||
github.com/fatih/color v1.18.0
|
||||
github.com/fsnotify/fsnotify v1.9.0
|
||||
github.com/go-git/go-billy/v5 v5.7.0
|
||||
github.com/go-git/go-git/v5 v5.16.4
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0
|
||||
github.com/go-task/template v0.2.0
|
||||
github.com/google/uuid v1.6.0
|
||||
github.com/hashicorp/go-getter v1.8.3
|
||||
github.com/joho/godotenv v1.5.1
|
||||
github.com/mitchellh/hashstructure/v2 v2.0.2
|
||||
github.com/puzpuzpuz/xsync/v4 v4.2.0
|
||||
@@ -26,42 +25,69 @@ require (
|
||||
github.com/stretchr/testify v1.11.1
|
||||
github.com/zeebo/xxh3 v1.0.2
|
||||
go.yaml.in/yaml/v4 v4.0.0-rc.3
|
||||
golang.org/x/sync v0.18.0
|
||||
golang.org/x/term v0.37.0
|
||||
golang.org/x/sync v0.19.0
|
||||
golang.org/x/term v0.38.0
|
||||
mvdan.cc/sh/moreinterp v0.0.0-20251109230715-65adef8e2c5b
|
||||
mvdan.cc/sh/v3 v3.12.0
|
||||
)
|
||||
|
||||
require (
|
||||
dario.cat/mergo v1.0.0 // indirect
|
||||
github.com/Microsoft/go-winio v0.6.2 // indirect
|
||||
github.com/ProtonMail/go-crypto v1.3.0 // indirect
|
||||
github.com/cloudflare/circl v1.6.1 // indirect
|
||||
github.com/cyphar/filepath-securejoin v0.4.1 // indirect
|
||||
cloud.google.com/go v0.110.0 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.3.0 // indirect
|
||||
cloud.google.com/go/iam v0.13.0 // indirect
|
||||
cloud.google.com/go/storage v1.29.0 // indirect
|
||||
github.com/aws/aws-sdk-go-v2 v1.36.3 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.10 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/config v1.29.15 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.17.68 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.30 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.34 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.34 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.34 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.7.2 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.15 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.15 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.80.1 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.25.3 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.1 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.33.20 // indirect
|
||||
github.com/aws/smithy-go v1.22.3 // indirect
|
||||
github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect
|
||||
github.com/dlclark/regexp2 v1.11.5 // indirect
|
||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||
github.com/emirpasic/gods v1.18.1 // indirect
|
||||
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
|
||||
github.com/kevinburke/ssh_config v1.2.0 // indirect
|
||||
github.com/golang/protobuf v1.5.4 // indirect
|
||||
github.com/google/go-cmp v0.7.0 // indirect
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect
|
||||
github.com/googleapis/gax-go/v2 v2.7.1 // indirect
|
||||
github.com/hashicorp/aws-sdk-go-base/v2 v2.0.0-beta.65 // indirect
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
|
||||
github.com/hashicorp/go-version v1.6.0 // indirect
|
||||
github.com/klauspost/compress v1.18.0 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.7 // indirect
|
||||
github.com/klauspost/pgzip v1.2.6 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-colorable v0.1.14 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||
github.com/pierrec/lz4/v4 v4.1.22 // indirect
|
||||
github.com/pjbgf/sha1cd v0.3.2 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect
|
||||
github.com/skeema/knownhosts v1.3.1 // indirect
|
||||
github.com/stretchr/objx v0.5.2 // indirect
|
||||
github.com/u-root/u-root v0.15.1-0.20251014130006-62f7144b33da // indirect
|
||||
github.com/u-root/uio v0.0.0-20240224005618-d2acac8f3701 // indirect
|
||||
github.com/xanzy/ssh-agent v0.3.3 // indirect
|
||||
golang.org/x/crypto v0.45.0 // indirect
|
||||
github.com/ulikunitz/xz v0.5.15 // indirect
|
||||
go.opencensus.io v0.24.0 // indirect
|
||||
golang.org/x/net v0.47.0 // indirect
|
||||
golang.org/x/sys v0.38.0 // indirect
|
||||
gopkg.in/warnings.v0 v0.1.2 // indirect
|
||||
golang.org/x/oauth2 v0.27.0 // indirect
|
||||
golang.org/x/sys v0.39.0 // indirect
|
||||
golang.org/x/text v0.31.0 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
|
||||
google.golang.org/api v0.114.0 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect
|
||||
google.golang.org/grpc v1.56.3 // indirect
|
||||
google.golang.org/protobuf v1.33.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
||||
256
go.sum
256
go.sum
@@ -1,32 +1,70 @@
|
||||
dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk=
|
||||
dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.110.0 h1:Zc8gqp3+a9/Eyph2KDmcGaPtbKRIoqq4YTlL4NMD0Ys=
|
||||
cloud.google.com/go v0.110.0/go.mod h1:SJnCLqQ0FCFGSZMUNUf84MV3Aia54kn7pi8st7tMzaY=
|
||||
cloud.google.com/go/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc=
|
||||
cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k=
|
||||
cloud.google.com/go/iam v0.13.0 h1:+CmB+K0J/33d0zSQ9SlFWUeCCEn5XJA0ZMZ3pHE9u8k=
|
||||
cloud.google.com/go/iam v0.13.0/go.mod h1:ljOg+rcNfzZ5d6f1nAUJ8ZIxOaZUVoS14bKCtaLZ/D0=
|
||||
cloud.google.com/go/longrunning v0.4.1 h1:v+yFJOfKC3yZdY6ZUI933pIYdhyhV8S3NpWrXWmg7jM=
|
||||
cloud.google.com/go/longrunning v0.4.1/go.mod h1:4iWDqhBZ70CvZ6BfETbvam3T8FMvLK+eFj0E6AaRQTo=
|
||||
cloud.google.com/go/storage v1.29.0 h1:6weCgzRvMg7lzuUurI4697AqIRPU1SvzHhynwpW31jI=
|
||||
cloud.google.com/go/storage v1.29.0/go.mod h1:4puEjyTKnku6gfKoTfNOU/W+a9JyuVNxjpS5GBrB8h4=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
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/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0=
|
||||
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.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
|
||||
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
|
||||
github.com/ProtonMail/go-crypto v1.3.0 h1:ILq8+Sf5If5DCpHQp4PbZdS1J7HDFRXz/+xKBiRGFrw=
|
||||
github.com/ProtonMail/go-crypto v1.3.0/go.mod h1:9whxjD8Rbs29b4XWbB8irEcE8KHMqaR2e7GWU1R+/PE=
|
||||
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/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.5.1 h1:E3G4t2QbHTSNpPKBgMTln5KLkZHLOcU7r37J4pXBuIg=
|
||||
github.com/alecthomas/repr v0.5.1/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/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4=
|
||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
|
||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
|
||||
github.com/aws/aws-sdk-go-v2 v1.36.3 h1:mJoei2CxPutQVxaATCzDUjcZEjVRdpsiiXi2o38yqWM=
|
||||
github.com/aws/aws-sdk-go-v2 v1.36.3/go.mod h1:LLXuLpgzEbD766Z5ECcRmi8AzSwfZItDtmABVkRLGzg=
|
||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.10 h1:zAybnyUQXIZ5mok5Jqwlf58/TFE7uvd3IAsa1aF9cXs=
|
||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.10/go.mod h1:qqvMj6gHLR/EXWZw4ZbqlPbQUyenf4h82UQUlKc+l14=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.29.15 h1:I5XjesVMpDZXZEZonVfjI12VNMrYa38LtLnw4NtY5Ss=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.29.15/go.mod h1:tNIp4JIPonlsgaO5hxO372a6gjhN63aSWl2GVl5QoBQ=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.17.68 h1:cFb9yjI02/sWHBSYXAtkamjzCuRymvmeFmt0TC0MbYY=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.17.68/go.mod h1:H6E+jBzyqUu8u0vGaU6POkK3P0NylYEeRZ6ynBpMqIk=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.30 h1:x793wxmUWVDhshP8WW2mlnXuFrO4cOd3HLBroh1paFw=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.30/go.mod h1:Jpne2tDnYiFascUEs2AWHJL9Yp7A5ZVy3TNyxaAjD6M=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.34 h1:ZK5jHhnrioRkUNOc+hOgQKlUL5JeC3S6JgLxtQ+Rm0Q=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.34/go.mod h1:p4VfIceZokChbA9FzMbRGz5OV+lekcVtHlPKEO0gSZY=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.34 h1:SZwFm17ZUNNg5Np0ioo/gq8Mn6u9w19Mri8DnJ15Jf0=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.34/go.mod h1:dFZsC0BLo346mvKQLWmoJxT+Sjp+qcVR1tRVHQGOH9Q=
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 h1:bIqFDwgGXXN1Kpp99pDOdKMTTb5d2KyU5X/BZxjOkRo=
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3/go.mod h1:H5O/EsxDWyU+LP/V8i5sm8cxoZgc2fdNR9bxlOFrQTo=
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.34 h1:ZNTqv4nIdE/DiBfUUfXcLZ/Spcuz+RjeziUtNJackkM=
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.34/go.mod h1:zf7Vcd1ViW7cPqYWEHLHJkS50X0JS2IKz9Cgaj6ugrs=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3 h1:eAh2A4b5IzM/lum78bZ590jy36+d/aFLgKF/4Vd1xPE=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3/go.mod h1:0yKJC/kb8sAnmlYa6Zs3QVYqaC8ug2AbnNChv5Ox3uA=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.7.2 h1:BCG7DCXEXpNCcpwCxg1oi9pkJWH2+eZzTn9MY56MbVw=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.7.2/go.mod h1:iu6FSzgt+M2/x3Dk8zhycdIcHjEFb36IS8HVUVFoMg0=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.15 h1:dM9/92u2F1JbDaGooxTq18wmmFzbJRfXfVfy96/1CXM=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.15/go.mod h1:SwFBy2vjtA0vZbjjaFtfN045boopadnoVPhu4Fv66vY=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.15 h1:moLQUoVq91LiqT1nbvzDukyqAlCv89ZmwaHw/ZFlFZg=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.15/go.mod h1:ZH34PJUc8ApjBIfgQCFvkWcUDBtl/WTD+uiYHjd8igA=
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.80.1 h1:xYEAf/6QHiTZDccKnPMbsMwlau13GsDsTgdue3wmHGw=
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.80.1/go.mod h1:qbn305Je/IofWBJ4bJz/Q7pDEtnnoInw/dGt71v6rHE=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.25.3 h1:1Gw+9ajCV1jogloEv1RRnvfRFia2cL6c9cuKV2Ps+G8=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.25.3/go.mod h1:qs4a9T5EMLl/Cajiw2TcbNt2UNo/Hqlyp+GiuG4CFDI=
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.1 h1:hXmVKytPfTy5axZ+fYbR5d0cFmC3JvwLm5kM83luako=
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.1/go.mod h1:MlYRNmYu/fGPoxBQVvBYr9nyr948aY/WLUvwBMBJubs=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.33.20 h1:oIaQ1e17CSKaWmUTu62MtraRWVIosn/iONMuZt0gbqc=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.33.20/go.mod h1:cQnB8CUnxbMU82JvlqjKR2HBOm3fe9pWorWBza6MBJ4=
|
||||
github.com/aws/smithy-go v1.22.3 h1:Z//5NuZCSW6R4PhQ93hShNbyBbn8BWCmCVCt+Q8Io5k=
|
||||
github.com/aws/smithy-go v1.22.3/go.mod h1:t1ufH5HMublsJYulve2RKmHDC15xu1f26kHCp/HgceI=
|
||||
github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d h1:xDfNPAt8lFiC1UJrqV3uuy861HCTo708pDMbjHHdCas=
|
||||
github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d/go.mod h1:6QX/PXZ00z/TKoufEY6K/a0k6AhaJrQKdFe6OfVXsa4=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/chainguard-dev/git-urls v1.0.2 h1:pSpT7ifrpc5X55n4aTTm7FFUE+ZQHKiqpiwNkJrVcKQ=
|
||||
github.com/chainguard-dev/git-urls v1.0.2/go.mod h1:rbGgj10OS7UgZlbzdUQIQpT0k/D4+An04HJY7Ol+Y/o=
|
||||
github.com/cloudflare/circl v1.6.1 h1:zqIqSPIndyBh1bjLVVDHMPpVKqp8Su/V+6MeDzzQBQ0=
|
||||
github.com/cloudflare/circl v1.6.1/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/creack/pty v1.1.24 h1:bJrF4RRfyJnbTJqzRLHzcGaZK1NeM5kTC9jGgovnR1s=
|
||||
github.com/creack/pty v1.1.24/go.mod h1:08sCNb52WyoAwi2QDyzUCTgcvVFhUzewun7wtTfvcwE=
|
||||
github.com/cyphar/filepath-securejoin v0.4.1 h1:JyxxyPEaktOD+GAnqIqTf9A8tHyAG22rowi7HkoSU1s=
|
||||
github.com/cyphar/filepath-securejoin v0.4.1/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
@@ -36,48 +74,68 @@ github.com/dominikbraun/graph v0.23.0 h1:TdZB4pPqCLFxYhdyMFb1TBdFxp8XLcJfTTBQucV
|
||||
github.com/dominikbraun/graph v0.23.0/go.mod h1:yOjYyogZLY1LSG9E33JWZJiq5k83Qy2C6POAuiViluc=
|
||||
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
|
||||
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
|
||||
github.com/elazarl/goproxy v1.7.2 h1:Y2o6urb7Eule09PjlhQRGNsqRfPmYI3KKQLFpCAV3+o=
|
||||
github.com/elazarl/goproxy v1.7.2/go.mod h1:82vkLNir0ALaW14Rc399OTTjyNREgmdL2cVoIbS6XaE=
|
||||
github.com/elliotchance/orderedmap/v3 v3.1.0 h1:j4DJ5ObEmMBt/lcwIecKcoRxIQUEnw0L804lXYDt/pg=
|
||||
github.com/elliotchance/orderedmap/v3 v3.1.0/go.mod h1:G+Hc2RwaZvJMcS4JpGCOyViCnGeKf0bTYCGTO4uhjSo=
|
||||
github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc=
|
||||
github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ=
|
||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
|
||||
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
|
||||
github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
|
||||
github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
|
||||
github.com/gliderlabs/ssh v0.3.8 h1:a4YXD1V7xMF9g5nTkdfnja3Sxy1PVDCj1Zg4Wb8vY6c=
|
||||
github.com/gliderlabs/ssh v0.3.8/go.mod h1:xYoytBv1sV0aL3CavoDuJIQNURXkkfPA/wxQ1pL1fAU=
|
||||
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI=
|
||||
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic=
|
||||
github.com/go-git/go-billy/v5 v5.6.2 h1:6Q86EsPXMa7c3YZ3aLAQsMA0VlWmy43r6FHqa/UNbRM=
|
||||
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.7.0 h1:83lBUJhGWhYp0ngzCMSgllhUSuoHP1iEWYjsPl9nwqM=
|
||||
github.com/go-git/go-billy/v5 v5.7.0/go.mod h1:/1IUejTKH8xipsAcdfcSAlUlo2J7lkYV8GTKxAT/L3E=
|
||||
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4=
|
||||
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII=
|
||||
github.com/go-git/go-git/v5 v5.16.4 h1:7ajIEZHZJULcyJebDLo99bGgS0jRrOxzZG4uCk2Yb2Y=
|
||||
github.com/go-git/go-git/v5 v5.16.4/go.mod h1:4Ge4alE/5gPs30F2H1esi2gPd69R0C39lolkucHBOp8=
|
||||
github.com/go-quicktest/qt v1.101.0 h1:O1K29Txy5P2OK0dGo59b7b0LR6wKfIhttaAhHUyn7eI=
|
||||
github.com/go-quicktest/qt v1.101.0/go.mod h1:14Bz/f7NwaXPtdYEgzsx46kqSxVwTbzVZsDC26tQJow=
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
|
||||
github.com/go-task/template v0.2.0 h1:xW7ek0o65FUSTbKcSNeg2Vyf/I7wYXFgLUznptvviBE=
|
||||
github.com/go-task/template v0.2.0/go.mod h1:dbdoUb6qKnHQi1y6o+IdIrs0J4o/SEhSTA6bbzZmdtc=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ=
|
||||
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/google/martian/v3 v3.3.2 h1:IqNFLAmvJOgVlpdEBiQbDc2EwKW77amAycfTuWKdfvw=
|
||||
github.com/google/martian/v3 v3.3.2/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.2.3 h1:yk9/cqRKtT9wXZSsRH9aurXEpJX+U6FLtpYTdC3R06k=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k=
|
||||
github.com/googleapis/gax-go/v2 v2.7.1 h1:gF4c0zjUP2H/s/hEGyLA3I0fA2ZWjzYiONAD6cvPr8A=
|
||||
github.com/googleapis/gax-go/v2 v2.7.1/go.mod h1:4orTrqY6hXxxaUL4LHIPl6lGo8vAE38/qKbhSAKP6QI=
|
||||
github.com/hashicorp/aws-sdk-go-base/v2 v2.0.0-beta.65 h1:81+kWbE1yErFBMjME0I5k3x3kojjKsWtPYHEAutoPow=
|
||||
github.com/hashicorp/aws-sdk-go-base/v2 v2.0.0-beta.65/go.mod h1:WtMzv9T++tfWVea+qB2MXoaqxw33S8bpJslzUike2mQ=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
|
||||
github.com/hashicorp/go-getter v1.8.3 h1:gIS+oTNv3kyYAvlUVgMR46MiG0bM0KuSON/KZEvRoRg=
|
||||
github.com/hashicorp/go-getter v1.8.3/go.mod h1:CUTt9x2bCtJ/sV8ihgrITL3IUE+0BE1j/e4n5P/GIM4=
|
||||
github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek=
|
||||
github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
||||
github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM=
|
||||
github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg=
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
|
||||
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
||||
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||
github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4=
|
||||
github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
|
||||
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
|
||||
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
|
||||
github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM=
|
||||
@@ -91,26 +149,20 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
|
||||
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/mitchellh/hashstructure/v2 v2.0.2 h1:vGKWl0YJqUNxE8d+h8f6NJLcCJrgbhC4NcD46KavDd4=
|
||||
github.com/mitchellh/hashstructure/v2 v2.0.2/go.mod h1:MG3aRVU/N29oo/V/IhBX8GR/zz4kQkprJgF2EVszyDE=
|
||||
github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k=
|
||||
github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY=
|
||||
github.com/pierrec/lz4/v4 v4.1.22 h1:cKFw6uJDK+/gfw5BcDL0JL5aBsAFdsIT18eRtLj7VIU=
|
||||
github.com/pierrec/lz4/v4 v4.1.22/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
||||
github.com/pjbgf/sha1cd v0.3.2 h1:a9wb0bp1oC2TGwStyn0Umc/IGKQnEgF0vVaZ8QF8eo4=
|
||||
github.com/pjbgf/sha1cd v0.3.2/go.mod h1:zQWigSxVmsHEZow5qaLtPYxpcKMMQpa09ixqBxuCS6A=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/puzpuzpuz/xsync/v4 v4.1.0 h1:x9eHRl4QhZFIPJ17yl4KKW9xLyVWbb3/Yq4SXpjF71U=
|
||||
github.com/puzpuzpuz/xsync/v4 v4.1.0/go.mod h1:VJDmTCJMBt8igNxnkQd86r+8KUeN1quSfNKu5bLYFQo=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/puzpuzpuz/xsync/v4 v4.2.0 h1:dlxm77dZj2c3rxq0/XNvvUKISAmovoXF4a4qM6Wvkr0=
|
||||
github.com/puzpuzpuz/xsync/v4 v4.2.0/go.mod h1:VJDmTCJMBt8igNxnkQd86r+8KUeN1quSfNKu5bLYFQo=
|
||||
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
|
||||
@@ -122,69 +174,119 @@ github.com/sebdah/goldie/v2 v2.8.0/go.mod h1:oZ9fp0+se1eapSRjfYbsV/0Hqhbuu3bJVvK
|
||||
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8=
|
||||
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4=
|
||||
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/skeema/knownhosts v1.3.1 h1:X2osQ+RAjK76shCbvhHHHVl3ZlgDm8apHEHFqRjnBY8=
|
||||
github.com/skeema/knownhosts v1.3.1/go.mod h1:r7KTdC8l4uxWRyK2TpQZ/1o5HaSzh06ePQNxPwTcfiY=
|
||||
github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
|
||||
github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
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/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
||||
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
||||
github.com/u-root/u-root v0.15.1-0.20251014130006-62f7144b33da h1:Vst9Tvq3G6f6pYBvxy7coi2arDsnOZ3Mkj8MkNarSK8=
|
||||
github.com/u-root/u-root v0.15.1-0.20251014130006-62f7144b33da/go.mod h1:R49zft13memK20EgFAvmTbXBS0t29UvglnM0BCA1ldQ=
|
||||
github.com/u-root/uio v0.0.0-20240224005618-d2acac8f3701 h1:pyC9PaHYZFgEKFdlp3G8RaCKgVpHZnecvArXvPXcFkM=
|
||||
github.com/u-root/uio v0.0.0-20240224005618-d2acac8f3701/go.mod h1:P3a5rG4X7tI17Nn3aOIAYr5HbIMukwXG0urG0WuL8OA=
|
||||
github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=
|
||||
github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw=
|
||||
github.com/ulikunitz/xz v0.5.15 h1:9DNdB5s+SgV3bQ2ApL10xRc35ck0DuIX/isZvIk+ubY=
|
||||
github.com/ulikunitz/xz v0.5.15/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
|
||||
github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ=
|
||||
github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0=
|
||||
github.com/zeebo/xxh3 v1.0.2 h1:xZmwmqxHZA8AI603jOQ0tMqmBr9lPeFwGg6d+xy9DC0=
|
||||
github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA=
|
||||
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
|
||||
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
|
||||
go.yaml.in/yaml/v4 v4.0.0-rc.3 h1:3h1fjsh1CTAPjW7q/EMe+C8shx5d8ctzZTrLcs/j8Go=
|
||||
go.yaml.in/yaml/v4 v4.0.0-rc.3/go.mod h1:aZqd9kCMsGL7AuUv/m/PvWLdg5sjJsZ4oHDEnfPPfY0=
|
||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=
|
||||
golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=
|
||||
golang.org/x/exp v0.0.0-20250305212735-054e65f0b394 h1:nDVHiLt8aIbd/VzvPWN6kSOPE7+F/fNFDSXLVYkE/Iw=
|
||||
golang.org/x/exp v0.0.0-20250305212735-054e65f0b394/go.mod h1:sIifuuw/Yco/y6yb6+bDNfyeQ/MdPUy/hKEMYQV17cM=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
|
||||
golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
|
||||
golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I=
|
||||
golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.27.0 h1:da9Vo7/tDv5RH/7nZDz1eMGS/q1Vv1N/7FCrBhI9I3M=
|
||||
golang.org/x/oauth2 v0.27.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
|
||||
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
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.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
|
||||
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU=
|
||||
golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk=
|
||||
golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/term v0.38.0 h1:PQ5pkm/rLO6HnxFR7N2lJHOZX6Kez5Y1gDSJla6jo7Q=
|
||||
golang.org/x/term v0.38.0/go.mod h1:bSEAKrOT1W+VSu9TSCMtoGEOUcKxOKgl3LE5QEF/xVg=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=
|
||||
golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk=
|
||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
|
||||
google.golang.org/api v0.114.0 h1:1xQPji6cO2E2vLiI+C/XiFAnsn1WV3mjaEwGLhi3grE=
|
||||
google.golang.org/api v0.114.0/go.mod h1:ifYI2ZsFK6/uGddGfAD5BMxlnkBqCmqHSDUVi45N5Yg=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
|
||||
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 h1:KpwkzHKEF7B9Zxg18WzOa7djJ+Ha5DzthMyZYQfEn2A=
|
||||
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
|
||||
google.golang.org/grpc v1.56.3 h1:8I4C0Yq1EjstUzUJzpcRVbuYA2mODtEmpWiQoN/b2nc=
|
||||
google.golang.org/grpc v1.56.3/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
|
||||
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
|
||||
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
mvdan.cc/sh/moreinterp v0.0.0-20251109230715-65adef8e2c5b h1:vTpx76nZDTP/BAGnnhEXYjM+8nPKe9+I86qCErBvjCw=
|
||||
mvdan.cc/sh/moreinterp v0.0.0-20251109230715-65adef8e2c5b/go.mod h1:bDyKbUYKqkFunWmxxuSPrkYpln9QZcUsqu7W128qYW4=
|
||||
mvdan.cc/sh/v3 v3.12.0 h1:ejKUR7ONP5bb+UGHGEG/k9V5+pRVIyD+LsZz7o8KHrI=
|
||||
|
||||
@@ -5,13 +5,16 @@ import (
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/fatih/color"
|
||||
"github.com/spf13/pflag"
|
||||
|
||||
"github.com/go-task/task/v3"
|
||||
"github.com/go-task/task/v3/errors"
|
||||
"github.com/go-task/task/v3/experiments"
|
||||
"github.com/go-task/task/v3/internal/env"
|
||||
"github.com/go-task/task/v3/internal/sort"
|
||||
"github.com/go-task/task/v3/taskfile/ast"
|
||||
"github.com/go-task/task/v3/taskrc"
|
||||
@@ -79,6 +82,7 @@ var (
|
||||
ClearCache bool
|
||||
Timeout time.Duration
|
||||
CacheExpiryDuration time.Duration
|
||||
RemoteCacheDir string
|
||||
)
|
||||
|
||||
func init() {
|
||||
@@ -138,7 +142,7 @@ func init() {
|
||||
pflag.StringVar(&Output.Group.Begin, "output-group-begin", "", "Message template to print before a task's grouped output.")
|
||||
pflag.StringVar(&Output.Group.End, "output-group-end", "", "Message template to print after a task's grouped output.")
|
||||
pflag.BoolVar(&Output.Group.ErrorOnly, "output-group-error-only", false, "Swallow output from successful tasks.")
|
||||
pflag.BoolVarP(&Color, "color", "c", true, "Colored output. Enabled by default. Set flag to false or use NO_COLOR=1 to disable.")
|
||||
pflag.BoolVarP(&Color, "color", "c", getConfig(config, func() *bool { return config.Color }, true), "Colored output. Enabled by default. Set flag to false or use NO_COLOR=1 to disable.")
|
||||
pflag.IntVarP(&Concurrency, "concurrency", "C", getConfig(config, func() *int { return config.Concurrency }, 0), "Limit number of tasks to run concurrently.")
|
||||
pflag.DurationVarP(&Interval, "interval", "I", 0, "Interval to watch for changes.")
|
||||
pflag.BoolVarP(&Failfast, "failfast", "F", getConfig(config, func() *bool { return &config.Failfast }, false), "When running tasks in parallel, stop all tasks if one fails.")
|
||||
@@ -157,12 +161,36 @@ func init() {
|
||||
if experiments.RemoteTaskfiles.Enabled() {
|
||||
pflag.BoolVar(&Download, "download", false, "Downloads a cached version of a remote Taskfile.")
|
||||
pflag.BoolVar(&Offline, "offline", getConfig(config, func() *bool { return config.Remote.Offline }, false), "Forces Task to only use local or cached Taskfiles.")
|
||||
pflag.StringSliceVar(&TrustedHosts, "trusted-hosts", config.Remote.TrustedHosts, "List of trusted hosts for remote Taskfiles (comma-separated).")
|
||||
pflag.StringSliceVar(&TrustedHosts, "trusted-hosts", getConfig(config, func() *[]string { return &config.Remote.TrustedHosts }, nil), "List of trusted hosts for remote Taskfiles (comma-separated).")
|
||||
pflag.DurationVar(&Timeout, "timeout", getConfig(config, func() *time.Duration { return config.Remote.Timeout }, time.Second*10), "Timeout for downloading remote Taskfiles.")
|
||||
pflag.BoolVar(&ClearCache, "clear-cache", false, "Clear the remote cache.")
|
||||
pflag.DurationVar(&CacheExpiryDuration, "expiry", getConfig(config, func() *time.Duration { return config.Remote.CacheExpiry }, 0), "Expiry duration for cached remote Taskfiles.")
|
||||
pflag.StringVar(&RemoteCacheDir, "remote-cache-dir", getConfig(config, func() *string { return config.Remote.CacheDir }, env.GetTaskEnv("REMOTE_DIR")), "Directory to cache remote Taskfiles.")
|
||||
}
|
||||
pflag.Parse()
|
||||
|
||||
// Auto-detect color based on environment when not explicitly configured
|
||||
// Priority: CLI flag > taskrc config > NO_COLOR > FORCE_COLOR/CI > default
|
||||
colorExplicitlySet := pflag.Lookup("color").Changed || (config != nil && config.Color != nil)
|
||||
if !colorExplicitlySet {
|
||||
if os.Getenv("NO_COLOR") != "" {
|
||||
Color = false
|
||||
color.NoColor = true
|
||||
} else if os.Getenv("FORCE_COLOR") != "" || isCI() {
|
||||
Color = true
|
||||
color.NoColor = false // Force colors even without TTY
|
||||
}
|
||||
// Otherwise, let fatih/color auto-detect TTY
|
||||
} else {
|
||||
// Explicit config: sync with fatih/color
|
||||
color.NoColor = !Color
|
||||
}
|
||||
}
|
||||
|
||||
// isCI returns true if running in a CI environment
|
||||
func isCI() bool {
|
||||
ci, _ := strconv.ParseBool(os.Getenv("CI"))
|
||||
return ci
|
||||
}
|
||||
|
||||
func Validate() error {
|
||||
@@ -247,6 +275,7 @@ func (o *flagsOption) ApplyToExecutor(e *task.Executor) {
|
||||
task.WithTrustedHosts(TrustedHosts),
|
||||
task.WithTimeout(Timeout),
|
||||
task.WithCacheExpiryDuration(CacheExpiryDuration),
|
||||
task.WithRemoteCacheDir(RemoteCacheDir),
|
||||
task.WithWatch(Watch),
|
||||
task.WithVerbose(Verbose),
|
||||
task.WithSilent(Silent),
|
||||
|
||||
@@ -3,7 +3,6 @@ package logger
|
||||
import (
|
||||
"bufio"
|
||||
"io"
|
||||
"os"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -96,10 +95,6 @@ func BrightRed() PrintFunc {
|
||||
}
|
||||
|
||||
func envColor(name string, defaultColor color.Attribute) []color.Attribute {
|
||||
if os.Getenv("FORCE_COLOR") != "" {
|
||||
color.NoColor = false
|
||||
}
|
||||
|
||||
// Fetch the environment variable
|
||||
override := env.GetTaskEnv(name)
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
3.45.5
|
||||
3.46.2
|
||||
|
||||
12
setup.go
12
setup.go
@@ -153,16 +153,16 @@ func (e *Executor) setupTempDir() error {
|
||||
}
|
||||
}
|
||||
|
||||
remoteDir := env.GetTaskEnv("REMOTE_DIR")
|
||||
if remoteDir != "" {
|
||||
if filepath.IsAbs(remoteDir) || strings.HasPrefix(remoteDir, "~") {
|
||||
remoteTempDir, err := execext.ExpandLiteral(remoteDir)
|
||||
// RemoteCacheDir from taskrc/env can override the remote cache directory
|
||||
if e.RemoteCacheDir != "" {
|
||||
if filepath.IsAbs(e.RemoteCacheDir) || strings.HasPrefix(e.RemoteCacheDir, "~") {
|
||||
remoteCacheDir, err := execext.ExpandLiteral(e.RemoteCacheDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
e.TempDir.Remote = remoteTempDir
|
||||
e.TempDir.Remote = remoteCacheDir
|
||||
} else {
|
||||
e.TempDir.Remote = filepathext.SmartJoin(e.Dir, ".task")
|
||||
e.TempDir.Remote = filepathext.SmartJoin(e.Dir, e.RemoteCacheDir)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
10
task.go
10
task.go
@@ -311,10 +311,12 @@ func (e *Executor) runCommand(ctx context.Context, t *ast.Task, call *Call, i in
|
||||
defer reacquire()
|
||||
|
||||
err := e.RunTask(ctx, &Call{Task: cmd.Task, Vars: cmd.Vars, Silent: cmd.Silent, Indirect: true})
|
||||
if err != nil {
|
||||
return err
|
||||
var exitCode interp.ExitStatus
|
||||
if errors.As(err, &exitCode) && cmd.IgnoreError {
|
||||
e.Logger.VerboseErrf(logger.Yellow, "task: [%s] task error ignored: %v\n", t.Name(), err)
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
return err
|
||||
case cmd.Cmd != "":
|
||||
if !shouldRunOnCurrentPlatform(cmd.Platforms) {
|
||||
e.Logger.VerboseOutf(logger.Yellow, "task: [%s] %s not for current platform - ignored\n", t.Name(), cmd.Cmd)
|
||||
@@ -370,7 +372,7 @@ func (e *Executor) startExecution(ctx context.Context, t *ast.Task, execute func
|
||||
return err
|
||||
}
|
||||
|
||||
if h == "" {
|
||||
if h == "" || t.Watch {
|
||||
return execute(ctx)
|
||||
}
|
||||
|
||||
|
||||
@@ -93,6 +93,7 @@ func (c *Cmd) UnmarshalYAML(node *yaml.Node) error {
|
||||
c.Vars = cmdStruct.Vars
|
||||
c.For = cmdStruct.For
|
||||
c.Silent = cmdStruct.Silent
|
||||
c.IgnoreError = cmdStruct.IgnoreError
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -118,7 +118,7 @@ func (vars *Vars) ToCacheMap() (m map[string]any) {
|
||||
|
||||
// Merge loops over other and merges it values with the variables in vars. If
|
||||
// the include parameter is not nil and its it is an advanced import, the
|
||||
// directory is set set to the value of the include parameter.
|
||||
// directory is set to the value of the include parameter.
|
||||
func (vars *Vars) Merge(other *Vars, include *Include) {
|
||||
if vars == nil || vars.om == nil || other == nil {
|
||||
return
|
||||
@@ -133,6 +133,35 @@ func (vars *Vars) Merge(other *Vars, include *Include) {
|
||||
}
|
||||
}
|
||||
|
||||
// ReverseMerge merges other variables with the existing variables in vars, but
|
||||
// keeps the other variables first in order. If the include parameter is not
|
||||
// nil and it is an advanced import, the directory is set to the value of the
|
||||
// include parameter.
|
||||
func (vars *Vars) ReverseMerge(other *Vars, include *Include) {
|
||||
if vars == nil || vars.om == nil || other == nil || other.om == nil {
|
||||
return
|
||||
}
|
||||
|
||||
newOM := orderedmap.NewOrderedMap[string, Var]()
|
||||
|
||||
other.mutex.RLock()
|
||||
for pair := other.om.Front(); pair != nil; pair = pair.Next() {
|
||||
val := pair.Value
|
||||
if include != nil && include.AdvancedImport {
|
||||
val.Dir = include.Dir
|
||||
}
|
||||
newOM.Set(pair.Key, val)
|
||||
}
|
||||
other.mutex.RUnlock()
|
||||
|
||||
vars.mutex.Lock()
|
||||
for pair := vars.om.Front(); pair != nil; pair = pair.Next() {
|
||||
newOM.Set(pair.Key, pair.Value)
|
||||
}
|
||||
vars.om = newOM
|
||||
vars.mutex.Unlock()
|
||||
}
|
||||
|
||||
func (vs *Vars) DeepCopy() *Vars {
|
||||
if vs == nil {
|
||||
return nil
|
||||
|
||||
@@ -3,16 +3,14 @@ package taskfile
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
giturls "github.com/chainguard-dev/git-urls"
|
||||
"github.com/go-git/go-billy/v5/memfs"
|
||||
"github.com/go-git/go-git/v5"
|
||||
"github.com/go-git/go-git/v5/plumbing"
|
||||
"github.com/go-git/go-git/v5/storage/memory"
|
||||
"github.com/hashicorp/go-getter"
|
||||
|
||||
"github.com/go-task/task/v3/errors"
|
||||
"github.com/go-task/task/v3/internal/execext"
|
||||
@@ -28,6 +26,36 @@ type GitNode struct {
|
||||
path string
|
||||
}
|
||||
|
||||
type gitRepoCache struct {
|
||||
mu sync.Mutex // Protects the locks map
|
||||
locks map[string]*sync.Mutex // One mutex per repo cache key
|
||||
}
|
||||
|
||||
func (c *gitRepoCache) getLockForRepo(cacheKey string) *sync.Mutex {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
|
||||
if _, exists := c.locks[cacheKey]; !exists {
|
||||
c.locks[cacheKey] = &sync.Mutex{}
|
||||
}
|
||||
|
||||
return c.locks[cacheKey]
|
||||
}
|
||||
|
||||
var globalGitRepoCache = &gitRepoCache{
|
||||
locks: make(map[string]*sync.Mutex),
|
||||
}
|
||||
|
||||
func CleanGitCache() error {
|
||||
// Clear the in-memory locks map to prevent memory leak
|
||||
globalGitRepoCache.mu.Lock()
|
||||
globalGitRepoCache.locks = make(map[string]*sync.Mutex)
|
||||
globalGitRepoCache.mu.Unlock()
|
||||
|
||||
cacheDir := filepath.Join(os.TempDir(), "task-git-repos")
|
||||
return os.RemoveAll(cacheDir)
|
||||
}
|
||||
|
||||
func NewGitNode(
|
||||
entrypoint string,
|
||||
dir string,
|
||||
@@ -72,24 +100,78 @@ func (node *GitNode) Read() ([]byte, error) {
|
||||
return node.ReadContext(context.Background())
|
||||
}
|
||||
|
||||
func (node *GitNode) ReadContext(_ context.Context) ([]byte, error) {
|
||||
fs := memfs.New()
|
||||
storer := memory.NewStorage()
|
||||
_, err := git.Clone(storer, fs, &git.CloneOptions{
|
||||
URL: node.url.String(),
|
||||
ReferenceName: plumbing.ReferenceName(node.ref),
|
||||
SingleBranch: true,
|
||||
Depth: 1,
|
||||
})
|
||||
func (node *GitNode) buildURL() string {
|
||||
// Get the base URL
|
||||
baseURL := node.url.String()
|
||||
|
||||
ref := node.ref
|
||||
if ref == "" {
|
||||
ref = "HEAD"
|
||||
}
|
||||
// Always use git:: prefix for git URLs (following Terraform's pattern)
|
||||
// This forces go-getter to use git protocol
|
||||
return fmt.Sprintf("git::%s?ref=%s&depth=1", baseURL, ref)
|
||||
}
|
||||
|
||||
// getOrCloneRepo returns the path to a cached git repository.
|
||||
// If the repository is not cached, it clones it first.
|
||||
// This function is thread-safe: multiple goroutines cloning the same repo+ref
|
||||
// will synchronize, and only one clone operation will occur.
|
||||
//
|
||||
// The cache directory is /tmp/task-git-repos/{cache_key}/
|
||||
func (node *GitNode) getOrCloneRepo(ctx context.Context) (string, error) {
|
||||
cacheKey := node.repoCacheKey()
|
||||
|
||||
repoMutex := globalGitRepoCache.getLockForRepo(cacheKey)
|
||||
repoMutex.Lock()
|
||||
defer repoMutex.Unlock()
|
||||
|
||||
// Check if context was cancelled while waiting for lock
|
||||
if err := ctx.Err(); err != nil {
|
||||
return "", fmt.Errorf("context cancelled while waiting for repository lock: %w", err)
|
||||
}
|
||||
|
||||
cacheDir := filepath.Join(os.TempDir(), "task-git-repos", cacheKey)
|
||||
|
||||
// check if repo is already cached (under the lock)
|
||||
gitDir := filepath.Join(cacheDir, ".git")
|
||||
if _, err := os.Stat(gitDir); err == nil {
|
||||
return cacheDir, nil
|
||||
}
|
||||
|
||||
getterURL := node.buildURL()
|
||||
|
||||
client := &getter.Client{
|
||||
Ctx: ctx,
|
||||
Src: getterURL,
|
||||
Dst: cacheDir,
|
||||
Mode: getter.ClientModeDir,
|
||||
}
|
||||
|
||||
if err := client.Get(); err != nil {
|
||||
_ = os.RemoveAll(cacheDir)
|
||||
return "", fmt.Errorf("failed to clone repository: %w", err)
|
||||
}
|
||||
|
||||
return cacheDir, nil
|
||||
}
|
||||
|
||||
func (node *GitNode) ReadContext(ctx context.Context) ([]byte, error) {
|
||||
// Get or clone the repository into cache
|
||||
repoDir, err := node.getOrCloneRepo(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
file, err := fs.Open(node.path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
// Build path to Taskfile in the cached repo
|
||||
taskfilePath := node.path
|
||||
if taskfilePath == "" {
|
||||
taskfilePath = "Taskfile.yml"
|
||||
}
|
||||
// Read the entire response body
|
||||
b, err := io.ReadAll(file)
|
||||
filePath := filepath.Join(repoDir, taskfilePath)
|
||||
|
||||
// Read file from cached repo
|
||||
b, err := os.ReadFile(filePath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -138,6 +220,22 @@ func (node *GitNode) CacheKey() string {
|
||||
return fmt.Sprintf("git.%s.%s.%s", node.url.Host, prefix, checksum)
|
||||
}
|
||||
|
||||
// repoCacheKey generates a unique cache key for the repository+ref combination.
|
||||
// Unlike CacheKey() which includes the file path, this identifies the repository itself.
|
||||
// Two GitNodes with the same repo+ref but different file paths will share the same cache.
|
||||
//
|
||||
// Returns a path like: github.com/user/repo.git/main
|
||||
func (node *GitNode) repoCacheKey() string {
|
||||
repoPath := strings.Trim(node.url.Path, "/")
|
||||
|
||||
ref := node.ref
|
||||
if ref == "" {
|
||||
ref = "HEAD"
|
||||
}
|
||||
|
||||
return filepath.Join(node.url.Host, repoPath, ref)
|
||||
}
|
||||
|
||||
func splitURLOnDoubleSlash(u *url.URL) (string, string) {
|
||||
x := strings.Split(u.Path, "//")
|
||||
switch len(x) {
|
||||
|
||||
@@ -102,3 +102,146 @@ func TestGitNode_CacheKey(t *testing.T) {
|
||||
assert.Equal(t, tt.expectedKey, key)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGitNode_buildURL(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
entrypoint string
|
||||
expectedURL string
|
||||
}{
|
||||
{
|
||||
name: "HTTPS with ref",
|
||||
entrypoint: "https://github.com/foo/bar.git//Taskfile.yml?ref=main",
|
||||
expectedURL: "git::https://github.com/foo/bar.git?ref=main&depth=1",
|
||||
},
|
||||
{
|
||||
name: "SSH with ref",
|
||||
entrypoint: "git@github.com:foo/bar.git//Taskfile.yml?ref=main",
|
||||
expectedURL: "git::ssh://git@github.com/foo/bar.git?ref=main&depth=1",
|
||||
},
|
||||
{
|
||||
name: "HTTPS with tag ref",
|
||||
entrypoint: "https://github.com/foo/bar.git//Taskfile.yml?ref=v1.0.0",
|
||||
expectedURL: "git::https://github.com/foo/bar.git?ref=v1.0.0&depth=1",
|
||||
},
|
||||
{
|
||||
name: "HTTPS without ref (uses remote HEAD)",
|
||||
entrypoint: "https://github.com/foo/bar.git//Taskfile.yml",
|
||||
expectedURL: "git::https://github.com/foo/bar.git?ref=HEAD&depth=1",
|
||||
},
|
||||
{
|
||||
name: "SSH with directory path",
|
||||
entrypoint: "git@github.com:foo/bar.git//directory/Taskfile.yml?ref=dev",
|
||||
expectedURL: "git::ssh://git@github.com/foo/bar.git?ref=dev&depth=1",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
node, err := NewGitNode(tt.entrypoint, "", false)
|
||||
require.NoError(t, err)
|
||||
gotURL := node.buildURL()
|
||||
assert.Equal(t, tt.expectedURL, gotURL)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestRepoCacheKey_SameRepoSameRef(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
// Same repo, same ref, different files should have SAME cache key
|
||||
node1, err := NewGitNode("https://github.com/foo/bar.git//file1.yml?ref=main", "", false)
|
||||
require.NoError(t, err)
|
||||
|
||||
node2, err := NewGitNode("https://github.com/foo/bar.git//dir/file2.yml?ref=main", "", false)
|
||||
require.NoError(t, err)
|
||||
|
||||
key1 := node1.repoCacheKey()
|
||||
key2 := node2.repoCacheKey()
|
||||
|
||||
assert.Equal(t, key1, key2, "Same repo+ref should generate same cache key regardless of file path")
|
||||
}
|
||||
|
||||
func TestRepoCacheKey_SameRepoDifferentRef(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
// Same repo, different ref should have DIFFERENT cache keys
|
||||
node1, err := NewGitNode("https://github.com/foo/bar.git//file.yml?ref=main", "", false)
|
||||
require.NoError(t, err)
|
||||
|
||||
node2, err := NewGitNode("https://github.com/foo/bar.git//file.yml?ref=dev", "", false)
|
||||
require.NoError(t, err)
|
||||
|
||||
key1 := node1.repoCacheKey()
|
||||
key2 := node2.repoCacheKey()
|
||||
|
||||
assert.NotEqual(t, key1, key2, "Different refs should generate different cache keys")
|
||||
}
|
||||
|
||||
func TestRepoCacheKey_DifferentRepos(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
// Different repos should have DIFFERENT cache keys
|
||||
node1, err := NewGitNode("https://github.com/foo/bar.git//file.yml?ref=main", "", false)
|
||||
require.NoError(t, err)
|
||||
|
||||
node2, err := NewGitNode("https://github.com/foo/other.git//file.yml?ref=main", "", false)
|
||||
require.NoError(t, err)
|
||||
|
||||
key1 := node1.repoCacheKey()
|
||||
key2 := node2.repoCacheKey()
|
||||
|
||||
assert.NotEqual(t, key1, key2, "Different repos should generate different cache keys")
|
||||
}
|
||||
|
||||
func TestRepoCacheKey_NoRefVsHead(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
// No ref (defaults to HEAD) vs explicit HEAD should have SAME cache key
|
||||
node1, err := NewGitNode("https://github.com/foo/bar.git//file.yml", "", false)
|
||||
require.NoError(t, err)
|
||||
|
||||
node2, err := NewGitNode("https://github.com/foo/bar.git//file.yml?ref=HEAD", "", false)
|
||||
require.NoError(t, err)
|
||||
|
||||
key1 := node1.repoCacheKey()
|
||||
key2 := node2.repoCacheKey()
|
||||
|
||||
assert.Equal(t, key1, key2, "No ref and explicit HEAD should generate same cache key")
|
||||
}
|
||||
|
||||
func TestRepoCacheKey_SSHvsHTTPS(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
// SSH vs HTTPS pointing to same repo should have SAME cache key
|
||||
// They clone the same repo, so we want to share the cache
|
||||
node1, err := NewGitNode("git@github.com:foo/bar.git//file.yml?ref=main", "", false)
|
||||
require.NoError(t, err)
|
||||
|
||||
node2, err := NewGitNode("https://github.com/foo/bar.git//file.yml?ref=main", "", false)
|
||||
require.NoError(t, err)
|
||||
|
||||
key1 := node1.repoCacheKey()
|
||||
key2 := node2.repoCacheKey()
|
||||
|
||||
assert.Equal(t, key1, key2, "SSH and HTTPS for same repo should share cache")
|
||||
}
|
||||
|
||||
func TestRepoCacheKey_Consistency(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
// Calling repoCacheKey multiple times on same node should return same key
|
||||
node, err := NewGitNode("https://github.com/foo/bar.git//file.yml?ref=main", "", false)
|
||||
require.NoError(t, err)
|
||||
|
||||
key1 := node.repoCacheKey()
|
||||
key2 := node.repoCacheKey()
|
||||
key3 := node.repoCacheKey()
|
||||
|
||||
assert.Equal(t, key1, key2)
|
||||
assert.Equal(t, key2, key3)
|
||||
}
|
||||
|
||||
@@ -204,9 +204,15 @@ func (o *promptFuncOption) ApplyToReader(r *Reader) {
|
||||
// building an [ast.TaskfileGraph] as it goes. If any errors occur, they will be
|
||||
// returned immediately.
|
||||
func (r *Reader) Read(ctx context.Context, node Node) (*ast.TaskfileGraph, error) {
|
||||
// Clean up git cache after reading all taskfiles
|
||||
defer func() {
|
||||
_ = CleanGitCache()
|
||||
}()
|
||||
|
||||
if err := r.include(ctx, node); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return r.graph, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
type TaskRC struct {
|
||||
Version *semver.Version `yaml:"version"`
|
||||
Verbose *bool `yaml:"verbose"`
|
||||
Color *bool `yaml:"color"`
|
||||
DisableFuzzy *bool `yaml:"disable-fuzzy"`
|
||||
Concurrency *int `yaml:"concurrency"`
|
||||
Remote Remote `yaml:"remote"`
|
||||
@@ -24,6 +25,7 @@ type Remote struct {
|
||||
Offline *bool `yaml:"offline"`
|
||||
Timeout *time.Duration `yaml:"timeout"`
|
||||
CacheExpiry *time.Duration `yaml:"cache-expiry"`
|
||||
CacheDir *string `yaml:"cache-dir"`
|
||||
TrustedHosts []string `yaml:"trusted-hosts"`
|
||||
}
|
||||
|
||||
@@ -46,7 +48,7 @@ func (t *TaskRC) Merge(other *TaskRC) {
|
||||
t.Remote.Offline = cmp.Or(other.Remote.Offline, t.Remote.Offline)
|
||||
t.Remote.Timeout = cmp.Or(other.Remote.Timeout, t.Remote.Timeout)
|
||||
t.Remote.CacheExpiry = cmp.Or(other.Remote.CacheExpiry, t.Remote.CacheExpiry)
|
||||
|
||||
t.Remote.CacheDir = cmp.Or(other.Remote.CacheDir, t.Remote.CacheDir)
|
||||
if len(other.Remote.TrustedHosts) > 0 {
|
||||
merged := slices.Concat(other.Remote.TrustedHosts, t.Remote.TrustedHosts)
|
||||
slices.Sort(merged)
|
||||
@@ -54,6 +56,7 @@ func (t *TaskRC) Merge(other *TaskRC) {
|
||||
}
|
||||
|
||||
t.Verbose = cmp.Or(other.Verbose, t.Verbose)
|
||||
t.Color = cmp.Or(other.Color, t.Color)
|
||||
t.DisableFuzzy = cmp.Or(other.DisableFuzzy, t.DisableFuzzy)
|
||||
t.Concurrency = cmp.Or(other.Concurrency, t.Concurrency)
|
||||
t.Failfast = cmp.Or(other.Failfast, t.Failfast)
|
||||
|
||||
7
testdata/vars/Taskfile.yml
vendored
7
testdata/vars/Taskfile.yml
vendored
@@ -49,3 +49,10 @@ tasks:
|
||||
- echo "{{.MESSAGE}}"
|
||||
|
||||
from-dot-env: echo '{{.DOT_ENV_VAR}}'
|
||||
|
||||
# Test that CLI variables take priority over Taskfile defaults
|
||||
cli-var-priority:
|
||||
vars:
|
||||
CLI_VAR: '{{.CLI_VAR | default "default_value"}}'
|
||||
cmds:
|
||||
- echo '{{.CLI_VAR}}'
|
||||
|
||||
1
testdata/vars/testdata/TestVars-cli-var-priority-default.golden
vendored
Normal file
1
testdata/vars/testdata/TestVars-cli-var-priority-default.golden
vendored
Normal file
@@ -0,0 +1 @@
|
||||
default_value
|
||||
1
testdata/vars/testdata/TestVars-cli-var-priority-override.golden
vendored
Normal file
1
testdata/vars/testdata/TestVars-cli-var-priority-override.golden
vendored
Normal file
@@ -0,0 +1 @@
|
||||
from_cli
|
||||
@@ -1,4 +1,4 @@
|
||||
import { defineConfig } from 'vitepress';
|
||||
import { defineConfig, HeadConfig } from 'vitepress';
|
||||
import githubLinksPlugin from './plugins/github-links';
|
||||
import { readFileSync } from 'fs';
|
||||
import { resolve } from 'path';
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
localIconLoader
|
||||
} from 'vitepress-plugin-group-icons';
|
||||
import { team } from './team.ts';
|
||||
import { taskDescription, taskName } from './meta.ts';
|
||||
import { taskDescription, taskName, ogUrl, ogImage } from './meta.ts';
|
||||
import { fileURLToPath, URL } from 'node:url';
|
||||
import llmstxt, { copyOrDownloadAsMarkdownButtons } from 'vitepress-plugin-llms';
|
||||
|
||||
@@ -40,7 +40,7 @@ export default defineConfig({
|
||||
{
|
||||
rel: 'icon',
|
||||
type: 'image/x-icon',
|
||||
href: '/img/favicon.icon',
|
||||
href: '/img/favicon.ico',
|
||||
sizes: '48x48'
|
||||
}
|
||||
],
|
||||
@@ -53,17 +53,23 @@ export default defineConfig({
|
||||
href: '/img/logo.svg'
|
||||
}
|
||||
],
|
||||
[
|
||||
'link',
|
||||
{
|
||||
rel: 'canonical',
|
||||
href: 'https://taskfile.dev/'
|
||||
}
|
||||
],
|
||||
[
|
||||
'meta',
|
||||
{ name: 'author', content: `${team.map((c) => c.name).join(', ')}` }
|
||||
],
|
||||
// Open Graph
|
||||
['meta', { property: 'og:type', content: 'website' }],
|
||||
['meta', { property: 'og:site_name', content: taskName }],
|
||||
['meta', { property: 'og:title', content: taskName }],
|
||||
['meta', { property: 'og:description', content: taskDescription }],
|
||||
['meta', { property: 'og:image', content: ogImage }],
|
||||
['meta', { property: 'og:url', content: ogUrl }],
|
||||
// Twitter Card
|
||||
['meta', { name: 'twitter:card', content: 'summary_large_image' }],
|
||||
['meta', { name: 'twitter:site', content: '@taskfiledev' }],
|
||||
['meta', { name: 'twitter:title', content: taskName }],
|
||||
['meta', { name: 'twitter:description', content: taskDescription }],
|
||||
['meta', { name: 'twitter:image', content: ogImage }],
|
||||
[
|
||||
'meta',
|
||||
{
|
||||
@@ -81,6 +87,22 @@ export default defineConfig({
|
||||
}
|
||||
]
|
||||
],
|
||||
transformHead({ pageData }) {
|
||||
const head: HeadConfig[] = []
|
||||
|
||||
// Canonical URL dynamique
|
||||
const canonicalUrl = `https://taskfile.dev/${pageData.relativePath
|
||||
.replace(/\.md$/, '')
|
||||
.replace(/index$/, '')}`
|
||||
head.push(['link', { rel: 'canonical', href: canonicalUrl }])
|
||||
|
||||
// Noindex pour 404
|
||||
if (pageData.relativePath === '404.md') {
|
||||
head.push(['meta', { name: 'robots', content: 'noindex, nofollow' }])
|
||||
}
|
||||
|
||||
return head
|
||||
},
|
||||
srcDir: 'src',
|
||||
cleanUrls: true,
|
||||
markdown: {
|
||||
@@ -342,6 +364,12 @@ export default defineConfig({
|
||||
}
|
||||
},
|
||||
sitemap: {
|
||||
hostname: 'https://taskfile.dev'
|
||||
hostname: 'https://taskfile.dev',
|
||||
transformItems: (items) => {
|
||||
return items.map((item) => ({
|
||||
...item,
|
||||
lastmod: new Date().toISOString()
|
||||
}));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -3,3 +3,4 @@ export const taskDescription =
|
||||
'A fast, cross-platform build tool inspired by Make, designed for modern workflows.';
|
||||
|
||||
export const ogUrl = 'https://taskfile.dev/';
|
||||
export const ogImage = 'https://taskfile.dev/img/logo.png';
|
||||
|
||||
@@ -20,10 +20,8 @@
|
||||
"vitepress": "^1.6.3",
|
||||
"vitepress-plugin-group-icons": "^1.6.1",
|
||||
"vitepress-plugin-tabs": "^0.7.1",
|
||||
"vitepress-plugin-llms": "^1.9.1",
|
||||
"vue": "^3.5.18"
|
||||
},
|
||||
"packageManager": "pnpm@10.24.0+sha512.01ff8ae71b4419903b65c60fb2dc9d34cf8bb6e06d03bde112ef38f7a34d6904c424ba66bea5cdcf12890230bf39f9580473140ed9c946fef328b6e5238a345a",
|
||||
"dependencies": {
|
||||
"vitepress-plugin-llms": "^1.9.1"
|
||||
}
|
||||
"packageManager": "pnpm@10.26.0+sha512.3b3f6c725ebe712506c0ab1ad4133cf86b1f4b687effce62a9b38b4d72e3954242e643190fc51fa1642949c735f403debd44f5cb0edd657abe63a8b6a7e1e402"
|
||||
}
|
||||
|
||||
77
website/pnpm-lock.yaml
generated
77
website/pnpm-lock.yaml
generated
@@ -7,32 +7,31 @@ settings:
|
||||
importers:
|
||||
|
||||
.:
|
||||
dependencies:
|
||||
vitepress-plugin-llms:
|
||||
specifier: ^1.9.1
|
||||
version: 1.9.3
|
||||
devDependencies:
|
||||
'@types/markdown-it':
|
||||
specifier: ^14.1.2
|
||||
version: 14.1.2
|
||||
'@types/node':
|
||||
specifier: ^24.1.0
|
||||
version: 24.10.1
|
||||
version: 24.10.4
|
||||
netlify-cli:
|
||||
specifier: ^23.1.1
|
||||
version: 23.12.3(@types/node@24.10.1)(picomatch@4.0.3)(rollup@4.46.2)
|
||||
version: 23.12.3(@types/node@24.10.4)(picomatch@4.0.3)(rollup@4.46.2)
|
||||
prettier:
|
||||
specifier: ^3.6.2
|
||||
version: 3.7.4
|
||||
vitepress:
|
||||
specifier: ^1.6.3
|
||||
version: 1.6.4(@algolia/client-search@5.35.0)(@types/node@24.10.1)(jwt-decode@4.0.0)(postcss@8.5.6)(search-insights@2.17.3)(typescript@5.9.3)
|
||||
version: 1.6.4(@algolia/client-search@5.35.0)(@types/node@24.10.4)(jwt-decode@4.0.0)(postcss@8.5.6)(search-insights@2.17.3)(typescript@5.9.3)
|
||||
vitepress-plugin-group-icons:
|
||||
specifier: ^1.6.1
|
||||
version: 1.6.5(vite@5.4.19(@types/node@24.10.1))
|
||||
version: 1.6.5(vite@5.4.19(@types/node@24.10.4))
|
||||
vitepress-plugin-llms:
|
||||
specifier: ^1.9.1
|
||||
version: 1.9.3
|
||||
vitepress-plugin-tabs:
|
||||
specifier: ^0.7.1
|
||||
version: 0.7.3(vitepress@1.6.4(@algolia/client-search@5.35.0)(@types/node@24.10.1)(jwt-decode@4.0.0)(postcss@8.5.6)(search-insights@2.17.3)(typescript@5.9.3))(vue@3.5.25(typescript@5.9.3))
|
||||
version: 0.7.3(vitepress@1.6.4(@algolia/client-search@5.35.0)(@types/node@24.10.4)(jwt-decode@4.0.0)(postcss@8.5.6)(search-insights@2.17.3)(typescript@5.9.3))(vue@3.5.25(typescript@5.9.3))
|
||||
vue:
|
||||
specifier: ^3.5.18
|
||||
version: 3.5.25(typescript@5.9.3)
|
||||
@@ -1543,8 +1542,8 @@ packages:
|
||||
'@types/ms@2.1.0':
|
||||
resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==}
|
||||
|
||||
'@types/node@24.10.1':
|
||||
resolution: {integrity: sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ==}
|
||||
'@types/node@24.10.4':
|
||||
resolution: {integrity: sha512-vnDVpYPMzs4wunl27jHrfmwojOGKya0xyM3sH+UE5iv5uPS6vX7UIoh6m+vQc5LGBq52HBKPIn/zcSZVzeDEZg==}
|
||||
|
||||
'@types/normalize-package-data@2.4.4':
|
||||
resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==}
|
||||
@@ -5639,12 +5638,12 @@ snapshots:
|
||||
|
||||
'@import-maps/resolve@2.0.0': {}
|
||||
|
||||
'@inquirer/external-editor@1.0.3(@types/node@24.10.1)':
|
||||
'@inquirer/external-editor@1.0.3(@types/node@24.10.4)':
|
||||
dependencies:
|
||||
chardet: 2.1.1
|
||||
iconv-lite: 0.7.0
|
||||
optionalDependencies:
|
||||
'@types/node': 24.10.1
|
||||
'@types/node': 24.10.4
|
||||
|
||||
'@isaacs/balanced-match@4.0.1': {}
|
||||
|
||||
@@ -5727,7 +5726,7 @@ snapshots:
|
||||
yaml: 2.8.2
|
||||
yargs: 17.7.2
|
||||
|
||||
'@netlify/build@35.5.2(@opentelemetry/api@1.8.0)(@types/node@24.10.1)(picomatch@4.0.3)(rollup@4.46.2)':
|
||||
'@netlify/build@35.5.2(@opentelemetry/api@1.8.0)(@types/node@24.10.4)(picomatch@4.0.3)(rollup@4.46.2)':
|
||||
dependencies:
|
||||
'@bugsnag/js': 8.6.0
|
||||
'@netlify/blobs': 10.4.2(supports-color@10.2.2)
|
||||
@@ -5775,7 +5774,7 @@ snapshots:
|
||||
string-width: 7.2.0
|
||||
supports-color: 10.2.2
|
||||
terminal-link: 4.0.0
|
||||
ts-node: 10.9.2(@types/node@24.10.1)(typescript@5.9.3)
|
||||
ts-node: 10.9.2(@types/node@24.10.4)(typescript@5.9.3)
|
||||
typescript: 5.9.3
|
||||
uuid: 11.1.0
|
||||
yaml: 2.8.2
|
||||
@@ -6481,7 +6480,7 @@ snapshots:
|
||||
|
||||
'@types/http-proxy@1.17.17':
|
||||
dependencies:
|
||||
'@types/node': 24.10.1
|
||||
'@types/node': 24.10.4
|
||||
|
||||
'@types/linkify-it@5.0.0': {}
|
||||
|
||||
@@ -6498,7 +6497,7 @@ snapshots:
|
||||
|
||||
'@types/ms@2.1.0': {}
|
||||
|
||||
'@types/node@24.10.1':
|
||||
'@types/node@24.10.4':
|
||||
dependencies:
|
||||
undici-types: 7.16.0
|
||||
|
||||
@@ -6514,7 +6513,7 @@ snapshots:
|
||||
|
||||
'@types/yauzl@2.10.3':
|
||||
dependencies:
|
||||
'@types/node': 24.10.1
|
||||
'@types/node': 24.10.4
|
||||
optional: true
|
||||
|
||||
'@typescript-eslint/project-service@8.48.1(supports-color@10.2.2)(typescript@5.9.3)':
|
||||
@@ -6573,9 +6572,9 @@ snapshots:
|
||||
- rollup
|
||||
- supports-color
|
||||
|
||||
'@vitejs/plugin-vue@5.2.4(vite@5.4.19(@types/node@24.10.1))(vue@3.5.25(typescript@5.9.3))':
|
||||
'@vitejs/plugin-vue@5.2.4(vite@5.4.19(@types/node@24.10.4))(vue@3.5.25(typescript@5.9.3))':
|
||||
dependencies:
|
||||
vite: 5.4.19(@types/node@24.10.1)
|
||||
vite: 5.4.19(@types/node@24.10.4)
|
||||
vue: 3.5.25(typescript@5.9.3)
|
||||
|
||||
'@vue/compiler-core@3.5.25':
|
||||
@@ -8157,18 +8156,18 @@ snapshots:
|
||||
|
||||
ini@4.1.1: {}
|
||||
|
||||
inquirer-autocomplete-prompt@1.4.0(inquirer@8.2.7(@types/node@24.10.1)):
|
||||
inquirer-autocomplete-prompt@1.4.0(inquirer@8.2.7(@types/node@24.10.4)):
|
||||
dependencies:
|
||||
ansi-escapes: 4.3.2
|
||||
chalk: 4.1.2
|
||||
figures: 3.2.0
|
||||
inquirer: 8.2.7(@types/node@24.10.1)
|
||||
inquirer: 8.2.7(@types/node@24.10.4)
|
||||
run-async: 2.4.1
|
||||
rxjs: 6.6.7
|
||||
|
||||
inquirer@8.2.7(@types/node@24.10.1):
|
||||
inquirer@8.2.7(@types/node@24.10.4):
|
||||
dependencies:
|
||||
'@inquirer/external-editor': 1.0.3(@types/node@24.10.1)
|
||||
'@inquirer/external-editor': 1.0.3(@types/node@24.10.4)
|
||||
ansi-escapes: 4.3.2
|
||||
chalk: 4.1.2
|
||||
cli-cursor: 3.1.0
|
||||
@@ -8869,13 +8868,13 @@ snapshots:
|
||||
|
||||
negotiator@0.6.3: {}
|
||||
|
||||
netlify-cli@23.12.3(@types/node@24.10.1)(picomatch@4.0.3)(rollup@4.46.2):
|
||||
netlify-cli@23.12.3(@types/node@24.10.4)(picomatch@4.0.3)(rollup@4.46.2):
|
||||
dependencies:
|
||||
'@fastify/static': 7.0.4
|
||||
'@netlify/ai': 0.3.4(@netlify/api@14.0.11)
|
||||
'@netlify/api': 14.0.11
|
||||
'@netlify/blobs': 10.1.0
|
||||
'@netlify/build': 35.5.2(@opentelemetry/api@1.8.0)(@types/node@24.10.1)(picomatch@4.0.3)(rollup@4.46.2)
|
||||
'@netlify/build': 35.5.2(@opentelemetry/api@1.8.0)(@types/node@24.10.4)(picomatch@4.0.3)(rollup@4.46.2)
|
||||
'@netlify/build-info': 10.0.10
|
||||
'@netlify/config': 24.1.1
|
||||
'@netlify/dev-utils': 4.3.2
|
||||
@@ -8926,8 +8925,8 @@ snapshots:
|
||||
http-proxy: 1.18.1(debug@4.4.3)
|
||||
http-proxy-middleware: 2.0.9(debug@4.4.3)
|
||||
https-proxy-agent: 7.0.6(supports-color@10.2.2)
|
||||
inquirer: 8.2.7(@types/node@24.10.1)
|
||||
inquirer-autocomplete-prompt: 1.4.0(inquirer@8.2.7(@types/node@24.10.1))
|
||||
inquirer: 8.2.7(@types/node@24.10.4)
|
||||
inquirer-autocomplete-prompt: 1.4.0(inquirer@8.2.7(@types/node@24.10.4))
|
||||
ipx: 3.1.1(@netlify/blobs@10.1.0)
|
||||
is-docker: 3.0.0
|
||||
is-stream: 4.0.1
|
||||
@@ -10024,14 +10023,14 @@ snapshots:
|
||||
dependencies:
|
||||
typescript: 5.9.3
|
||||
|
||||
ts-node@10.9.2(@types/node@24.10.1)(typescript@5.9.3):
|
||||
ts-node@10.9.2(@types/node@24.10.4)(typescript@5.9.3):
|
||||
dependencies:
|
||||
'@cspotcode/source-map-support': 0.8.1
|
||||
'@tsconfig/node10': 1.0.12
|
||||
'@tsconfig/node12': 1.0.11
|
||||
'@tsconfig/node14': 1.0.3
|
||||
'@tsconfig/node16': 1.0.4
|
||||
'@types/node': 24.10.1
|
||||
'@types/node': 24.10.4
|
||||
acorn: 8.15.0
|
||||
acorn-walk: 8.3.4
|
||||
arg: 4.1.3
|
||||
@@ -10202,22 +10201,22 @@ snapshots:
|
||||
'@types/unist': 3.0.3
|
||||
vfile-message: 4.0.3
|
||||
|
||||
vite@5.4.19(@types/node@24.10.1):
|
||||
vite@5.4.19(@types/node@24.10.4):
|
||||
dependencies:
|
||||
esbuild: 0.21.5
|
||||
postcss: 8.5.6
|
||||
rollup: 4.46.2
|
||||
optionalDependencies:
|
||||
'@types/node': 24.10.1
|
||||
'@types/node': 24.10.4
|
||||
fsevents: 2.3.3
|
||||
|
||||
vitepress-plugin-group-icons@1.6.5(vite@5.4.19(@types/node@24.10.1)):
|
||||
vitepress-plugin-group-icons@1.6.5(vite@5.4.19(@types/node@24.10.4)):
|
||||
dependencies:
|
||||
'@iconify-json/logos': 1.2.10
|
||||
'@iconify-json/vscode-icons': 1.2.33
|
||||
'@iconify/utils': 3.0.2
|
||||
optionalDependencies:
|
||||
vite: 5.4.19(@types/node@24.10.1)
|
||||
vite: 5.4.19(@types/node@24.10.4)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
@@ -10240,12 +10239,12 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
vitepress-plugin-tabs@0.7.3(vitepress@1.6.4(@algolia/client-search@5.35.0)(@types/node@24.10.1)(jwt-decode@4.0.0)(postcss@8.5.6)(search-insights@2.17.3)(typescript@5.9.3))(vue@3.5.25(typescript@5.9.3)):
|
||||
vitepress-plugin-tabs@0.7.3(vitepress@1.6.4(@algolia/client-search@5.35.0)(@types/node@24.10.4)(jwt-decode@4.0.0)(postcss@8.5.6)(search-insights@2.17.3)(typescript@5.9.3))(vue@3.5.25(typescript@5.9.3)):
|
||||
dependencies:
|
||||
vitepress: 1.6.4(@algolia/client-search@5.35.0)(@types/node@24.10.1)(jwt-decode@4.0.0)(postcss@8.5.6)(search-insights@2.17.3)(typescript@5.9.3)
|
||||
vitepress: 1.6.4(@algolia/client-search@5.35.0)(@types/node@24.10.4)(jwt-decode@4.0.0)(postcss@8.5.6)(search-insights@2.17.3)(typescript@5.9.3)
|
||||
vue: 3.5.25(typescript@5.9.3)
|
||||
|
||||
vitepress@1.6.4(@algolia/client-search@5.35.0)(@types/node@24.10.1)(jwt-decode@4.0.0)(postcss@8.5.6)(search-insights@2.17.3)(typescript@5.9.3):
|
||||
vitepress@1.6.4(@algolia/client-search@5.35.0)(@types/node@24.10.4)(jwt-decode@4.0.0)(postcss@8.5.6)(search-insights@2.17.3)(typescript@5.9.3):
|
||||
dependencies:
|
||||
'@docsearch/css': 3.8.2
|
||||
'@docsearch/js': 3.8.2(@algolia/client-search@5.35.0)(search-insights@2.17.3)
|
||||
@@ -10254,7 +10253,7 @@ snapshots:
|
||||
'@shikijs/transformers': 2.5.0
|
||||
'@shikijs/types': 2.5.0
|
||||
'@types/markdown-it': 14.1.2
|
||||
'@vitejs/plugin-vue': 5.2.4(vite@5.4.19(@types/node@24.10.1))(vue@3.5.25(typescript@5.9.3))
|
||||
'@vitejs/plugin-vue': 5.2.4(vite@5.4.19(@types/node@24.10.4))(vue@3.5.25(typescript@5.9.3))
|
||||
'@vue/devtools-api': 7.7.7
|
||||
'@vue/shared': 3.5.18
|
||||
'@vueuse/core': 12.8.2(typescript@5.9.3)
|
||||
@@ -10263,7 +10262,7 @@ snapshots:
|
||||
mark.js: 8.11.1
|
||||
minisearch: 7.1.2
|
||||
shiki: 2.5.0
|
||||
vite: 5.4.19(@types/node@24.10.1)
|
||||
vite: 5.4.19(@types/node@24.10.4)
|
||||
vue: 3.5.25(typescript@5.9.3)
|
||||
optionalDependencies:
|
||||
postcss: 8.5.6
|
||||
|
||||
@@ -7,6 +7,79 @@ outline: deep
|
||||
|
||||
::: v-pre
|
||||
|
||||
## v3.46.2 - 2025-12-18
|
||||
|
||||
- Fixed a regression on previous release that affected variables passed via
|
||||
command line (#2588, #2589 by @vmaerten).
|
||||
|
||||
## v3.46.1 - 2025-12-18
|
||||
|
||||
### ✨ Features
|
||||
|
||||
- A small behavior change was made to dependencies. Task will now wait for all
|
||||
dependencies to finish running before continuing, even if any of them fail. To
|
||||
opt for the previous behavior, set `failfast: true` either on your
|
||||
`.taskrc.yml` or per task, or use the `--failfast` flag, which will also work
|
||||
for `--parallel` (#1246, #2525 by @andreynering).
|
||||
- The `--summary` flag now displays `vars:` (both global and task-level),
|
||||
`env:`, and `requires:` sections. Dynamic variables show their shell command
|
||||
(e.g., `sh: echo "hello"`) instead of the evaluated value (#2486 ,#2524 by
|
||||
@vmaerten).
|
||||
- Improved performance of fuzzy task name matching by implementing lazy
|
||||
initialization. Added `--disable-fuzzy` flag and `disable-fuzzy` taskrc option
|
||||
to allow disabling fuzzy matching entirely (#2521, #2523 by @vmaerten).
|
||||
- Added LLM-optimized documentation via VitePress plugin, generating `llms.txt`
|
||||
and `llms-full.txt` for AI-powered development tools (#2513 by @vmaerten).
|
||||
- Added `--trusted-hosts` CLI flag and `remote.trusted-hosts` config option to
|
||||
skip confirmation prompts for specified hosts when using Remote Taskfiles
|
||||
(#2491, #2473 by @maciejlech).
|
||||
- When running in GitHub Actions, Task now automatically emits error annotations
|
||||
on failure, improving visibility in workflow summaries (#2568 by @vmaerten).
|
||||
- The `--yes` flag is now accessible in templates via the new `CLI_ASSUME_YES`
|
||||
variable (#2577, #2479 by @semihbkgr).
|
||||
- Improved shell completion scripts (Zsh, Fish, PowerShell) by adding missing
|
||||
flags and dynamic experimental feature detection (#2532 by @vmaerten).
|
||||
- Remote Taskfiles now accept `application/octet-stream` Content-Type (#2536,
|
||||
#1944 by @vmaerten).
|
||||
- Shell completion now works when Task is installed or aliased under a different
|
||||
binary name via TASK_EXE environment variable (#2495, #2468 by @vmaerten).
|
||||
- Some small fixes and improvements were made to `task --init` and to the
|
||||
default Taskfile it generates (#2433 by @andreynering).
|
||||
- Added `--remote-cache-dir` flag and `remote.cache-dir` taskrc option to
|
||||
customize the cache directory for Remote Taskfiles (#2572 by @vmaerten).
|
||||
- Zsh completion now supports zstyle verbose option to show or hide task
|
||||
descriptions (#2571 by @vmaerten).
|
||||
- Task now automatically enables colored output in CI environments (GitHub
|
||||
Actions, GitLab CI, etc.) without requiring FORCE_COLOR=1 (#2569 by
|
||||
@vmaerten).
|
||||
- Added color taskrc option to explicitly enable or disable colored output
|
||||
globally (#2569 by @vmaerten).
|
||||
- Improved Git Remote Taskfiles by switching to go-getter: SSH authentication
|
||||
now works out of the box and `applyOf` is properly supported (#2512 by
|
||||
@vmaerten).
|
||||
|
||||
### 🐛 Fixes
|
||||
|
||||
- Fix RPM upload to Cloudsmith by including the version in the filename to
|
||||
ensure unique filenames (#2507 by @vmaerten).
|
||||
- Fix `run: when_changed` to work properly for Taskfiles included multiple times
|
||||
(#2508, #2511 by @trulede).
|
||||
- Fixed Zsh and Fish completions to stop suggesting task names after `--`
|
||||
separator, allowing proper CLI_ARGS completion (#1843, #1844 by
|
||||
@boiledfroginthewell).
|
||||
- Watch mode (`--watch`) now always runs the task, regardless of `run: once` or
|
||||
`run: when_changed` settings (#2566, #1388 by @trulede).
|
||||
- Fixed global variables (CLI_ARGS, CLI_FORCE, etc.) not being accessible in
|
||||
root-level vars section (#2403, #2397 by @trulede, @vmaerten).
|
||||
- Fixed a bug where `ignore_error` was ignored when using `task:` to call
|
||||
another task (#2552, #363 by @trulede).
|
||||
- Fixed Zsh completion not suggesting global tasks when using `-g`/`--global`
|
||||
flag (#1574, #2574 by @vmaerten).
|
||||
- Fixed Fish completion failing to parse task descriptions containing colons
|
||||
(e.g., URLs or namespaced functions) (#2101, #2573 by @vmaerten).
|
||||
- Fixed false positive "property 'for' is not allowed" warnings in IntelliJ when
|
||||
using `for` loops in Taskfiles (#2576 by @vmaerten).
|
||||
|
||||
## v3.45.5 - 2025-11-11
|
||||
|
||||
- Fixed bug that made a generic message, instead of an useful one, appear when a
|
||||
@@ -22,7 +95,8 @@ outline: deep
|
||||
parts won't be mixed up from different tasks (#1208, #2349, #2350 by
|
||||
@trulede).
|
||||
- Do not re-evaluate variables for `defer:` (#2244, #2418 by @trulede).
|
||||
- Improve error message when a Taskfile is not found (#2441, #2494 by @vmaerten).
|
||||
- Improve error message when a Taskfile is not found (#2441, #2494 by
|
||||
@vmaerten).
|
||||
- Fixed generic error message `exit status 1` when a dependency task failed
|
||||
(#2286 by @GrahamDennis).
|
||||
- Fixed YAML library from the unmaintained `gopkg.in/yaml.v3` to the new fork
|
||||
@@ -30,9 +104,8 @@ outline: deep
|
||||
- On Windows, the built-in version of the `rm` core utils contains a fix related
|
||||
to the `-f` flag (#2426,
|
||||
[u-root/u-root#3464](https://github.com/u-root/u-root/pull/3464),
|
||||
[mvdan/sh#1199](https://github.com/mvdan/sh/pull/1199),
|
||||
#2506 by @andreynering).
|
||||
|
||||
[mvdan/sh#1199](https://github.com/mvdan/sh/pull/1199), #2506 by
|
||||
@andreynering).
|
||||
|
||||
## v3.45.4 - 2025-09-17
|
||||
|
||||
@@ -183,8 +256,8 @@ Reverted the changes made in #2113 and #2186 that affected the
|
||||
- The default taskfile (output when using the `--init` flag) is now an embedded
|
||||
file in the binary instead of being stored in the code (#2112 by @pd93).
|
||||
- Improved the way we report the Task version when using the `--version` flag or
|
||||
`{{.TASK_VERSION}}` variable. This should now be more
|
||||
consistent and easier for package maintainers to use (#2131 by @pd93).
|
||||
`{{.TASK_VERSION}}` variable. This should now be more consistent and easier
|
||||
for package maintainers to use (#2131 by @pd93).
|
||||
- Fixed a bug where globstar (`**`) matching in `sources` only resolved the
|
||||
first result (#2073, #2075 by @pd93).
|
||||
- Fixed a bug where sorting tasks by "none" would use the default sorting
|
||||
@@ -198,7 +271,7 @@ Reverted the changes made in #2113 and #2186 that affected the
|
||||
- Fix Fish completions when `--global` (`-g`) is given (#2134 by @atusy).
|
||||
- Fixed variables not available when using `defer:` (#1909, #2173 by @vmaerten).
|
||||
|
||||
### Package API
|
||||
#### Package API
|
||||
|
||||
- The [`Executor`](https://pkg.go.dev/github.com/go-task/task/v3#Executor) now
|
||||
uses the functional options pattern (#2085, #2147, #2148 by @pd93).
|
||||
@@ -255,7 +328,7 @@ Reverted the changes made in #2113 and #2186 that affected the
|
||||
used, all other variables become unavailable in the templating system within
|
||||
the include (#2092 by @vmaerten).
|
||||
|
||||
### Package API
|
||||
#### Package API
|
||||
|
||||
Unlike our CLI tool,
|
||||
[Task's package API is not currently stable](https://taskfile.dev/reference/package).
|
||||
@@ -645,9 +718,8 @@ stabilize the API in the future. #121 now tracks this piece of work.
|
||||
@FilipSolich).
|
||||
- Fix `defer` on JSON Schema (#1288 by @calvinmclean and @andreynering).
|
||||
- Fix bug in usage of special variables like `{{.USER_WORKING_DIR}}` in
|
||||
combination with `includes`
|
||||
(#1046, #1205, #1250, #1293, #1312, #1274 by @andarto, #1309 by
|
||||
@andreynering).
|
||||
combination with `includes` (#1046, #1205, #1250, #1293, #1312, #1274 by
|
||||
@andarto, #1309 by @andreynering).
|
||||
- Fix bug on `--status` flag. Running this flag should not have side-effects: it
|
||||
should not update the checksum on `.task`, only report its status (#1305,
|
||||
#1307 by @visciang, #1313 by @andreynering).
|
||||
@@ -752,9 +824,9 @@ it a go and let us know what you think via a
|
||||
- Added task location data to the `--json` flag output (#1056 by @pd93)
|
||||
- Change the name of the file generated by `task --init` from `Taskfile.yaml` to
|
||||
`Taskfile.yml` (#1062 by @misitebao).
|
||||
- Added new `splitArgs` template function (`{{splitArgs "foo bar 'foo bar
|
||||
baz'"}}`) to ensure string is split as arguments (#1040, #1059 by
|
||||
@dhanusaputra).
|
||||
- Added new `splitArgs` template function
|
||||
(`{{splitArgs "foo bar 'foo bar baz'"}}`) to ensure string is split as
|
||||
arguments (#1040, #1059 by @dhanusaputra).
|
||||
- Fix the value of `{{.CHECKSUM}}` variable in status (#1076, #1080 by @pd93).
|
||||
- Fixed deep copy implementation (#1072 by @pd93)
|
||||
- Created a tool to assist with releases (#1086 by @pd93).
|
||||
@@ -979,8 +1051,8 @@ it a go and let us know what you think via a
|
||||
|
||||
## v3.9.0 - 2021-10-02
|
||||
|
||||
- A new `shellQuote` function was added to the template system (`{{shellQuote
|
||||
"a string"}}`) to ensure a string is safe for use in shell
|
||||
- A new `shellQuote` function was added to the template system
|
||||
(`{{shellQuote "a string"}}`) to ensure a string is safe for use in shell
|
||||
([mvdan/sh#727](https://github.com/mvdan/sh/pull/727),
|
||||
[mvdan/sh#737](https://github.com/mvdan/sh/pull/737),
|
||||
[Documentation](https://pkg.go.dev/mvdan.cc/sh/v3@v3.4.0/syntax#Quote))
|
||||
@@ -1367,4 +1439,4 @@ document, since it describes in depth what changed for this version.
|
||||
|
||||
- Add LICENSE file
|
||||
|
||||
:::
|
||||
:::
|
||||
@@ -284,10 +284,11 @@ and look for a cached copy instead. This timeout can be configured by setting
|
||||
the `--timeout` flag and specifying a duration. For example, `--timeout 5s` will
|
||||
set the timeout to 5 seconds.
|
||||
|
||||
By default, the cache is stored in the Task temp directory, represented by the
|
||||
`TASK_TEMP_DIR` environment variable. You can override the location of the cache
|
||||
by setting the `TASK_REMOTE_DIR` environment variable. This way, you can share
|
||||
the cache between different projects.
|
||||
By default, the cache is stored in the Task temp directory (`.task`). You can
|
||||
override the location of the cache by using the `--remote-cache-dir` flag, the
|
||||
`remote.cache-dir` option in your [configuration file](#cache-dir), or the
|
||||
`TASK_REMOTE_DIR` environment variable. This way, you can share the cache
|
||||
between different projects.
|
||||
|
||||
You can force Task to ignore the cache and download the latest version by using
|
||||
the `--download` flag.
|
||||
@@ -308,6 +309,7 @@ remote:
|
||||
offline: false
|
||||
timeout: "30s"
|
||||
cache-expiry: "24h"
|
||||
cache-dir: ~/.task
|
||||
trusted-hosts:
|
||||
- github.com
|
||||
- gitlab.com
|
||||
@@ -360,6 +362,20 @@ remote:
|
||||
cache-expiry: "6h"
|
||||
```
|
||||
|
||||
#### `cache-dir`
|
||||
|
||||
- **Type**: `string`
|
||||
- **Default**: `.task`
|
||||
- **Description**: Directory where remote Taskfiles are cached. Can be an
|
||||
absolute path (e.g., `/var/cache/task`) or relative to the Taskfile directory.
|
||||
- **CLI equivalent**: `--remote-cache-dir`
|
||||
- **Environment variable**: `TASK_REMOTE_DIR` (lowest priority)
|
||||
|
||||
```yaml
|
||||
remote:
|
||||
cache-dir: ~/.task
|
||||
```
|
||||
|
||||
#### `trusted-hosts`
|
||||
|
||||
- **Type**: `array of strings`
|
||||
|
||||
@@ -2290,6 +2290,28 @@ The `output` option can also be specified by the `--output` or `-o` flags.
|
||||
|
||||
:::
|
||||
|
||||
## CI Integration
|
||||
|
||||
### Colored output
|
||||
|
||||
Task automatically enables colored output when running in CI environments
|
||||
(`CI=true`). Most CI providers set this variable automatically.
|
||||
|
||||
You can also force colored output with `FORCE_COLOR=1` or disable it with
|
||||
`NO_COLOR=1`.
|
||||
|
||||
### Error annotations
|
||||
|
||||
When running in GitHub Actions (`GITHUB_ACTIONS=true`), Task automatically emits
|
||||
error annotations when a task fails. These annotations appear in the workflow
|
||||
summary, making it easier to spot failures without scrolling through logs.
|
||||
|
||||
```shell
|
||||
::error title=Task 'build' failed::exit status 1
|
||||
```
|
||||
|
||||
This feature requires no configuration and works automatically.
|
||||
|
||||
## Interactive CLI application
|
||||
|
||||
When running interactive CLI applications inside Task they can sometimes behave
|
||||
|
||||
@@ -384,3 +384,13 @@ task --completion fish > ~/.config/fish/completions/task.fish
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
### Zsh customization
|
||||
|
||||
The Zsh completion supports the standard `verbose` zstyle to control whether task
|
||||
descriptions are shown. By default, descriptions are displayed. To show only task
|
||||
names without descriptions, add this to your `~/.zshrc` (after the completion is loaded):
|
||||
|
||||
```shell
|
||||
zstyle ':completion:*:*:task:*' verbose false
|
||||
```
|
||||
|
||||
@@ -91,6 +91,17 @@ experiments:
|
||||
verbose: true
|
||||
```
|
||||
|
||||
### `color`
|
||||
|
||||
- **Type**: `boolean`
|
||||
- **Default**: `true`
|
||||
- **Description**: Enable colored output. Colors are automatically enabled in CI environments (`CI=true`).
|
||||
- **CLI equivalent**: [`-c, --color`](./cli.md#-c---color)
|
||||
|
||||
```yaml
|
||||
color: false
|
||||
```
|
||||
|
||||
### `disable-fuzzy`
|
||||
|
||||
- **Type**: `boolean`
|
||||
@@ -131,6 +142,7 @@ Here's a complete example of a `.taskrc.yml` file with all available options:
|
||||
```yaml
|
||||
# Global settings
|
||||
verbose: true
|
||||
color: true
|
||||
disable-fuzzy: false
|
||||
concurrency: 2
|
||||
|
||||
|
||||
@@ -172,6 +172,11 @@ tasks:
|
||||
- **Type**: `bool`
|
||||
- **Description**: Whether `--offline` flag was set
|
||||
|
||||
#### `CLI_ASSUME_YES`
|
||||
|
||||
- **Type**: `bool`
|
||||
- **Description**: Whether `--yes` flag was set
|
||||
|
||||
### Task
|
||||
|
||||
#### `TASK`
|
||||
|
||||
BIN
website/src/public/favicon.ico
Normal file
BIN
website/src/public/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 170 KiB |
@@ -57,6 +57,10 @@
|
||||
"type": "boolean",
|
||||
"description": "Enable verbose output"
|
||||
},
|
||||
"color": {
|
||||
"type": "boolean",
|
||||
"description": "Enable colored output"
|
||||
},
|
||||
"disable-fuzzy": {
|
||||
"type": "boolean",
|
||||
"description": "Disable fuzzy matching for task names"
|
||||
|
||||
@@ -233,7 +233,10 @@
|
||||
"$ref": "#/definitions/defer_cmd_call"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/for_cmds_call"
|
||||
"$ref": "#/definitions/for_cmd_call"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/for_task_call"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -401,7 +404,7 @@
|
||||
"additionalProperties": false,
|
||||
"required": ["defer"]
|
||||
},
|
||||
"for_cmds_call": {
|
||||
"for_cmd_call": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"for": {
|
||||
@@ -415,6 +418,20 @@
|
||||
"description": "Silent mode disables echoing of command before Task runs it",
|
||||
"type": "boolean"
|
||||
},
|
||||
"platforms": {
|
||||
"description": "Specifies which platforms the command should be run on.",
|
||||
"$ref": "#/definitions/platforms"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": ["for", "cmd"]
|
||||
},
|
||||
"for_task_call": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"for": {
|
||||
"$ref": "#/definitions/for"
|
||||
},
|
||||
"task": {
|
||||
"description": "Task to run",
|
||||
"type": "string"
|
||||
@@ -423,14 +440,17 @@
|
||||
"description": "Values passed to the task called",
|
||||
"$ref": "#/definitions/vars"
|
||||
},
|
||||
"silent": {
|
||||
"description": "Silent mode disables echoing of command before Task runs it",
|
||||
"type": "boolean"
|
||||
},
|
||||
"platforms": {
|
||||
"description": "Specifies which platforms the command should be run on.",
|
||||
"$ref": "#/definitions/platforms"
|
||||
}
|
||||
},
|
||||
"oneOf": [{ "required": ["cmd"] }, { "required": ["task"] }],
|
||||
"additionalProperties": false,
|
||||
"required": ["for"]
|
||||
"required": ["for", "task"]
|
||||
},
|
||||
"for_deps_call": {
|
||||
"type": "object",
|
||||
@@ -451,9 +471,8 @@
|
||||
"$ref": "#/definitions/vars"
|
||||
}
|
||||
},
|
||||
"oneOf": [{ "required": ["cmd"] }, { "required": ["task"] }],
|
||||
"additionalProperties": false,
|
||||
"required": ["for"]
|
||||
"required": ["for", "task"]
|
||||
},
|
||||
"for": {
|
||||
"anyOf": [
|
||||
@@ -475,7 +494,7 @@
|
||||
"description": "A list of values to iterate over",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
"type": ["string", "number"]
|
||||
}
|
||||
},
|
||||
"for_attribute": {
|
||||
|
||||
Reference in New Issue
Block a user