mirror of
https://github.com/go-task/task.git
synced 2025-06-02 23:27:37 +02:00
refactor: unify how executor tests are written (#2042)
* feat: use TaskTest for executor tests * feat: more tests * feat: separate tests for executing and formatting with new functional options that work for both test types * feat: formatter tests * refactor: more tests
This commit is contained in:
parent
180fcef364
commit
4736bc2734
@ -43,6 +43,13 @@ tasks:
|
||||
- "{{.BIN}}/mockery --dir ./internal/fingerprint --name SourcesCheckable"
|
||||
- "{{.BIN}}/mockery --dir ./internal/fingerprint --name StatusCheckable"
|
||||
|
||||
generate:fixtures:
|
||||
desc: Runs tests and generates golden fixture files
|
||||
aliases: [gen:fixtures, g:fixtures]
|
||||
cmds:
|
||||
- find ./testdata -name '*.golden' -delete
|
||||
- go test -update ./...
|
||||
|
||||
install:mockery:
|
||||
desc: Installs mockgen; a tool to generate mock files
|
||||
vars:
|
||||
|
@ -217,6 +217,14 @@ func ExecutorWithAssumeYes(assumeYes bool) ExecutorOption {
|
||||
}
|
||||
|
||||
// WithAssumeTerm is used for testing purposes to simulate a terminal.
|
||||
func ExecutorWithAssumeTerm(assumeTerm bool) ExecutorOption {
|
||||
return func(e *Executor) {
|
||||
e.AssumeTerm = assumeTerm
|
||||
}
|
||||
}
|
||||
|
||||
// ExecutorWithDry tells the [Executor] to output the commands that would be run
|
||||
// without actually running them.
|
||||
func ExecutorWithDry(dry bool) ExecutorOption {
|
||||
return func(e *Executor) {
|
||||
e.Dry = dry
|
||||
|
946
executor_test.go
Normal file
946
executor_test.go
Normal file
@ -0,0 +1,946 @@
|
||||
package task_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"cmp"
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/sebdah/goldie/v2"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/go-task/task/v3"
|
||||
"github.com/go-task/task/v3/internal/experiments"
|
||||
"github.com/go-task/task/v3/internal/filepathext"
|
||||
"github.com/go-task/task/v3/taskfile/ast"
|
||||
)
|
||||
|
||||
type (
|
||||
// A ExecutorTestOption is a function that configures an [ExecutorTest].
|
||||
ExecutorTestOption interface {
|
||||
applyToExecutorTest(*ExecutorTest)
|
||||
}
|
||||
// A ExecutorTest is a test wrapper around a [task.Executor] to make it easy
|
||||
// to write tests for tasks. See [NewExecutorTest] for information on
|
||||
// creating and running ExecutorTests. These tests use fixture files to
|
||||
// assert whether the result of a task is correct. If Task's behavior has
|
||||
// been changed, the fixture files can be updated by running `task
|
||||
// gen:fixtures`.
|
||||
ExecutorTest struct {
|
||||
TaskTest
|
||||
task string
|
||||
vars map[string]any
|
||||
input string
|
||||
executorOpts []task.ExecutorOption
|
||||
wantSetupError bool
|
||||
wantRunError bool
|
||||
wantStatusError bool
|
||||
}
|
||||
)
|
||||
|
||||
// NewExecutorTest sets up a new [task.Executor] with the given options and runs
|
||||
// a task with the given [ExecutorTestOption]s. The output of the task is
|
||||
// written to a set of fixture files depending on the configuration of the test.
|
||||
func NewExecutorTest(t *testing.T, opts ...ExecutorTestOption) {
|
||||
t.Helper()
|
||||
tt := &ExecutorTest{
|
||||
task: "default",
|
||||
vars: map[string]any{},
|
||||
TaskTest: TaskTest{
|
||||
experiments: map[*experiments.Experiment]int{},
|
||||
},
|
||||
}
|
||||
// Apply the functional options
|
||||
for _, opt := range opts {
|
||||
opt.applyToExecutorTest(tt)
|
||||
}
|
||||
// Enable any experiments that have been set
|
||||
for x, v := range tt.experiments {
|
||||
prev := *x
|
||||
*x = experiments.Experiment{
|
||||
Name: prev.Name,
|
||||
AllowedValues: []int{v},
|
||||
Value: v,
|
||||
}
|
||||
t.Cleanup(func() {
|
||||
*x = prev
|
||||
})
|
||||
}
|
||||
tt.run(t)
|
||||
}
|
||||
|
||||
// Functional options
|
||||
|
||||
// WithInput tells the test to create a reader with the given input. This can be
|
||||
// used to simulate user input when a task requires it.
|
||||
func WithInput(input string) ExecutorTestOption {
|
||||
return &inputTestOption{input}
|
||||
}
|
||||
|
||||
type inputTestOption struct {
|
||||
input string
|
||||
}
|
||||
|
||||
func (opt *inputTestOption) applyToExecutorTest(t *ExecutorTest) {
|
||||
t.input = opt.input
|
||||
}
|
||||
|
||||
// WithRunError tells the test to expect an error during the run phase of the
|
||||
// task execution. A fixture will be created with the output of any errors.
|
||||
func WithRunError() ExecutorTestOption {
|
||||
return &runErrorTestOption{}
|
||||
}
|
||||
|
||||
type runErrorTestOption struct{}
|
||||
|
||||
func (opt *runErrorTestOption) applyToExecutorTest(t *ExecutorTest) {
|
||||
t.wantRunError = true
|
||||
}
|
||||
|
||||
// WithStatusError tells the test to make an additional call to
|
||||
// [task.Executor.Status] after the task has been run. A fixture will be created
|
||||
// with the output of any errors.
|
||||
func WithStatusError() ExecutorTestOption {
|
||||
return &statusErrorTestOption{}
|
||||
}
|
||||
|
||||
type statusErrorTestOption struct{}
|
||||
|
||||
func (opt *statusErrorTestOption) applyToExecutorTest(t *ExecutorTest) {
|
||||
t.wantStatusError = true
|
||||
}
|
||||
|
||||
// Helpers
|
||||
|
||||
// writeFixtureErrRun is a wrapper for writing the output of an error during the
|
||||
// run phase of the task to a fixture file.
|
||||
func (tt *ExecutorTest) writeFixtureErrRun(
|
||||
t *testing.T,
|
||||
g *goldie.Goldie,
|
||||
err error,
|
||||
) {
|
||||
t.Helper()
|
||||
tt.writeFixture(t, g, "err-run", []byte(err.Error()))
|
||||
}
|
||||
|
||||
// writeFixtureStatus is a wrapper for writing the output of an error when
|
||||
// making an additional call to [task.Executor.Status] to a fixture file.
|
||||
func (tt *ExecutorTest) writeFixtureStatus(
|
||||
t *testing.T,
|
||||
g *goldie.Goldie,
|
||||
status string,
|
||||
) {
|
||||
t.Helper()
|
||||
tt.writeFixture(t, g, "err-status", []byte(status))
|
||||
}
|
||||
|
||||
// run is the main function for running the test. It sets up the task executor,
|
||||
// runs the task, and writes the output to a fixture file.
|
||||
func (tt *ExecutorTest) run(t *testing.T) {
|
||||
t.Helper()
|
||||
f := func(t *testing.T) {
|
||||
t.Helper()
|
||||
var buf bytes.Buffer
|
||||
|
||||
opts := append(
|
||||
tt.executorOpts,
|
||||
task.ExecutorWithStdout(&buf),
|
||||
task.ExecutorWithStderr(&buf),
|
||||
)
|
||||
|
||||
// If the test has input, create a reader for it and add it to the
|
||||
// executor options
|
||||
if tt.input != "" {
|
||||
var reader bytes.Buffer
|
||||
reader.WriteString(tt.input)
|
||||
opts = append(opts, task.ExecutorWithStdin(&reader))
|
||||
}
|
||||
|
||||
// Set up the task executor
|
||||
e := task.NewExecutor(opts...)
|
||||
|
||||
// Create a golden fixture file for the output
|
||||
g := goldie.New(t,
|
||||
goldie.WithFixtureDir(filepath.Join(e.Dir, "testdata")),
|
||||
)
|
||||
|
||||
// Call setup and check for errors
|
||||
if err := e.Setup(); tt.wantSetupError {
|
||||
require.Error(t, err)
|
||||
tt.writeFixtureErrSetup(t, g, err)
|
||||
tt.writeFixtureBuffer(t, g, buf)
|
||||
return
|
||||
} else {
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
// Create the task call
|
||||
vars := ast.NewVars()
|
||||
for key, value := range tt.vars {
|
||||
vars.Set(key, ast.Var{Value: value})
|
||||
}
|
||||
call := &task.Call{
|
||||
Task: tt.task,
|
||||
Vars: vars,
|
||||
}
|
||||
|
||||
// Run the task and check for errors
|
||||
ctx := context.Background()
|
||||
if err := e.Run(ctx, call); tt.wantRunError {
|
||||
require.Error(t, err)
|
||||
tt.writeFixtureErrRun(t, g, err)
|
||||
tt.writeFixtureBuffer(t, g, buf)
|
||||
return
|
||||
} else {
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
// If the status flag is set, run the status check
|
||||
if tt.wantStatusError {
|
||||
if err := e.Status(ctx, call); err != nil {
|
||||
tt.writeFixtureStatus(t, g, err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
tt.writeFixtureBuffer(t, g, buf)
|
||||
}
|
||||
|
||||
// Run the test (with a name if it has one)
|
||||
if tt.name != "" {
|
||||
t.Run(tt.name, f)
|
||||
} else {
|
||||
f(t)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEmptyTask(t *testing.T) {
|
||||
t.Parallel()
|
||||
NewExecutorTest(t,
|
||||
WithExecutorOptions(
|
||||
task.ExecutorWithDir("testdata/empty_task"),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
func TestEmptyTaskfile(t *testing.T) {
|
||||
t.Parallel()
|
||||
NewExecutorTest(t,
|
||||
WithExecutorOptions(
|
||||
task.ExecutorWithDir("testdata/empty_taskfile"),
|
||||
),
|
||||
WithSetupError(),
|
||||
WithPostProcessFn(PPRemoveAbsolutePaths),
|
||||
)
|
||||
}
|
||||
|
||||
func TestEnv(t *testing.T) {
|
||||
t.Setenv("QUX", "from_os")
|
||||
NewExecutorTest(t,
|
||||
WithName("env precedence disabled"),
|
||||
WithExecutorOptions(
|
||||
task.ExecutorWithDir("testdata/env"),
|
||||
task.ExecutorWithSilent(true),
|
||||
),
|
||||
)
|
||||
NewExecutorTest(t,
|
||||
WithName("env precedence enabled"),
|
||||
WithExecutorOptions(
|
||||
task.ExecutorWithDir("testdata/env"),
|
||||
task.ExecutorWithSilent(true),
|
||||
),
|
||||
WithExperiment(&experiments.EnvPrecedence, 1),
|
||||
)
|
||||
}
|
||||
|
||||
func TestVars(t *testing.T) {
|
||||
t.Parallel()
|
||||
NewExecutorTest(t,
|
||||
WithExecutorOptions(
|
||||
task.ExecutorWithDir("testdata/vars"),
|
||||
task.ExecutorWithSilent(true),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
func TestRequires(t *testing.T) {
|
||||
t.Parallel()
|
||||
NewExecutorTest(t,
|
||||
WithName("required var missing"),
|
||||
WithExecutorOptions(
|
||||
task.ExecutorWithDir("testdata/requires"),
|
||||
),
|
||||
WithTask("missing-var"),
|
||||
WithRunError(),
|
||||
)
|
||||
NewExecutorTest(t,
|
||||
WithName("required var ok"),
|
||||
WithExecutorOptions(
|
||||
task.ExecutorWithDir("testdata/requires"),
|
||||
),
|
||||
WithTask("missing-var"),
|
||||
WithVar("FOO", "bar"),
|
||||
)
|
||||
NewExecutorTest(t,
|
||||
WithName("fails validation"),
|
||||
WithExecutorOptions(
|
||||
task.ExecutorWithDir("testdata/requires"),
|
||||
),
|
||||
WithTask("validation-var"),
|
||||
WithVar("ENV", "dev"),
|
||||
WithVar("FOO", "bar"),
|
||||
WithRunError(),
|
||||
)
|
||||
NewExecutorTest(t,
|
||||
WithName("passes validation"),
|
||||
WithExecutorOptions(
|
||||
task.ExecutorWithDir("testdata/requires"),
|
||||
),
|
||||
WithTask("validation-var"),
|
||||
WithVar("FOO", "one"),
|
||||
WithVar("ENV", "dev"),
|
||||
)
|
||||
NewExecutorTest(t,
|
||||
WithName("required var missing + fails validation"),
|
||||
WithExecutorOptions(
|
||||
task.ExecutorWithDir("testdata/requires"),
|
||||
),
|
||||
WithTask("validation-var"),
|
||||
WithRunError(),
|
||||
)
|
||||
NewExecutorTest(t,
|
||||
WithName("required var missing + fails validation"),
|
||||
WithExecutorOptions(
|
||||
task.ExecutorWithDir("testdata/requires"),
|
||||
),
|
||||
WithTask("validation-var-dynamic"),
|
||||
WithVar("FOO", "one"),
|
||||
WithVar("ENV", "dev"),
|
||||
)
|
||||
NewExecutorTest(t,
|
||||
WithName("require before compile"),
|
||||
WithExecutorOptions(
|
||||
task.ExecutorWithDir("testdata/requires"),
|
||||
),
|
||||
WithTask("require-before-compile"),
|
||||
WithRunError(),
|
||||
)
|
||||
NewExecutorTest(t,
|
||||
WithName("var defined in task"),
|
||||
WithExecutorOptions(
|
||||
task.ExecutorWithDir("testdata/requires"),
|
||||
),
|
||||
WithTask("var-defined-in-task"),
|
||||
)
|
||||
}
|
||||
|
||||
// TODO: mock fs
|
||||
func TestSpecialVars(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
const dir = "testdata/special_vars"
|
||||
const subdir = "testdata/special_vars/subdir"
|
||||
toAbs := func(rel string) string {
|
||||
abs, err := filepath.Abs(rel)
|
||||
assert.NoError(t, err)
|
||||
return abs
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
target string
|
||||
expected string
|
||||
}{
|
||||
// Root
|
||||
{target: "print-task", expected: "print-task"},
|
||||
{target: "print-root-dir", expected: toAbs(dir)},
|
||||
{target: "print-taskfile", expected: toAbs(dir) + "/Taskfile.yml"},
|
||||
{target: "print-taskfile-dir", expected: toAbs(dir)},
|
||||
{target: "print-task-version", expected: "unknown"},
|
||||
{target: "print-task-dir", expected: toAbs(dir) + "/foo"},
|
||||
// Included
|
||||
{target: "included:print-task", expected: "included:print-task"},
|
||||
{target: "included:print-root-dir", expected: toAbs(dir)},
|
||||
{target: "included:print-taskfile", expected: toAbs(dir) + "/included/Taskfile.yml"},
|
||||
{target: "included:print-taskfile-dir", expected: toAbs(dir) + "/included"},
|
||||
{target: "included:print-task-version", expected: "unknown"},
|
||||
}
|
||||
|
||||
for _, dir := range []string{dir, subdir} {
|
||||
for _, test := range tests {
|
||||
NewExecutorTest(t,
|
||||
WithName(fmt.Sprintf("%s-%s", dir, test.target)),
|
||||
WithExecutorOptions(
|
||||
task.ExecutorWithDir(dir),
|
||||
task.ExecutorWithSilent(true),
|
||||
task.ExecutorWithVersionCheck(true),
|
||||
),
|
||||
WithTask(test.target),
|
||||
WithPostProcessFn(PPRemoveAbsolutePaths),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestConcurrency(t *testing.T) {
|
||||
t.Parallel()
|
||||
NewExecutorTest(t,
|
||||
WithExecutorOptions(
|
||||
task.ExecutorWithDir("testdata/concurrency"),
|
||||
task.ExecutorWithConcurrency(1),
|
||||
),
|
||||
WithPostProcessFn(PPSortedLines),
|
||||
)
|
||||
}
|
||||
|
||||
func TestParams(t *testing.T) {
|
||||
t.Parallel()
|
||||
NewExecutorTest(t,
|
||||
WithExecutorOptions(
|
||||
task.ExecutorWithDir("testdata/params"),
|
||||
task.ExecutorWithSilent(true),
|
||||
),
|
||||
WithPostProcessFn(PPSortedLines),
|
||||
)
|
||||
}
|
||||
|
||||
func TestDeps(t *testing.T) {
|
||||
t.Parallel()
|
||||
NewExecutorTest(t,
|
||||
WithExecutorOptions(
|
||||
task.ExecutorWithDir("testdata/deps"),
|
||||
task.ExecutorWithSilent(true),
|
||||
),
|
||||
WithPostProcessFn(PPSortedLines),
|
||||
)
|
||||
}
|
||||
|
||||
// TODO: mock fs
|
||||
func TestStatus(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
const dir = "testdata/status"
|
||||
|
||||
files := []string{
|
||||
"foo.txt",
|
||||
"bar.txt",
|
||||
"baz.txt",
|
||||
}
|
||||
|
||||
for _, f := range files {
|
||||
path := filepathext.SmartJoin(dir, f)
|
||||
_ = os.Remove(path)
|
||||
if _, err := os.Stat(path); err == nil {
|
||||
t.Errorf("File should not exist: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// gen-foo creates foo.txt, and will always fail it's status check.
|
||||
NewExecutorTest(t,
|
||||
WithName("run gen-foo 1 silent"),
|
||||
WithExecutorOptions(
|
||||
task.ExecutorWithDir(dir),
|
||||
task.ExecutorWithSilent(true),
|
||||
),
|
||||
WithTask("gen-foo"),
|
||||
)
|
||||
// gen-foo creates bar.txt, and will pass its status-check the 3. time it
|
||||
// is run. It creates bar.txt, but also lists it as its source. So, the checksum
|
||||
// for the file won't match before after the second run as we the file
|
||||
// only exists after the first run.
|
||||
NewExecutorTest(t,
|
||||
WithName("run gen-bar 1 silent"),
|
||||
WithExecutorOptions(
|
||||
task.ExecutorWithDir(dir),
|
||||
task.ExecutorWithSilent(true),
|
||||
),
|
||||
WithTask("gen-bar"),
|
||||
)
|
||||
// gen-silent-baz is marked as being silent, and should only produce output
|
||||
// if e.Verbose is set to true.
|
||||
NewExecutorTest(t,
|
||||
WithName("run gen-baz silent"),
|
||||
WithExecutorOptions(
|
||||
task.ExecutorWithDir(dir),
|
||||
task.ExecutorWithSilent(true),
|
||||
),
|
||||
WithTask("gen-silent-baz"),
|
||||
)
|
||||
|
||||
for _, f := range files {
|
||||
if _, err := os.Stat(filepathext.SmartJoin(dir, f)); err != nil {
|
||||
t.Errorf("File should exist: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Run gen-bar a second time to produce a checksum file that matches bar.txt
|
||||
NewExecutorTest(t,
|
||||
WithName("run gen-bar 2 silent"),
|
||||
WithExecutorOptions(
|
||||
task.ExecutorWithDir(dir),
|
||||
task.ExecutorWithSilent(true),
|
||||
),
|
||||
WithTask("gen-bar"),
|
||||
)
|
||||
// Run gen-bar a third time, to make sure we've triggered the status check.
|
||||
NewExecutorTest(t,
|
||||
WithName("run gen-bar 3 silent"),
|
||||
WithExecutorOptions(
|
||||
task.ExecutorWithDir(dir),
|
||||
task.ExecutorWithSilent(true),
|
||||
),
|
||||
WithTask("gen-bar"),
|
||||
)
|
||||
|
||||
// Now, let's remove source file, and run the task again to to prepare
|
||||
// for the next test.
|
||||
err := os.Remove(filepathext.SmartJoin(dir, "bar.txt"))
|
||||
require.NoError(t, err)
|
||||
NewExecutorTest(t,
|
||||
WithName("run gen-bar 4 silent"),
|
||||
WithExecutorOptions(
|
||||
task.ExecutorWithDir(dir),
|
||||
task.ExecutorWithSilent(true),
|
||||
),
|
||||
WithTask("gen-bar"),
|
||||
)
|
||||
// all: not up-to-date
|
||||
NewExecutorTest(t,
|
||||
WithName("run gen-foo 2"),
|
||||
WithExecutorOptions(
|
||||
task.ExecutorWithDir(dir),
|
||||
),
|
||||
WithTask("gen-foo"),
|
||||
)
|
||||
// status: not up-to-date
|
||||
NewExecutorTest(t,
|
||||
WithName("run gen-foo 3"),
|
||||
WithExecutorOptions(
|
||||
task.ExecutorWithDir(dir),
|
||||
),
|
||||
WithTask("gen-foo"),
|
||||
)
|
||||
// sources: not up-to-date
|
||||
NewExecutorTest(t,
|
||||
WithName("run gen-bar 5"),
|
||||
WithExecutorOptions(
|
||||
task.ExecutorWithDir(dir),
|
||||
),
|
||||
WithTask("gen-bar"),
|
||||
)
|
||||
// all: up-to-date
|
||||
NewExecutorTest(t,
|
||||
WithName("run gen-bar 6"),
|
||||
WithExecutorOptions(
|
||||
task.ExecutorWithDir(dir),
|
||||
),
|
||||
WithTask("gen-bar"),
|
||||
)
|
||||
// sources: not up-to-date, no output produced.
|
||||
NewExecutorTest(t,
|
||||
WithName("run gen-baz 2"),
|
||||
WithExecutorOptions(
|
||||
task.ExecutorWithDir(dir),
|
||||
),
|
||||
WithTask("gen-silent-baz"),
|
||||
)
|
||||
// up-to-date, no output produced
|
||||
NewExecutorTest(t,
|
||||
WithName("run gen-baz 3"),
|
||||
WithExecutorOptions(
|
||||
task.ExecutorWithDir(dir),
|
||||
),
|
||||
WithTask("gen-silent-baz"),
|
||||
)
|
||||
// up-to-date, output produced due to Verbose mode.
|
||||
NewExecutorTest(t,
|
||||
WithName("run gen-baz 4 verbose"),
|
||||
WithExecutorOptions(
|
||||
task.ExecutorWithDir(dir),
|
||||
task.ExecutorWithVerbose(true),
|
||||
),
|
||||
WithTask("gen-silent-baz"),
|
||||
WithPostProcessFn(PPRemoveAbsolutePaths),
|
||||
)
|
||||
}
|
||||
|
||||
func TestPrecondition(t *testing.T) {
|
||||
t.Parallel()
|
||||
const dir = "testdata/precondition"
|
||||
NewExecutorTest(t,
|
||||
WithName("a precondition has been met"),
|
||||
WithExecutorOptions(
|
||||
task.ExecutorWithDir(dir),
|
||||
),
|
||||
WithTask("foo"),
|
||||
)
|
||||
NewExecutorTest(t,
|
||||
WithName("a precondition was not met"),
|
||||
WithExecutorOptions(
|
||||
task.ExecutorWithDir(dir),
|
||||
),
|
||||
WithTask("impossible"),
|
||||
WithRunError(),
|
||||
)
|
||||
NewExecutorTest(t,
|
||||
WithName("precondition in dependency fails the task"),
|
||||
WithExecutorOptions(
|
||||
task.ExecutorWithDir(dir),
|
||||
),
|
||||
WithTask("depends_on_impossible"),
|
||||
WithRunError(),
|
||||
)
|
||||
NewExecutorTest(t,
|
||||
WithName("precondition in cmd fails the task"),
|
||||
WithExecutorOptions(
|
||||
task.ExecutorWithDir(dir),
|
||||
),
|
||||
WithTask("executes_failing_task_as_cmd"),
|
||||
WithRunError(),
|
||||
)
|
||||
}
|
||||
|
||||
func TestAlias(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
NewExecutorTest(t,
|
||||
WithName("alias"),
|
||||
WithExecutorOptions(
|
||||
task.ExecutorWithDir("testdata/alias"),
|
||||
),
|
||||
WithTask("f"),
|
||||
)
|
||||
|
||||
NewExecutorTest(t,
|
||||
WithName("duplicate alias"),
|
||||
WithExecutorOptions(
|
||||
task.ExecutorWithDir("testdata/alias"),
|
||||
),
|
||||
WithTask("x"),
|
||||
WithRunError(),
|
||||
)
|
||||
|
||||
NewExecutorTest(t,
|
||||
WithName("alias summary"),
|
||||
WithExecutorOptions(
|
||||
task.ExecutorWithDir("testdata/alias"),
|
||||
task.ExecutorWithSummary(true),
|
||||
),
|
||||
WithTask("f"),
|
||||
)
|
||||
}
|
||||
|
||||
func TestLabel(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
NewExecutorTest(t,
|
||||
WithName("up to date"),
|
||||
WithExecutorOptions(
|
||||
task.ExecutorWithDir("testdata/label_uptodate"),
|
||||
),
|
||||
WithTask("foo"),
|
||||
)
|
||||
|
||||
NewExecutorTest(t,
|
||||
WithName("summary"),
|
||||
WithExecutorOptions(
|
||||
task.ExecutorWithDir("testdata/label_summary"),
|
||||
task.ExecutorWithSummary(true),
|
||||
),
|
||||
WithTask("foo"),
|
||||
)
|
||||
|
||||
NewExecutorTest(t,
|
||||
WithName("status"),
|
||||
WithExecutorOptions(
|
||||
task.ExecutorWithDir("testdata/label_status"),
|
||||
),
|
||||
WithTask("foo"),
|
||||
WithStatusError(),
|
||||
)
|
||||
|
||||
NewExecutorTest(t,
|
||||
WithName("var"),
|
||||
WithExecutorOptions(
|
||||
task.ExecutorWithDir("testdata/label_var"),
|
||||
),
|
||||
WithTask("foo"),
|
||||
)
|
||||
|
||||
NewExecutorTest(t,
|
||||
WithName("label in summary"),
|
||||
WithExecutorOptions(
|
||||
task.ExecutorWithDir("testdata/label_summary"),
|
||||
),
|
||||
WithTask("foo"),
|
||||
)
|
||||
}
|
||||
|
||||
func TestPromptInSummary(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
input string
|
||||
wantError bool
|
||||
}{
|
||||
{"test short approval", "y\n", false},
|
||||
{"test long approval", "yes\n", false},
|
||||
{"test uppercase approval", "Y\n", false},
|
||||
{"test stops task", "n\n", true},
|
||||
{"test junk value stops task", "foobar\n", true},
|
||||
{"test Enter stops task", "\n", true},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
opts := []ExecutorTestOption{
|
||||
WithName(test.name),
|
||||
WithExecutorOptions(
|
||||
task.ExecutorWithDir("testdata/prompt"),
|
||||
task.ExecutorWithAssumeTerm(true),
|
||||
),
|
||||
WithTask("foo"),
|
||||
WithInput(test.input),
|
||||
}
|
||||
if test.wantError {
|
||||
opts = append(opts, WithRunError())
|
||||
}
|
||||
NewExecutorTest(t, opts...)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestPromptWithIndirectTask(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
NewExecutorTest(t,
|
||||
WithExecutorOptions(
|
||||
task.ExecutorWithDir("testdata/prompt"),
|
||||
task.ExecutorWithAssumeTerm(true),
|
||||
),
|
||||
WithTask("bar"),
|
||||
WithInput("y\n"),
|
||||
)
|
||||
}
|
||||
|
||||
func TestPromptAssumeYes(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
NewExecutorTest(t,
|
||||
WithName("--yes flag should skip prompt"),
|
||||
WithExecutorOptions(
|
||||
task.ExecutorWithDir("testdata/prompt"),
|
||||
task.ExecutorWithAssumeTerm(true),
|
||||
task.ExecutorWithAssumeYes(true),
|
||||
),
|
||||
WithTask("foo"),
|
||||
WithInput("\n"),
|
||||
)
|
||||
|
||||
NewExecutorTest(t,
|
||||
WithName("task should raise errors.TaskCancelledError"),
|
||||
WithExecutorOptions(
|
||||
task.ExecutorWithDir("testdata/prompt"),
|
||||
task.ExecutorWithAssumeTerm(true),
|
||||
),
|
||||
WithTask("foo"),
|
||||
WithInput("\n"),
|
||||
WithRunError(),
|
||||
)
|
||||
}
|
||||
|
||||
func TestForCmds(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
wantErr bool
|
||||
}{
|
||||
{name: "loop-explicit"},
|
||||
{name: "loop-matrix"},
|
||||
{name: "loop-matrix-ref"},
|
||||
{
|
||||
name: "loop-matrix-ref-error",
|
||||
wantErr: true,
|
||||
},
|
||||
{name: "loop-sources"},
|
||||
{name: "loop-sources-glob"},
|
||||
{name: "loop-vars"},
|
||||
{name: "loop-vars-sh"},
|
||||
{name: "loop-task"},
|
||||
{name: "loop-task-as"},
|
||||
{name: "loop-different-tasks"},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
opts := []ExecutorTestOption{
|
||||
WithName(test.name),
|
||||
WithExecutorOptions(
|
||||
task.ExecutorWithDir("testdata/for/cmds"),
|
||||
task.ExecutorWithSilent(true),
|
||||
task.ExecutorWithForce(true),
|
||||
),
|
||||
WithTask(test.name),
|
||||
WithPostProcessFn(PPRemoveAbsolutePaths),
|
||||
}
|
||||
if test.wantErr {
|
||||
opts = append(opts, WithRunError())
|
||||
}
|
||||
NewExecutorTest(t, opts...)
|
||||
}
|
||||
}
|
||||
|
||||
func TestForDeps(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
wantErr bool
|
||||
}{
|
||||
{name: "loop-explicit"},
|
||||
{name: "loop-matrix"},
|
||||
{name: "loop-matrix-ref"},
|
||||
{
|
||||
name: "loop-matrix-ref-error",
|
||||
wantErr: true,
|
||||
},
|
||||
{name: "loop-sources"},
|
||||
{name: "loop-sources-glob"},
|
||||
{name: "loop-vars"},
|
||||
{name: "loop-vars-sh"},
|
||||
{name: "loop-task"},
|
||||
{name: "loop-task-as"},
|
||||
{name: "loop-different-tasks"},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
opts := []ExecutorTestOption{
|
||||
WithName(test.name),
|
||||
WithExecutorOptions(
|
||||
task.ExecutorWithDir("testdata/for/deps"),
|
||||
task.ExecutorWithSilent(true),
|
||||
task.ExecutorWithForce(true),
|
||||
// Force output of each dep to be grouped together to prevent interleaving
|
||||
task.ExecutorWithOutputStyle(ast.Output{Name: "group"}),
|
||||
),
|
||||
WithTask(test.name),
|
||||
WithPostProcessFn(PPRemoveAbsolutePaths),
|
||||
WithPostProcessFn(PPSortedLines),
|
||||
}
|
||||
if test.wantErr {
|
||||
opts = append(opts, WithRunError())
|
||||
}
|
||||
NewExecutorTest(t, opts...)
|
||||
}
|
||||
}
|
||||
|
||||
func TestReference(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
call string
|
||||
}{
|
||||
{
|
||||
name: "reference in command",
|
||||
call: "ref-cmd",
|
||||
},
|
||||
{
|
||||
name: "reference in dependency",
|
||||
call: "ref-dep",
|
||||
},
|
||||
{
|
||||
name: "reference using templating resolver",
|
||||
call: "ref-resolver",
|
||||
},
|
||||
{
|
||||
name: "reference using templating resolver and dynamic var",
|
||||
call: "ref-resolver-sh",
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
NewExecutorTest(t,
|
||||
WithName(test.name),
|
||||
WithExecutorOptions(
|
||||
task.ExecutorWithDir("testdata/var_references"),
|
||||
task.ExecutorWithSilent(true),
|
||||
task.ExecutorWithForce(true),
|
||||
),
|
||||
WithTask(cmp.Or(test.call, "default")),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVarInheritance(t *testing.T) {
|
||||
enableExperimentForTest(t, &experiments.EnvPrecedence, 1)
|
||||
tests := []struct {
|
||||
name string
|
||||
call string
|
||||
}{
|
||||
{name: "shell"},
|
||||
{name: "entrypoint-global-dotenv"},
|
||||
{name: "entrypoint-global-vars"},
|
||||
// We can't send env vars to a called task, so the env var is not overridden
|
||||
{name: "entrypoint-task-call-vars"},
|
||||
// Dotenv doesn't set variables
|
||||
{name: "entrypoint-task-call-dotenv"},
|
||||
{name: "entrypoint-task-call-task-vars"},
|
||||
// Dotenv doesn't set variables
|
||||
{name: "entrypoint-task-dotenv"},
|
||||
{name: "entrypoint-task-vars"},
|
||||
// {
|
||||
// // Dotenv not currently allowed in included taskfiles
|
||||
// name: "included-global-dotenv",
|
||||
// want: "included-global-dotenv\nincluded-global-dotenv\n",
|
||||
// },
|
||||
{
|
||||
name: "included-global-vars",
|
||||
call: "included",
|
||||
},
|
||||
{
|
||||
// We can't send env vars to a called task, so the env var is not overridden
|
||||
name: "included-task-call-vars",
|
||||
call: "included",
|
||||
},
|
||||
{
|
||||
// Dotenv doesn't set variables
|
||||
// Dotenv not currently allowed in included taskfiles (but doesn't error in a task)
|
||||
name: "included-task-call-dotenv",
|
||||
call: "included",
|
||||
},
|
||||
{
|
||||
name: "included-task-call-task-vars",
|
||||
call: "included",
|
||||
},
|
||||
{
|
||||
// Dotenv doesn't set variables
|
||||
// Somehow dotenv is working here!
|
||||
name: "included-task-dotenv",
|
||||
call: "included",
|
||||
},
|
||||
{
|
||||
name: "included-task-vars",
|
||||
call: "included",
|
||||
},
|
||||
}
|
||||
|
||||
t.Setenv("VAR", "shell")
|
||||
t.Setenv("ENV", "shell")
|
||||
for _, test := range tests {
|
||||
NewExecutorTest(t,
|
||||
WithName(test.name),
|
||||
WithExecutorOptions(
|
||||
task.ExecutorWithDir(fmt.Sprintf("testdata/var_inheritance/v3/%s", test.name)),
|
||||
task.ExecutorWithSilent(true),
|
||||
task.ExecutorWithForce(true),
|
||||
),
|
||||
WithTask(cmp.Or(test.call, "default")),
|
||||
)
|
||||
}
|
||||
}
|
220
formatter_test.go
Normal file
220
formatter_test.go
Normal file
@ -0,0 +1,220 @@
|
||||
package task_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/sebdah/goldie/v2"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/go-task/task/v3"
|
||||
"github.com/go-task/task/v3/internal/experiments"
|
||||
"github.com/go-task/task/v3/taskfile/ast"
|
||||
)
|
||||
|
||||
type (
|
||||
// A FormatterTestOption is a function that configures an [FormatterTest].
|
||||
FormatterTestOption interface {
|
||||
applyToFormatterTest(*FormatterTest)
|
||||
}
|
||||
// A FormatterTest is a test wrapper around a [task.Executor] to make it
|
||||
// easy to write tests for the task formatter. See [NewFormatterTest] for
|
||||
// information on creating and running FormatterTests. These tests use
|
||||
// fixture files to assert whether the result of the output is correct. If
|
||||
// Task's behavior has been changed, the fixture files can be updated by
|
||||
// running `task gen:fixtures`.
|
||||
FormatterTest struct {
|
||||
TaskTest
|
||||
task string
|
||||
vars map[string]any
|
||||
executorOpts []task.ExecutorOption
|
||||
listOptions task.ListOptions
|
||||
wantSetupError bool
|
||||
wantListError bool
|
||||
}
|
||||
)
|
||||
|
||||
// NewFormatterTest sets up a new [task.Executor] with the given options and
|
||||
// runs a task with the given [FormatterTestOption]s. The output of the task is
|
||||
// written to a set of fixture files depending on the configuration of the test.
|
||||
func NewFormatterTest(t *testing.T, opts ...FormatterTestOption) {
|
||||
t.Helper()
|
||||
tt := &FormatterTest{
|
||||
task: "default",
|
||||
vars: map[string]any{},
|
||||
TaskTest: TaskTest{
|
||||
experiments: map[*experiments.Experiment]int{},
|
||||
},
|
||||
}
|
||||
// Apply the functional options
|
||||
for _, opt := range opts {
|
||||
opt.applyToFormatterTest(tt)
|
||||
}
|
||||
// Enable any experiments that have been set
|
||||
for x, v := range tt.experiments {
|
||||
prev := *x
|
||||
*x = experiments.Experiment{
|
||||
Name: prev.Name,
|
||||
AllowedValues: []int{v},
|
||||
Value: v,
|
||||
}
|
||||
t.Cleanup(func() {
|
||||
*x = prev
|
||||
})
|
||||
}
|
||||
tt.run(t)
|
||||
}
|
||||
|
||||
// Functional options
|
||||
|
||||
// WithListOptions sets the list options for the formatter.
|
||||
func WithListOptions(opts task.ListOptions) FormatterTestOption {
|
||||
return &listOptionsTestOption{opts}
|
||||
}
|
||||
|
||||
type listOptionsTestOption struct {
|
||||
listOptions task.ListOptions
|
||||
}
|
||||
|
||||
func (opt *listOptionsTestOption) applyToFormatterTest(t *FormatterTest) {
|
||||
t.listOptions = opt.listOptions
|
||||
}
|
||||
|
||||
// WithListError tells the test to expect an error when running the formatter.
|
||||
// A fixture will be created with the output of any errors.
|
||||
func WithListError() FormatterTestOption {
|
||||
return &listErrorTestOption{}
|
||||
}
|
||||
|
||||
type listErrorTestOption struct{}
|
||||
|
||||
func (opt *listErrorTestOption) applyToFormatterTest(t *FormatterTest) {
|
||||
t.wantListError = true
|
||||
}
|
||||
|
||||
// Helpers
|
||||
|
||||
// writeFixtureErrList is a wrapper for writing the output of an error when
|
||||
// running the formatter to a fixture file.
|
||||
func (tt *FormatterTest) writeFixtureErrList(
|
||||
t *testing.T,
|
||||
g *goldie.Goldie,
|
||||
err error,
|
||||
) {
|
||||
t.Helper()
|
||||
tt.writeFixture(t, g, "err-list", []byte(err.Error()))
|
||||
}
|
||||
|
||||
// run is the main function for running the test. It sets up the task executor,
|
||||
// runs the task, and writes the output to a fixture file.
|
||||
func (tt *FormatterTest) run(t *testing.T) {
|
||||
t.Helper()
|
||||
f := func(t *testing.T) {
|
||||
t.Helper()
|
||||
var buf bytes.Buffer
|
||||
|
||||
opts := append(
|
||||
tt.executorOpts,
|
||||
task.ExecutorWithStdout(&buf),
|
||||
task.ExecutorWithStderr(&buf),
|
||||
)
|
||||
|
||||
// Set up the task executor
|
||||
e := task.NewExecutor(opts...)
|
||||
|
||||
// Create a golden fixture file for the output
|
||||
g := goldie.New(t,
|
||||
goldie.WithFixtureDir(filepath.Join(e.Dir, "testdata")),
|
||||
)
|
||||
|
||||
// Call setup and check for errors
|
||||
if err := e.Setup(); tt.wantSetupError {
|
||||
require.Error(t, err)
|
||||
tt.writeFixtureErrSetup(t, g, err)
|
||||
tt.writeFixtureBuffer(t, g, buf)
|
||||
return
|
||||
} else {
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
// Create the task call
|
||||
vars := ast.NewVars()
|
||||
for key, value := range tt.vars {
|
||||
vars.Set(key, ast.Var{Value: value})
|
||||
}
|
||||
|
||||
// Run the formatter and check for errors
|
||||
if _, err := e.ListTasks(tt.listOptions); tt.wantListError {
|
||||
require.Error(t, err)
|
||||
tt.writeFixtureErrList(t, g, err)
|
||||
tt.writeFixtureBuffer(t, g, buf)
|
||||
return
|
||||
} else {
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
tt.writeFixtureBuffer(t, g, buf)
|
||||
}
|
||||
|
||||
// Run the test (with a name if it has one)
|
||||
if tt.name != "" {
|
||||
t.Run(tt.name, f)
|
||||
} else {
|
||||
f(t)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNoLabelInList(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
NewFormatterTest(t,
|
||||
WithExecutorOptions(
|
||||
task.ExecutorWithDir("testdata/label_list"),
|
||||
),
|
||||
WithListOptions(task.ListOptions{
|
||||
ListOnlyTasksWithDescriptions: true,
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
// task -al case 1: listAll list all tasks
|
||||
func TestListAllShowsNoDesc(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
NewFormatterTest(t,
|
||||
WithExecutorOptions(
|
||||
task.ExecutorWithDir("testdata/list_mixed_desc"),
|
||||
),
|
||||
WithListOptions(task.ListOptions{
|
||||
ListAllTasks: true,
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
// task -al case 2: !listAll list some tasks (only those with desc)
|
||||
func TestListCanListDescOnly(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
NewFormatterTest(t,
|
||||
WithExecutorOptions(
|
||||
task.ExecutorWithDir("testdata/list_mixed_desc"),
|
||||
),
|
||||
WithListOptions(task.ListOptions{
|
||||
ListOnlyTasksWithDescriptions: true,
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
func TestListDescInterpolation(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
NewFormatterTest(t,
|
||||
WithExecutorOptions(
|
||||
task.ExecutorWithDir("testdata/list_desc_interpolation"),
|
||||
),
|
||||
WithListOptions(task.ListOptions{
|
||||
ListOnlyTasksWithDescriptions: true,
|
||||
}),
|
||||
)
|
||||
}
|
1
go.mod
1
go.mod
@ -22,6 +22,7 @@ require (
|
||||
github.com/otiai10/copy v1.14.1
|
||||
github.com/puzpuzpuz/xsync/v3 v3.5.1
|
||||
github.com/sajari/fuzzy v1.0.0
|
||||
github.com/sebdah/goldie/v2 v2.5.5
|
||||
github.com/spf13/pflag v1.0.6
|
||||
github.com/stretchr/testify v1.10.0
|
||||
github.com/zeebo/xxh3 v1.0.2
|
||||
|
5
go.sum
5
go.sum
@ -98,6 +98,7 @@ github.com/otiai10/mint v1.6.3 h1:87qsV/aw1F5as1eH1zS/yqHY85ANKVMgkDrf9rcxbQs=
|
||||
github.com/otiai10/mint v1.6.3/go.mod h1:MJm72SBthJjz8qhefc4z1PYEieWmy8Bku7CjcAqyUSM=
|
||||
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=
|
||||
@ -108,6 +109,9 @@ github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0t
|
||||
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
|
||||
github.com/sajari/fuzzy v1.0.0 h1:+FmwVvJErsd0d0hAPlj4CxqxUtQY/fOoY0DwX4ykpRY=
|
||||
github.com/sajari/fuzzy v1.0.0/go.mod h1:OjYR6KxoWOe9+dOlXeiCJd4dIbED4Oo8wpS89o0pwOo=
|
||||
github.com/sebdah/goldie/v2 v2.5.5 h1:rx1mwF95RxZ3/83sdS4Yp7t2C5TCokvWP4TBRbAyEWY=
|
||||
github.com/sebdah/goldie/v2 v2.5.5/go.mod h1:oZ9fp0+se1eapSRjfYbsV/0Hqhbuu3bJVvKI/NNtssI=
|
||||
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8=
|
||||
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4=
|
||||
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
@ -119,6 +123,7 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
|
||||
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.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
|
1298
task_test.go
1298
task_test.go
File diff suppressed because it is too large
Load Diff
1
testdata/alias/testdata/TestAlias-duplicate_alias-err-run.golden
vendored
Normal file
1
testdata/alias/testdata/TestAlias-duplicate_alias-err-run.golden
vendored
Normal file
@ -0,0 +1 @@
|
||||
task: Found multiple tasks (foo, bar) that match "x"
|
0
testdata/alias/testdata/TestAlias-duplicate_alias.golden
vendored
Normal file
0
testdata/alias/testdata/TestAlias-duplicate_alias.golden
vendored
Normal file
12
testdata/concurrency/testdata/TestConcurrency.golden
vendored
Normal file
12
testdata/concurrency/testdata/TestConcurrency.golden
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
done 1
|
||||
done 2
|
||||
done 3
|
||||
done 4
|
||||
done 5
|
||||
done 6
|
||||
task: [t1] echo done 1
|
||||
task: [t2] echo done 2
|
||||
task: [t3] echo done 3
|
||||
task: [t4] echo done 4
|
||||
task: [t5] echo done 5
|
||||
task: [t6] echo done 6
|
1
testdata/deps/.gitignore
vendored
1
testdata/deps/.gitignore
vendored
@ -1 +0,0 @@
|
||||
*.txt
|
24
testdata/deps/Taskfile.yml
vendored
24
testdata/deps/Taskfile.yml
vendored
@ -7,50 +7,50 @@ tasks:
|
||||
d1:
|
||||
deps: [d11, d12, d13]
|
||||
cmds:
|
||||
- echo 'Text' > d1.txt
|
||||
- echo 'd1'
|
||||
|
||||
d2:
|
||||
deps: [d21, d22, d23]
|
||||
cmds:
|
||||
- echo 'Text' > d2.txt
|
||||
- echo 'd2'
|
||||
|
||||
d3:
|
||||
deps: [d31, d32, d33]
|
||||
cmds:
|
||||
- echo 'Text' > d3.txt
|
||||
- echo 'd3'
|
||||
|
||||
d11:
|
||||
cmds:
|
||||
- echo 'Text' > d11.txt
|
||||
- echo 'd11'
|
||||
|
||||
d12:
|
||||
cmds:
|
||||
- echo 'Text' > d12.txt
|
||||
- echo 'd12'
|
||||
|
||||
d13:
|
||||
cmds:
|
||||
- echo 'Text' > d13.txt
|
||||
- echo 'd13'
|
||||
|
||||
d21:
|
||||
cmds:
|
||||
- echo 'Text' > d21.txt
|
||||
- echo 'd21'
|
||||
|
||||
d22:
|
||||
cmds:
|
||||
- echo 'Text' > d22.txt
|
||||
- echo 'd22'
|
||||
|
||||
d23:
|
||||
cmds:
|
||||
- echo 'Text' > d23.txt
|
||||
- echo 'd23'
|
||||
|
||||
d31:
|
||||
cmds:
|
||||
- echo 'Text' > d31.txt
|
||||
- echo 'd31'
|
||||
|
||||
d32:
|
||||
cmds:
|
||||
- echo 'Text' > d32.txt
|
||||
- echo 'd32'
|
||||
|
||||
d33:
|
||||
cmds:
|
||||
- echo 'Text' > d33.txt
|
||||
- echo 'd33'
|
||||
|
1
testdata/deps/d1.txt
vendored
Normal file
1
testdata/deps/d1.txt
vendored
Normal file
@ -0,0 +1 @@
|
||||
Text
|
1
testdata/deps/d11.txt
vendored
Normal file
1
testdata/deps/d11.txt
vendored
Normal file
@ -0,0 +1 @@
|
||||
Text
|
1
testdata/deps/d12.txt
vendored
Normal file
1
testdata/deps/d12.txt
vendored
Normal file
@ -0,0 +1 @@
|
||||
Text
|
1
testdata/deps/d13.txt
vendored
Normal file
1
testdata/deps/d13.txt
vendored
Normal file
@ -0,0 +1 @@
|
||||
Text
|
1
testdata/deps/d2.txt
vendored
Normal file
1
testdata/deps/d2.txt
vendored
Normal file
@ -0,0 +1 @@
|
||||
Text
|
1
testdata/deps/d21.txt
vendored
Normal file
1
testdata/deps/d21.txt
vendored
Normal file
@ -0,0 +1 @@
|
||||
Text
|
1
testdata/deps/d22.txt
vendored
Normal file
1
testdata/deps/d22.txt
vendored
Normal file
@ -0,0 +1 @@
|
||||
Text
|
1
testdata/deps/d23.txt
vendored
Normal file
1
testdata/deps/d23.txt
vendored
Normal file
@ -0,0 +1 @@
|
||||
Text
|
1
testdata/deps/d3.txt
vendored
Normal file
1
testdata/deps/d3.txt
vendored
Normal file
@ -0,0 +1 @@
|
||||
Text
|
1
testdata/deps/d31.txt
vendored
Normal file
1
testdata/deps/d31.txt
vendored
Normal file
@ -0,0 +1 @@
|
||||
Text
|
1
testdata/deps/d32.txt
vendored
Normal file
1
testdata/deps/d32.txt
vendored
Normal file
@ -0,0 +1 @@
|
||||
Text
|
1
testdata/deps/d33.txt
vendored
Normal file
1
testdata/deps/d33.txt
vendored
Normal file
@ -0,0 +1 @@
|
||||
Text
|
12
testdata/deps/testdata/TestDeps.golden
vendored
Normal file
12
testdata/deps/testdata/TestDeps.golden
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
d1
|
||||
d11
|
||||
d12
|
||||
d13
|
||||
d2
|
||||
d21
|
||||
d22
|
||||
d23
|
||||
d3
|
||||
d31
|
||||
d32
|
||||
d33
|
0
testdata/empty_task/testdata/TestEmptyTask.golden
vendored
Normal file
0
testdata/empty_task/testdata/TestEmptyTask.golden
vendored
Normal file
1
testdata/empty_taskfile/testdata/TestEmptyTaskfile-err-setup.golden
vendored
Normal file
1
testdata/empty_taskfile/testdata/TestEmptyTaskfile-err-setup.golden
vendored
Normal file
@ -0,0 +1 @@
|
||||
task: Missing schema version in Taskfile "/testdata/empty_taskfile/Taskfile.yml"
|
0
testdata/empty_taskfile/testdata/TestEmptyTaskfile.golden
vendored
Normal file
0
testdata/empty_taskfile/testdata/TestEmptyTaskfile.golden
vendored
Normal file
1
testdata/env/.gitignore
vendored
1
testdata/env/.gitignore
vendored
@ -1 +0,0 @@
|
||||
*.txt
|
12
testdata/env/Taskfile.yml
vendored
12
testdata/env/Taskfile.yml
vendored
@ -28,13 +28,13 @@ tasks:
|
||||
CGO_ENABLED:
|
||||
sh: echo '0'
|
||||
cmds:
|
||||
- echo "GOOS='$GOOS' GOARCH='$GOARCH' CGO_ENABLED='$CGO_ENABLED'" > local.txt
|
||||
- echo "GOOS='$GOOS' GOARCH='$GOARCH' CGO_ENABLED='$CGO_ENABLED'"
|
||||
|
||||
global:
|
||||
env:
|
||||
BAR: overridden
|
||||
cmds:
|
||||
- echo "FOO='$FOO' BAR='$BAR' BAZ='$BAZ'" > global.txt
|
||||
- echo "FOO='$FOO' BAR='$BAR' BAZ='$BAZ'"
|
||||
|
||||
multiple_type:
|
||||
env:
|
||||
@ -42,15 +42,15 @@ tasks:
|
||||
BAR: true
|
||||
BAZ: 1.1
|
||||
cmds:
|
||||
- echo "FOO='$FOO' BAR='$BAR' BAZ='$BAZ'" > multiple_type.txt
|
||||
- echo "FOO='$FOO' BAR='$BAR' BAZ='$BAZ'"
|
||||
|
||||
not-overridden:
|
||||
cmds:
|
||||
- echo "QUX='$QUX'" > not-overridden.txt
|
||||
- echo "QUX='$QUX'"
|
||||
|
||||
overridden:
|
||||
cmds:
|
||||
- echo "QUX='$QUX'" > overridden.txt
|
||||
- echo "QUX='$QUX'"
|
||||
|
||||
dynamic:
|
||||
silent: true
|
||||
@ -58,4 +58,4 @@ tasks:
|
||||
DYNAMIC_FOO:
|
||||
sh: echo $FOO
|
||||
cmds:
|
||||
- echo "{{ .DYNAMIC_FOO }}" > dynamic.txt
|
||||
- echo "{{ .DYNAMIC_FOO }}"
|
||||
|
1
testdata/env/dynamic.txt
vendored
Normal file
1
testdata/env/dynamic.txt
vendored
Normal file
@ -0,0 +1 @@
|
||||
foo
|
1
testdata/env/global.txt
vendored
Normal file
1
testdata/env/global.txt
vendored
Normal file
@ -0,0 +1 @@
|
||||
FOO='foo' BAR='overridden' BAZ='baz'
|
1
testdata/env/local.txt
vendored
Normal file
1
testdata/env/local.txt
vendored
Normal file
@ -0,0 +1 @@
|
||||
GOOS='linux' GOARCH='amd64' CGO_ENABLED='0'
|
1
testdata/env/multiple_type.txt
vendored
Normal file
1
testdata/env/multiple_type.txt
vendored
Normal file
@ -0,0 +1 @@
|
||||
FOO='1' BAR='true' BAZ='1.1'
|
1
testdata/env/not-overridden.txt
vendored
Normal file
1
testdata/env/not-overridden.txt
vendored
Normal file
@ -0,0 +1 @@
|
||||
QUX='from_os'
|
1
testdata/env/overridden.txt
vendored
Normal file
1
testdata/env/overridden.txt
vendored
Normal file
@ -0,0 +1 @@
|
||||
QUX='from_taskfile'
|
5
testdata/env/testdata/TestEnv-env_precedence_disabled.golden
vendored
Normal file
5
testdata/env/testdata/TestEnv-env_precedence_disabled.golden
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
GOOS='linux' GOARCH='amd64' CGO_ENABLED='0'
|
||||
FOO='foo' BAR='overridden' BAZ='baz'
|
||||
QUX='from_os'
|
||||
FOO='1' BAR='true' BAZ='1.1'
|
||||
foo
|
5
testdata/env/testdata/TestEnv-env_precedence_enabled.golden
vendored
Normal file
5
testdata/env/testdata/TestEnv-env_precedence_enabled.golden
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
GOOS='linux' GOARCH='amd64' CGO_ENABLED='0'
|
||||
FOO='foo' BAR='overridden' BAZ='baz'
|
||||
QUX='from_taskfile'
|
||||
FOO='1' BAR='true' BAZ='1.1'
|
||||
foo
|
3
testdata/for/cmds/testdata/TestForCmds-loop-different-tasks.golden
vendored
Normal file
3
testdata/for/cmds/testdata/TestForCmds-loop-different-tasks.golden
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
1
|
||||
2
|
||||
3
|
3
testdata/for/cmds/testdata/TestForCmds-loop-explicit.golden
vendored
Normal file
3
testdata/for/cmds/testdata/TestForCmds-loop-explicit.golden
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
a
|
||||
b
|
||||
c
|
2
testdata/for/cmds/testdata/TestForCmds-loop-matrix-ref-error-err-run.golden
vendored
Normal file
2
testdata/for/cmds/testdata/TestForCmds-loop-matrix-ref-error-err-run.golden
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
task: Failed to parse /testdata/for/cmds/Taskfile.yml:
|
||||
matrix reference ".NOT_A_LIST" must resolve to a list
|
0
testdata/for/cmds/testdata/TestForCmds-loop-matrix-ref-error.golden
vendored
Normal file
0
testdata/for/cmds/testdata/TestForCmds-loop-matrix-ref-error.golden
vendored
Normal file
6
testdata/for/cmds/testdata/TestForCmds-loop-matrix-ref.golden
vendored
Normal file
6
testdata/for/cmds/testdata/TestForCmds-loop-matrix-ref.golden
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
windows/amd64
|
||||
windows/arm64
|
||||
linux/amd64
|
||||
linux/arm64
|
||||
darwin/amd64
|
||||
darwin/arm64
|
6
testdata/for/cmds/testdata/TestForCmds-loop-matrix.golden
vendored
Normal file
6
testdata/for/cmds/testdata/TestForCmds-loop-matrix.golden
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
windows/amd64
|
||||
windows/arm64
|
||||
linux/amd64
|
||||
linux/arm64
|
||||
darwin/amd64
|
||||
darwin/arm64
|
2
testdata/for/cmds/testdata/TestForCmds-loop-sources-glob.golden
vendored
Normal file
2
testdata/for/cmds/testdata/TestForCmds-loop-sources-glob.golden
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
bar
|
||||
foo
|
2
testdata/for/cmds/testdata/TestForCmds-loop-sources.golden
vendored
Normal file
2
testdata/for/cmds/testdata/TestForCmds-loop-sources.golden
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
bar
|
||||
foo
|
2
testdata/for/cmds/testdata/TestForCmds-loop-task-as.golden
vendored
Normal file
2
testdata/for/cmds/testdata/TestForCmds-loop-task-as.golden
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
foo
|
||||
bar
|
2
testdata/for/cmds/testdata/TestForCmds-loop-task.golden
vendored
Normal file
2
testdata/for/cmds/testdata/TestForCmds-loop-task.golden
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
foo
|
||||
bar
|
2
testdata/for/cmds/testdata/TestForCmds-loop-vars-sh.golden
vendored
Normal file
2
testdata/for/cmds/testdata/TestForCmds-loop-vars-sh.golden
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
bar
|
||||
foo
|
2
testdata/for/cmds/testdata/TestForCmds-loop-vars.golden
vendored
Normal file
2
testdata/for/cmds/testdata/TestForCmds-loop-vars.golden
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
foo
|
||||
bar
|
3
testdata/for/deps/testdata/TestForDeps-loop-different-tasks.golden
vendored
Normal file
3
testdata/for/deps/testdata/TestForDeps-loop-different-tasks.golden
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
1
|
||||
2
|
||||
3
|
3
testdata/for/deps/testdata/TestForDeps-loop-explicit.golden
vendored
Normal file
3
testdata/for/deps/testdata/TestForDeps-loop-explicit.golden
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
a
|
||||
b
|
||||
c
|
2
testdata/for/deps/testdata/TestForDeps-loop-matrix-ref-error-err-run.golden
vendored
Normal file
2
testdata/for/deps/testdata/TestForDeps-loop-matrix-ref-error-err-run.golden
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
matrix reference ".NOT_A_LIST" must resolve to a list
|
||||
task: Failed to parse /testdata/for/deps/Taskfile.yml:
|
1
testdata/for/deps/testdata/TestForDeps-loop-matrix-ref-error.golden
vendored
Normal file
1
testdata/for/deps/testdata/TestForDeps-loop-matrix-ref-error.golden
vendored
Normal file
@ -0,0 +1 @@
|
||||
|
6
testdata/for/deps/testdata/TestForDeps-loop-matrix-ref.golden
vendored
Normal file
6
testdata/for/deps/testdata/TestForDeps-loop-matrix-ref.golden
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
darwin/amd64
|
||||
darwin/arm64
|
||||
linux/amd64
|
||||
linux/arm64
|
||||
windows/amd64
|
||||
windows/arm64
|
6
testdata/for/deps/testdata/TestForDeps-loop-matrix.golden
vendored
Normal file
6
testdata/for/deps/testdata/TestForDeps-loop-matrix.golden
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
darwin/amd64
|
||||
darwin/arm64
|
||||
linux/amd64
|
||||
linux/arm64
|
||||
windows/amd64
|
||||
windows/arm64
|
2
testdata/for/deps/testdata/TestForDeps-loop-sources-glob.golden
vendored
Normal file
2
testdata/for/deps/testdata/TestForDeps-loop-sources-glob.golden
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
bar
|
||||
foo
|
2
testdata/for/deps/testdata/TestForDeps-loop-sources.golden
vendored
Normal file
2
testdata/for/deps/testdata/TestForDeps-loop-sources.golden
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
bar
|
||||
foo
|
2
testdata/for/deps/testdata/TestForDeps-loop-task-as.golden
vendored
Normal file
2
testdata/for/deps/testdata/TestForDeps-loop-task-as.golden
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
bar
|
||||
foo
|
2
testdata/for/deps/testdata/TestForDeps-loop-task.golden
vendored
Normal file
2
testdata/for/deps/testdata/TestForDeps-loop-task.golden
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
bar
|
||||
foo
|
2
testdata/for/deps/testdata/TestForDeps-loop-vars-sh.golden
vendored
Normal file
2
testdata/for/deps/testdata/TestForDeps-loop-vars-sh.golden
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
bar
|
||||
foo
|
2
testdata/for/deps/testdata/TestForDeps-loop-vars.golden
vendored
Normal file
2
testdata/for/deps/testdata/TestForDeps-loop-vars.golden
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
bar
|
||||
foo
|
2
testdata/label_list/testdata/TestNoLabelInList.golden
vendored
Normal file
2
testdata/label_list/testdata/TestNoLabelInList.golden
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
task: Available tasks for this project:
|
||||
* foo: task description
|
1
testdata/label_status/testdata/TestLabel-status-err-status.golden
vendored
Normal file
1
testdata/label_status/testdata/TestLabel-status-err-status.golden
vendored
Normal file
@ -0,0 +1 @@
|
||||
task: Task "foobar" is not up-to-date
|
0
testdata/label_status/testdata/TestLabel-status.golden
vendored
Normal file
0
testdata/label_status/testdata/TestLabel-status.golden
vendored
Normal file
1
testdata/label_summary/testdata/TestLabel-label_in_summary.golden
vendored
Normal file
1
testdata/label_summary/testdata/TestLabel-label_in_summary.golden
vendored
Normal file
@ -0,0 +1 @@
|
||||
task: Task "foobar" is up to date
|
3
testdata/label_summary/testdata/TestLabel-summary.golden
vendored
Normal file
3
testdata/label_summary/testdata/TestLabel-summary.golden
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
task: foobar
|
||||
|
||||
description
|
1
testdata/label_uptodate/testdata/TestLabel-up_to_date.golden
vendored
Normal file
1
testdata/label_uptodate/testdata/TestLabel-up_to_date.golden
vendored
Normal file
@ -0,0 +1 @@
|
||||
task: Task "foobar" is up to date
|
1
testdata/label_var/testdata/TestLabel-var.golden
vendored
Normal file
1
testdata/label_var/testdata/TestLabel-var.golden
vendored
Normal file
@ -0,0 +1 @@
|
||||
task: Task "foobaz" is up to date
|
3
testdata/list_desc_interpolation/testdata/TestListDescInterpolation.golden
vendored
Normal file
3
testdata/list_desc_interpolation/testdata/TestListDescInterpolation.golden
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
task: Available tasks for this project:
|
||||
* bar: task has desc with bar-var
|
||||
* foo: task has desc with foo-var
|
4
testdata/list_mixed_desc/testdata/TestListAllShowsNoDesc.golden
vendored
Normal file
4
testdata/list_mixed_desc/testdata/TestListAllShowsNoDesc.golden
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
task: Available tasks for this project:
|
||||
* doo:
|
||||
* foo: foo has desc and label
|
||||
* voo:
|
2
testdata/list_mixed_desc/testdata/TestListCanListDescOnly.golden
vendored
Normal file
2
testdata/list_mixed_desc/testdata/TestListCanListDescOnly.golden
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
task: Available tasks for this project:
|
||||
* foo: foo has desc and label
|
1
testdata/params/.gitignore
vendored
1
testdata/params/.gitignore
vendored
@ -1 +0,0 @@
|
||||
*.txt
|
22
testdata/params/Taskfile.yml
vendored
22
testdata/params/Taskfile.yml
vendored
@ -12,33 +12,33 @@ tasks:
|
||||
GERMAN: "Welt!"
|
||||
deps:
|
||||
- task: write-file
|
||||
vars: {CONTENT: Dependence1, FILE: dep1.txt}
|
||||
vars: {CONTENT: Dependence1}
|
||||
- task: write-file
|
||||
vars: {CONTENT: Dependence2, FILE: dep2.txt}
|
||||
vars: {CONTENT: Dependence2}
|
||||
- task: write-file
|
||||
vars: {CONTENT: "{{.SPANISH|replace \"mundo\" \"dependencia\"}}", FILE: spanish-dep.txt}
|
||||
vars: {CONTENT: "{{.SPANISH|replace \"mundo\" \"dependencia\"}}"}
|
||||
cmds:
|
||||
- task: write-file
|
||||
vars: {CONTENT: Hello, FILE: hello.txt}
|
||||
vars: {CONTENT: Hello}
|
||||
- task: write-file
|
||||
vars: {CONTENT: "$echo 'World'", FILE: world.txt}
|
||||
vars: {CONTENT: "$echo 'World'"}
|
||||
- task: write-file
|
||||
vars: {CONTENT: "!", FILE: exclamation.txt}
|
||||
vars: {CONTENT: "!"}
|
||||
- task: write-file
|
||||
vars: {CONTENT: "{{.SPANISH}}", FILE: spanish.txt}
|
||||
vars: {CONTENT: "{{.SPANISH}}"}
|
||||
- task: write-file
|
||||
vars: {CONTENT: "{{.PORTUGUESE}}", FILE: portuguese.txt}
|
||||
vars: {CONTENT: "{{.PORTUGUESE}}"}
|
||||
- task: write-file
|
||||
vars: {CONTENT: "{{.GERMAN}}", FILE: german.txt}
|
||||
vars: {CONTENT: "{{.GERMAN}}"}
|
||||
- task: non-default
|
||||
|
||||
write-file:
|
||||
cmds:
|
||||
- echo {{.CONTENT}} > {{.FILE}}
|
||||
- echo {{.CONTENT}}
|
||||
|
||||
non-default:
|
||||
vars:
|
||||
PORTUGUESE: "{{.PORTUGUESE_HELLO_WORLD}}"
|
||||
cmds:
|
||||
- task: write-file
|
||||
vars: {CONTENT: "{{.PORTUGUESE}}", FILE: portuguese2.txt}
|
||||
vars: {CONTENT: "{{.PORTUGUESE}}"}
|
||||
|
1
testdata/params/dep1.txt
vendored
Normal file
1
testdata/params/dep1.txt
vendored
Normal file
@ -0,0 +1 @@
|
||||
Dependence1
|
1
testdata/params/dep2.txt
vendored
Normal file
1
testdata/params/dep2.txt
vendored
Normal file
@ -0,0 +1 @@
|
||||
Dependence2
|
1
testdata/params/exclamation.txt
vendored
Normal file
1
testdata/params/exclamation.txt
vendored
Normal file
@ -0,0 +1 @@
|
||||
!
|
1
testdata/params/german.txt
vendored
Normal file
1
testdata/params/german.txt
vendored
Normal file
@ -0,0 +1 @@
|
||||
Welt!
|
1
testdata/params/hello.txt
vendored
Normal file
1
testdata/params/hello.txt
vendored
Normal file
@ -0,0 +1 @@
|
||||
Hello
|
1
testdata/params/portuguese.txt
vendored
Normal file
1
testdata/params/portuguese.txt
vendored
Normal file
@ -0,0 +1 @@
|
||||
Olá, mundo!
|
1
testdata/params/portuguese2.txt
vendored
Normal file
1
testdata/params/portuguese2.txt
vendored
Normal file
@ -0,0 +1 @@
|
||||
Olá, mundo!
|
1
testdata/params/spanish-dep.txt
vendored
Normal file
1
testdata/params/spanish-dep.txt
vendored
Normal file
@ -0,0 +1 @@
|
||||
¡Holla dependencia!
|
1
testdata/params/spanish.txt
vendored
Normal file
1
testdata/params/spanish.txt
vendored
Normal file
@ -0,0 +1 @@
|
||||
¡Holla mundo!
|
10
testdata/params/testdata/TestParams.golden
vendored
Normal file
10
testdata/params/testdata/TestParams.golden
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
!
|
||||
Dependence1
|
||||
Dependence2
|
||||
Hello
|
||||
Olá, mundo!
|
||||
Olá, mundo!
|
||||
Welt!
|
||||
World
|
||||
¡Holla dependencia!
|
||||
¡Holla mundo!
|
1
testdata/params/world.txt
vendored
Normal file
1
testdata/params/world.txt
vendored
Normal file
@ -0,0 +1 @@
|
||||
World
|
0
testdata/precondition/testdata/TestPrecondition-a_precondition_has_been_met.golden
vendored
Normal file
0
testdata/precondition/testdata/TestPrecondition-a_precondition_has_been_met.golden
vendored
Normal file
1
testdata/precondition/testdata/TestPrecondition-a_precondition_was_not_met-err-run.golden
vendored
Normal file
1
testdata/precondition/testdata/TestPrecondition-a_precondition_was_not_met-err-run.golden
vendored
Normal file
@ -0,0 +1 @@
|
||||
task: precondition not met
|
1
testdata/precondition/testdata/TestPrecondition-a_precondition_was_not_met.golden
vendored
Normal file
1
testdata/precondition/testdata/TestPrecondition-a_precondition_was_not_met.golden
vendored
Normal file
@ -0,0 +1 @@
|
||||
task: 1 != 0 obviously!
|
@ -0,0 +1 @@
|
||||
task: Failed to run task "executes_failing_task_as_cmd": task: precondition not met
|
1
testdata/precondition/testdata/TestPrecondition-precondition_in_cmd_fails_the_task.golden
vendored
Normal file
1
testdata/precondition/testdata/TestPrecondition-precondition_in_cmd_fails_the_task.golden
vendored
Normal file
@ -0,0 +1 @@
|
||||
task: 1 != 0 obviously!
|
@ -0,0 +1 @@
|
||||
task: precondition not met
|
@ -0,0 +1 @@
|
||||
task: 1 != 0 obviously!
|
3
testdata/prompt/testdata/TestPromptAssumeYes---yes_flag_should_skip_prompt.golden
vendored
Normal file
3
testdata/prompt/testdata/TestPromptAssumeYes---yes_flag_should_skip_prompt.golden
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
Do you want to continue? [assuming yes]
|
||||
task: [foo] echo 'foo'
|
||||
foo
|
@ -0,0 +1 @@
|
||||
task: Task "foo" cancelled by user
|
@ -0,0 +1 @@
|
||||
Do you want to continue? [y/N]:
|
@ -0,0 +1 @@
|
||||
task: Task "foo" cancelled by user
|
@ -0,0 +1 @@
|
||||
Do you want to continue? [y/N]:
|
@ -0,0 +1 @@
|
||||
task: Task "foo" cancelled by user
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user