From 05600601ffa544fa64cb1ee1bf6e52950ff3a5ed Mon Sep 17 00:00:00 2001 From: Tobias Salzmann Date: Tue, 10 Jul 2018 10:44:58 +0200 Subject: [PATCH 1/6] add ignoreError option --- internal/execext/exec.go | 24 ++++++++++----- internal/taskfile/call.go | 5 ++-- internal/taskfile/cmd.go | 32 ++++++++++++-------- task.go | 19 ++++++------ task_test.go | 45 ++++++++++++++++++++++++++++- testdata/ignore_errors/Taskfile.yml | 15 ++++++++++ variables.go | 10 +++---- 7 files changed, 113 insertions(+), 37 deletions(-) create mode 100644 testdata/ignore_errors/Taskfile.yml diff --git a/internal/execext/exec.go b/internal/execext/exec.go index f86003bb..4428bd39 100644 --- a/internal/execext/exec.go +++ b/internal/execext/exec.go @@ -13,13 +13,14 @@ import ( // RunCommandOptions is the options for the RunCommand func type RunCommandOptions struct { - Context context.Context - Command string - Dir string - Env []string - Stdin io.Reader - Stdout io.Writer - Stderr io.Writer + Context context.Context + Command string + Dir string + Env []string + Stdin io.Reader + Stdout io.Writer + Stderr io.Writer + IgnoreErrorCode bool } var ( @@ -62,5 +63,12 @@ func RunCommand(opts *RunCommandOptions) error { if err = r.Reset(); err != nil { return err } - return r.Run(p) + if err = r.Run(p); err != nil { + if opts.IgnoreErrorCode { + if _, ok := err.(interp.ExitCode); ok { + return nil + } + } + } + return err } diff --git a/internal/taskfile/call.go b/internal/taskfile/call.go index eec41031..3b3ac725 100644 --- a/internal/taskfile/call.go +++ b/internal/taskfile/call.go @@ -2,6 +2,7 @@ package taskfile // Call is the parameters to a task call type Call struct { - Task string - Vars Vars + Task string + Vars Vars + IgnoreError bool } diff --git a/internal/taskfile/cmd.go b/internal/taskfile/cmd.go index f2bae2fc..78fdd370 100644 --- a/internal/taskfile/cmd.go +++ b/internal/taskfile/cmd.go @@ -7,16 +7,18 @@ import ( // Cmd is a task command type Cmd struct { - Cmd string - Silent bool - Task string - Vars Vars + Cmd string + Silent bool + Task string + Vars Vars + IgnoreError bool } // Dep is a task dependency type Dep struct { - Task string - Vars Vars + Task string + Vars Vars + IgnoreError bool } var ( @@ -38,21 +40,25 @@ func (c *Cmd) UnmarshalYAML(unmarshal func(interface{}) error) error { return nil } var cmdStruct struct { - Cmd string - Silent bool + Cmd string + Silent bool + IgnoreError bool `yaml:"ignoreError"` } if err := unmarshal(&cmdStruct); err == nil && cmdStruct.Cmd != "" { c.Cmd = cmdStruct.Cmd c.Silent = cmdStruct.Silent + c.IgnoreError = cmdStruct.IgnoreError return nil } var taskCall struct { - Task string - Vars Vars + Task string + Vars Vars + IgnoreError bool `yaml:"ignoreError"` } if err := unmarshal(&taskCall); err == nil { c.Task = taskCall.Task c.Vars = taskCall.Vars + c.IgnoreError = taskCall.IgnoreError return nil } return ErrCantUnmarshalCmd @@ -66,12 +72,14 @@ func (d *Dep) UnmarshalYAML(unmarshal func(interface{}) error) error { return nil } var taskCall struct { - Task string - Vars Vars + Task string + Vars Vars + IgnoreError bool `yaml:"ignoreError"` } if err := unmarshal(&taskCall); err == nil { d.Task = taskCall.Task d.Vars = taskCall.Vars + d.IgnoreError = taskCall.IgnoreError return nil } return ErrCantUnmarshalDep diff --git a/task.go b/task.go index f8805bd3..500e4112 100644 --- a/task.go +++ b/task.go @@ -188,7 +188,7 @@ func (e *Executor) runDeps(ctx context.Context, t *taskfile.Task) error { d := d g.Go(func() error { - return e.RunTask(ctx, taskfile.Call{Task: d.Task, Vars: d.Vars}) + return e.RunTask(ctx, taskfile.Call{Task: d.Task, Vars: d.Vars, IgnoreError: d.IgnoreError}) }) } @@ -200,7 +200,7 @@ func (e *Executor) runCommand(ctx context.Context, t *taskfile.Task, call taskfi switch { case cmd.Task != "": - return e.RunTask(ctx, taskfile.Call{Task: cmd.Task, Vars: cmd.Vars}) + return e.RunTask(ctx, taskfile.Call{Task: cmd.Task, Vars: cmd.Vars, IgnoreError: cmd.IgnoreError || call.IgnoreError}) case cmd.Cmd != "": if e.Verbose || (!cmd.Silent && !t.Silent && !e.Silent) { e.Logger.Errf(cmd.Cmd) @@ -212,13 +212,14 @@ func (e *Executor) runCommand(ctx context.Context, t *taskfile.Task, call taskfi defer stdErr.Close() return execext.RunCommand(&execext.RunCommandOptions{ - Context: ctx, - Command: cmd.Cmd, - Dir: t.Dir, - Env: getEnviron(t), - Stdin: e.Stdin, - Stdout: stdOut, - Stderr: stdErr, + Context: ctx, + Command: cmd.Cmd, + Dir: t.Dir, + Env: getEnviron(t), + Stdin: e.Stdin, + Stdout: stdOut, + Stderr: stdErr, + IgnoreErrorCode: cmd.IgnoreError || call.IgnoreError, }) default: return nil diff --git a/task_test.go b/task_test.go index 6e48faa8..4176eeab 100644 --- a/task_test.go +++ b/task_test.go @@ -52,7 +52,6 @@ func (fct fileContentTest) Run(t *testing.T) { assert.Equal(t, expectContent, s, "unexpected file content") }) } - } func TestEnv(t *testing.T) { @@ -412,3 +411,47 @@ func TestTaskVersion(t *testing.T) { }) } } + +func TestTaskIgnoreErrors(t *testing.T) { + const dir = "testdata/ignore_errors" + + t.Run("CmdShouldPass", func(t *testing.T) { + e := task.Executor{ + Dir: dir, + Stdout: ioutil.Discard, + Stderr: ioutil.Discard, + } + assert.NoError(t, e.Setup()) + assert.NoError(t, e.Run(taskfile.Call{Task: "CmdShouldPass"})) + }) + + t.Run("CmdShouldFail", func(t *testing.T) { + e := task.Executor{ + Dir: dir, + Stdout: ioutil.Discard, + Stderr: ioutil.Discard, + } + assert.NoError(t, e.Setup()) + assert.Error(t, e.Run(taskfile.Call{Task: "CmdShouldFail"})) + }) + + t.Run("TaskShouldPass", func(t *testing.T) { + e := task.Executor{ + Dir: dir, + Stdout: ioutil.Discard, + Stderr: ioutil.Discard, + } + assert.NoError(t, e.Setup()) + assert.NoError(t, e.Run(taskfile.Call{Task: "TaskShouldPass"})) + }) + + t.Run("TaskShouldFail", func(t *testing.T) { + e := task.Executor{ + Dir: dir, + Stdout: ioutil.Discard, + Stderr: ioutil.Discard, + } + assert.NoError(t, e.Setup()) + assert.Error(t, e.Run(taskfile.Call{Task: "TaskShouldFail"})) + }) +} diff --git a/testdata/ignore_errors/Taskfile.yml b/testdata/ignore_errors/Taskfile.yml new file mode 100644 index 00000000..3e5a67c5 --- /dev/null +++ b/testdata/ignore_errors/Taskfile.yml @@ -0,0 +1,15 @@ +CmdShouldPass: + cmds: + - cmd: UnknownCommandThatNeverWillExist + ignoreError: true +CmdShouldFail: + cmds: + - cmd: UnknownCommandThatNeverWillExist + +TaskShouldPass: + cmds: + - task: CmdShouldFail + ignoreError: true +TaskShouldFail: + cmds: + - task: CmdShouldFail \ No newline at end of file diff --git a/variables.go b/variables.go index ce8a4127..a30679d0 100644 --- a/variables.go +++ b/variables.go @@ -62,12 +62,12 @@ func (e *Executor) CompiledTask(call taskfile.Call) (*taskfile.Task, error) { new.Cmds = make([]*taskfile.Cmd, len(origTask.Cmds)) for i, cmd := range origTask.Cmds { new.Cmds[i] = &taskfile.Cmd{ - Task: r.Replace(cmd.Task), - Silent: cmd.Silent, - Cmd: r.Replace(cmd.Cmd), - Vars: r.ReplaceVars(cmd.Vars), + Task: r.Replace(cmd.Task), + Silent: cmd.Silent, + Cmd: r.Replace(cmd.Cmd), + Vars: r.ReplaceVars(cmd.Vars), + IgnoreError: cmd.IgnoreError, } - } } if len(origTask.Deps) > 0 { From 108cb91d959e8e5c559b67802b804c9bbf4b8369 Mon Sep 17 00:00:00 2001 From: Tobias Salzmann Date: Wed, 1 Aug 2018 10:44:53 +0200 Subject: [PATCH 2/6] IgnoreError * Document ignore_error * ignore_error only for commands --- README.md | 29 +++++++++++++++++++++++++++++ internal/taskfile/call.go | 5 ++--- internal/taskfile/cmd.go | 19 +++++++------------ task.go | 6 +++--- task_test.go | 28 ++++------------------------ testdata/ignore_errors/Taskfile.yml | 24 ++++++++++-------------- 6 files changed, 55 insertions(+), 56 deletions(-) diff --git a/README.md b/README.md index 9595e4a5..719aa31f 100644 --- a/README.md +++ b/README.md @@ -632,6 +632,35 @@ tasks: - echo "This will print nothing" > /dev/null ``` +## Ignore errors + +You have the option to ignore errors during command execution. +Given the following Taskfile: + +```yml +version: '2' + +tasks: + echo: + cmds: + - exit 1 + - echo "Hello World" +``` + +Task will abort the execution after running `exit 1` because the status code `1` stands for `EXIT_FAILURE`. +However it is possible to continue with execution using `ignore_errors`: + +```yml +version: '2' + +tasks: + echo: + cmds: + - cmd: exit 1 + ignore_errors: true + - echo "Hello World" +``` + ## Output syntax By default, Task just redirect the STDOUT and STDERR of the running commands diff --git a/internal/taskfile/call.go b/internal/taskfile/call.go index 3b3ac725..eec41031 100644 --- a/internal/taskfile/call.go +++ b/internal/taskfile/call.go @@ -2,7 +2,6 @@ package taskfile // Call is the parameters to a task call type Call struct { - Task string - Vars Vars - IgnoreError bool + Task string + Vars Vars } diff --git a/internal/taskfile/cmd.go b/internal/taskfile/cmd.go index 78fdd370..ea267811 100644 --- a/internal/taskfile/cmd.go +++ b/internal/taskfile/cmd.go @@ -16,9 +16,8 @@ type Cmd struct { // Dep is a task dependency type Dep struct { - Task string - Vars Vars - IgnoreError bool + Task string + Vars Vars } var ( @@ -42,7 +41,7 @@ func (c *Cmd) UnmarshalYAML(unmarshal func(interface{}) error) error { var cmdStruct struct { Cmd string Silent bool - IgnoreError bool `yaml:"ignoreError"` + IgnoreError bool `yaml:"ignore_error"` } if err := unmarshal(&cmdStruct); err == nil && cmdStruct.Cmd != "" { c.Cmd = cmdStruct.Cmd @@ -51,14 +50,12 @@ func (c *Cmd) UnmarshalYAML(unmarshal func(interface{}) error) error { return nil } var taskCall struct { - Task string - Vars Vars - IgnoreError bool `yaml:"ignoreError"` + Task string + Vars Vars } if err := unmarshal(&taskCall); err == nil { c.Task = taskCall.Task c.Vars = taskCall.Vars - c.IgnoreError = taskCall.IgnoreError return nil } return ErrCantUnmarshalCmd @@ -72,14 +69,12 @@ func (d *Dep) UnmarshalYAML(unmarshal func(interface{}) error) error { return nil } var taskCall struct { - Task string - Vars Vars - IgnoreError bool `yaml:"ignoreError"` + Task string + Vars Vars } if err := unmarshal(&taskCall); err == nil { d.Task = taskCall.Task d.Vars = taskCall.Vars - d.IgnoreError = taskCall.IgnoreError return nil } return ErrCantUnmarshalDep diff --git a/task.go b/task.go index 500e4112..d4fa70e7 100644 --- a/task.go +++ b/task.go @@ -188,7 +188,7 @@ func (e *Executor) runDeps(ctx context.Context, t *taskfile.Task) error { d := d g.Go(func() error { - return e.RunTask(ctx, taskfile.Call{Task: d.Task, Vars: d.Vars, IgnoreError: d.IgnoreError}) + return e.RunTask(ctx, taskfile.Call{Task: d.Task, Vars: d.Vars}) }) } @@ -200,7 +200,7 @@ func (e *Executor) runCommand(ctx context.Context, t *taskfile.Task, call taskfi switch { case cmd.Task != "": - return e.RunTask(ctx, taskfile.Call{Task: cmd.Task, Vars: cmd.Vars, IgnoreError: cmd.IgnoreError || call.IgnoreError}) + return e.RunTask(ctx, taskfile.Call{Task: cmd.Task, Vars: cmd.Vars}) case cmd.Cmd != "": if e.Verbose || (!cmd.Silent && !t.Silent && !e.Silent) { e.Logger.Errf(cmd.Cmd) @@ -219,7 +219,7 @@ func (e *Executor) runCommand(ctx context.Context, t *taskfile.Task, call taskfi Stdin: e.Stdin, Stdout: stdOut, Stderr: stdErr, - IgnoreErrorCode: cmd.IgnoreError || call.IgnoreError, + IgnoreErrorCode: cmd.IgnoreError, }) default: return nil diff --git a/task_test.go b/task_test.go index 4176eeab..2daa23e7 100644 --- a/task_test.go +++ b/task_test.go @@ -415,43 +415,23 @@ func TestTaskVersion(t *testing.T) { func TestTaskIgnoreErrors(t *testing.T) { const dir = "testdata/ignore_errors" - t.Run("CmdShouldPass", func(t *testing.T) { + t.Run("cmd-should-pass", func(t *testing.T) { e := task.Executor{ Dir: dir, Stdout: ioutil.Discard, Stderr: ioutil.Discard, } assert.NoError(t, e.Setup()) - assert.NoError(t, e.Run(taskfile.Call{Task: "CmdShouldPass"})) + assert.NoError(t, e.Run(taskfile.Call{Task: "cmd-should-pass"})) }) - t.Run("CmdShouldFail", func(t *testing.T) { + t.Run("cmd-should-fail", func(t *testing.T) { e := task.Executor{ Dir: dir, Stdout: ioutil.Discard, Stderr: ioutil.Discard, } assert.NoError(t, e.Setup()) - assert.Error(t, e.Run(taskfile.Call{Task: "CmdShouldFail"})) - }) - - t.Run("TaskShouldPass", func(t *testing.T) { - e := task.Executor{ - Dir: dir, - Stdout: ioutil.Discard, - Stderr: ioutil.Discard, - } - assert.NoError(t, e.Setup()) - assert.NoError(t, e.Run(taskfile.Call{Task: "TaskShouldPass"})) - }) - - t.Run("TaskShouldFail", func(t *testing.T) { - e := task.Executor{ - Dir: dir, - Stdout: ioutil.Discard, - Stderr: ioutil.Discard, - } - assert.NoError(t, e.Setup()) - assert.Error(t, e.Run(taskfile.Call{Task: "TaskShouldFail"})) + assert.Error(t, e.Run(taskfile.Call{Task: "cmd-should-fail"})) }) } diff --git a/testdata/ignore_errors/Taskfile.yml b/testdata/ignore_errors/Taskfile.yml index 3e5a67c5..57d86a6f 100644 --- a/testdata/ignore_errors/Taskfile.yml +++ b/testdata/ignore_errors/Taskfile.yml @@ -1,15 +1,11 @@ -CmdShouldPass: - cmds: - - cmd: UnknownCommandThatNeverWillExist - ignoreError: true -CmdShouldFail: - cmds: - - cmd: UnknownCommandThatNeverWillExist +version: 2 -TaskShouldPass: - cmds: - - task: CmdShouldFail - ignoreError: true -TaskShouldFail: - cmds: - - task: CmdShouldFail \ No newline at end of file +tasks: + cmd-should-pass: + cmds: + - cmd: exit 1 + ignore_error: true + + cmd-should-fail: + cmds: + - cmd: exit 1 \ No newline at end of file From c70343a5bc783cba86e5127058bb4fdb44fb066c Mon Sep 17 00:00:00 2001 From: Andrey Nering Date: Sun, 5 Aug 2018 12:40:11 -0300 Subject: [PATCH 3/6] Handle ignore_error one level up on the code --- internal/execext/exec.go | 24 ++++++++---------------- task.go | 23 ++++++++++++++--------- 2 files changed, 22 insertions(+), 25 deletions(-) diff --git a/internal/execext/exec.go b/internal/execext/exec.go index 4428bd39..f86003bb 100644 --- a/internal/execext/exec.go +++ b/internal/execext/exec.go @@ -13,14 +13,13 @@ import ( // RunCommandOptions is the options for the RunCommand func type RunCommandOptions struct { - Context context.Context - Command string - Dir string - Env []string - Stdin io.Reader - Stdout io.Writer - Stderr io.Writer - IgnoreErrorCode bool + Context context.Context + Command string + Dir string + Env []string + Stdin io.Reader + Stdout io.Writer + Stderr io.Writer } var ( @@ -63,12 +62,5 @@ func RunCommand(opts *RunCommandOptions) error { if err = r.Reset(); err != nil { return err } - if err = r.Run(p); err != nil { - if opts.IgnoreErrorCode { - if _, ok := err.(interp.ExitCode); ok { - return nil - } - } - } - return err + return r.Run(p) } diff --git a/task.go b/task.go index ab62c691..48f98048 100644 --- a/task.go +++ b/task.go @@ -19,6 +19,7 @@ import ( "github.com/Masterminds/semver" "golang.org/x/sync/errgroup" + "mvdan.cc/sh/interp" ) const ( @@ -221,16 +222,20 @@ func (e *Executor) runCommand(ctx context.Context, t *taskfile.Task, call taskfi defer stdOut.Close() defer stdErr.Close() - return execext.RunCommand(&execext.RunCommandOptions{ - Context: ctx, - Command: cmd.Cmd, - Dir: t.Dir, - Env: getEnviron(t), - Stdin: e.Stdin, - Stdout: stdOut, - Stderr: stdErr, - IgnoreErrorCode: cmd.IgnoreError, + err := execext.RunCommand(&execext.RunCommandOptions{ + Context: ctx, + Command: cmd.Cmd, + Dir: t.Dir, + Env: getEnviron(t), + Stdin: e.Stdin, + Stdout: stdOut, + Stderr: stdErr, }) + if _, ok := err.(interp.ExitCode); ok && cmd.IgnoreError { + e.Logger.VerboseErrf("task: command error ignored: %v", err) + return nil + } + return err default: return nil } From feaf70922d0cdd2f7feb931da6eaa507db81e416 Mon Sep 17 00:00:00 2001 From: Andrey Nering Date: Sun, 5 Aug 2018 12:53:42 -0300 Subject: [PATCH 4/6] Allow ignore_error at task level --- internal/taskfile/task.go | 27 ++++++++++++++------------- task.go | 6 ++++++ task_test.go | 20 ++++++++++++++++++++ testdata/ignore_errors/Taskfile.yml | 13 +++++++++++-- variables.go | 23 ++++++++++++----------- 5 files changed, 63 insertions(+), 26 deletions(-) diff --git a/internal/taskfile/task.go b/internal/taskfile/task.go index cf15ea8a..4ebfd5e5 100644 --- a/internal/taskfile/task.go +++ b/internal/taskfile/task.go @@ -5,17 +5,18 @@ type Tasks map[string]*Task // Task represents a task type Task struct { - Task string - Cmds []*Cmd - Deps []*Dep - Desc string - Sources []string - Generates []string - Status []string - Dir string - Vars Vars - Env Vars - Silent bool - Method string - Prefix string + Task string + Cmds []*Cmd + Deps []*Dep + Desc string + Sources []string + Generates []string + Status []string + Dir string + Vars Vars + Env Vars + Silent bool + Method string + Prefix string + IgnoreError bool `yaml:"ignore_error"` } diff --git a/task.go b/task.go index 48f98048..71c7644f 100644 --- a/task.go +++ b/task.go @@ -182,6 +182,12 @@ func (e *Executor) RunTask(ctx context.Context, call taskfile.Call) error { if err2 := statusOnError(t); err2 != nil { e.Logger.VerboseErrf("task: error cleaning status on error: %v", err2) } + + if _, ok := err.(interp.ExitCode); ok && t.IgnoreError { + e.Logger.VerboseErrf("task: task error ignored: %v", err) + continue + } + return &taskRunError{t.Task, err} } } diff --git a/task_test.go b/task_test.go index 84e2d570..d38e4f61 100644 --- a/task_test.go +++ b/task_test.go @@ -416,6 +416,26 @@ func TestTaskVersion(t *testing.T) { func TestTaskIgnoreErrors(t *testing.T) { const dir = "testdata/ignore_errors" + t.Run("task-should-pass", func(t *testing.T) { + e := task.Executor{ + Dir: dir, + Stdout: ioutil.Discard, + Stderr: ioutil.Discard, + } + assert.NoError(t, e.Setup()) + assert.NoError(t, e.Run(taskfile.Call{Task: "task-should-pass"})) + }) + + t.Run("task-should-fail", func(t *testing.T) { + e := task.Executor{ + Dir: dir, + Stdout: ioutil.Discard, + Stderr: ioutil.Discard, + } + assert.NoError(t, e.Setup()) + assert.Error(t, e.Run(taskfile.Call{Task: "task-should-fail"})) + }) + t.Run("cmd-should-pass", func(t *testing.T) { e := task.Executor{ Dir: dir, diff --git a/testdata/ignore_errors/Taskfile.yml b/testdata/ignore_errors/Taskfile.yml index 57d86a6f..1d7dc8b5 100644 --- a/testdata/ignore_errors/Taskfile.yml +++ b/testdata/ignore_errors/Taskfile.yml @@ -1,6 +1,15 @@ -version: 2 +version: '2' tasks: + task-should-pass: + cmds: + - exit 1 + ignore_error: true + + task-should-fail: + cmds: + - exit 1 + cmd-should-pass: cmds: - cmd: exit 1 @@ -8,4 +17,4 @@ tasks: cmd-should-fail: cmds: - - cmd: exit 1 \ No newline at end of file + - cmd: exit 1 diff --git a/variables.go b/variables.go index 17b74759..5968fb7b 100644 --- a/variables.go +++ b/variables.go @@ -24,17 +24,18 @@ func (e *Executor) CompiledTask(call taskfile.Call) (*taskfile.Task, error) { r := templater.Templater{Vars: vars} new := taskfile.Task{ - Task: origTask.Task, - Desc: r.Replace(origTask.Desc), - Sources: r.ReplaceSlice(origTask.Sources), - Generates: r.ReplaceSlice(origTask.Generates), - Status: r.ReplaceSlice(origTask.Status), - Dir: r.Replace(origTask.Dir), - Vars: nil, - Env: r.ReplaceVars(origTask.Env), - Silent: origTask.Silent, - Method: r.Replace(origTask.Method), - Prefix: r.Replace(origTask.Prefix), + Task: origTask.Task, + Desc: r.Replace(origTask.Desc), + Sources: r.ReplaceSlice(origTask.Sources), + Generates: r.ReplaceSlice(origTask.Generates), + Status: r.ReplaceSlice(origTask.Status), + Dir: r.Replace(origTask.Dir), + Vars: nil, + Env: r.ReplaceVars(origTask.Env), + Silent: origTask.Silent, + Method: r.Replace(origTask.Method), + Prefix: r.Replace(origTask.Prefix), + IgnoreError: origTask.IgnoreError, } new.Dir, err = shell.Expand(new.Dir, nil) if err != nil { From 76253bf516b2009c5889bbddaee6dec6744d1408 Mon Sep 17 00:00:00 2001 From: Andrey Nering Date: Sun, 5 Aug 2018 12:56:55 -0300 Subject: [PATCH 5/6] Reduce code duplication on test --- task_test.go | 48 ++++++++++-------------------------------------- 1 file changed, 10 insertions(+), 38 deletions(-) diff --git a/task_test.go b/task_test.go index d38e4f61..58687cab 100644 --- a/task_test.go +++ b/task_test.go @@ -416,45 +416,17 @@ func TestTaskVersion(t *testing.T) { func TestTaskIgnoreErrors(t *testing.T) { const dir = "testdata/ignore_errors" - t.Run("task-should-pass", func(t *testing.T) { - e := task.Executor{ - Dir: dir, - Stdout: ioutil.Discard, - Stderr: ioutil.Discard, - } - assert.NoError(t, e.Setup()) - assert.NoError(t, e.Run(taskfile.Call{Task: "task-should-pass"})) - }) + e := task.Executor{ + Dir: dir, + Stdout: ioutil.Discard, + Stderr: ioutil.Discard, + } + assert.NoError(t, e.Setup()) - t.Run("task-should-fail", func(t *testing.T) { - e := task.Executor{ - Dir: dir, - Stdout: ioutil.Discard, - Stderr: ioutil.Discard, - } - assert.NoError(t, e.Setup()) - assert.Error(t, e.Run(taskfile.Call{Task: "task-should-fail"})) - }) - - t.Run("cmd-should-pass", func(t *testing.T) { - e := task.Executor{ - Dir: dir, - Stdout: ioutil.Discard, - Stderr: ioutil.Discard, - } - assert.NoError(t, e.Setup()) - assert.NoError(t, e.Run(taskfile.Call{Task: "cmd-should-pass"})) - }) - - t.Run("cmd-should-fail", func(t *testing.T) { - e := task.Executor{ - Dir: dir, - Stdout: ioutil.Discard, - Stderr: ioutil.Discard, - } - assert.NoError(t, e.Setup()) - assert.Error(t, e.Run(taskfile.Call{Task: "cmd-should-fail"})) - }) + assert.NoError(t, e.Run(taskfile.Call{Task: "task-should-pass"})) + assert.Error(t, e.Run(taskfile.Call{Task: "task-should-fail"})) + assert.NoError(t, e.Run(taskfile.Call{Task: "cmd-should-pass"})) + assert.Error(t, e.Run(taskfile.Call{Task: "cmd-should-fail"})) } func TestExpand(t *testing.T) { From a04cf100b4bc27d885fdd0b1fe1703279459df29 Mon Sep 17 00:00:00 2001 From: Andrey Nering Date: Sun, 5 Aug 2018 13:01:30 -0300 Subject: [PATCH 6/6] Improve README a bit --- README.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index e2bbd19a..46d76157 100644 --- a/README.md +++ b/README.md @@ -655,8 +655,8 @@ tasks: - echo "Hello World" ``` -Task will abort the execution after running `exit 1` because the status code `1` stands for `EXIT_FAILURE`. -However it is possible to continue with execution using `ignore_errors`: +Task will abort the execution after running `exit 1` because the status code `1` stands for `EXIT_FAILURE`. +However it is possible to continue with execution using `ignore_error`: ```yml version: '2' @@ -665,10 +665,14 @@ tasks: echo: cmds: - cmd: exit 1 - ignore_errors: true + ignore_error: true - echo "Hello World" ``` +`ignore_error` can also be set for a task, which mean errors will be supressed +for all commands. But keep in mind this option won't propagate to other tasks +called either by `deps` or `cmds`! + ## Output syntax By default, Task just redirect the STDOUT and STDERR of the running commands