From feaf70922d0cdd2f7feb931da6eaa507db81e416 Mon Sep 17 00:00:00 2001 From: Andrey Nering Date: Sun, 5 Aug 2018 12:53:42 -0300 Subject: [PATCH] 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 {