diff --git a/cmd/task/task.go b/cmd/task/task.go index 20e4d612..6fa404e3 100644 --- a/cmd/task/task.go +++ b/cmd/task/task.go @@ -68,6 +68,7 @@ func main() { silent bool dry bool summary bool + carryErr bool parallel bool concurrency int dir string @@ -89,6 +90,7 @@ func main() { pflag.BoolVarP(¶llel, "parallel", "p", false, "executes tasks provided on command line in parallel") pflag.BoolVar(&dry, "dry", false, "compiles and prints tasks in the order that they would be run, without executing them") pflag.BoolVar(&summary, "summary", false, "show summary about a task") + pflag.BoolVar(&carryErr, "carry", false, "carry error code if any") pflag.StringVarP(&dir, "dir", "d", "", "sets directory of execution") pflag.StringVarP(&entrypoint, "taskfile", "t", "", `choose which Taskfile to run. Defaults to "Taskfile.yml"`) pflag.StringVarP(&output.Name, "output", "o", "", "sets output style: [interleaved|group|prefixed]") @@ -216,7 +218,13 @@ func main() { if err := e.Run(ctx, calls...); err != nil { e.Logger.Errf(logger.Red, "%v", err) - os.Exit(1) + code := 1 + if carryErr { + if tre, ok := err.(*task.TaskRunError); ok { + code = tre.ExitCode() + } + } + os.Exit(code) } } diff --git a/errors.go b/errors.go index a12df253..e2aa16b0 100644 --- a/errors.go +++ b/errors.go @@ -3,6 +3,7 @@ package task import ( "errors" "fmt" + "mvdan.cc/sh/v3/interp" ) var ( @@ -18,15 +19,23 @@ func (err *taskNotFoundError) Error() string { return fmt.Sprintf(`task: Task "%s" not found`, err.taskName) } -type taskRunError struct { +type TaskRunError struct { taskName string err error } -func (err *taskRunError) Error() string { +func (err *TaskRunError) Error() string { return fmt.Sprintf(`task: Failed to run task "%s": %v`, err.taskName, err.err) } +func (err *TaskRunError) ExitCode() int { + if c, ok := interp.IsExitStatus(err.err); ok { + return int(c) + } + + return 1 +} + // MaximumTaskCallExceededError is returned when a task is called too // many times. In this case you probably have a cyclic dependendy or // infinite loop diff --git a/task.go b/task.go index ec224260..6714d8e3 100644 --- a/task.go +++ b/task.go @@ -363,7 +363,7 @@ func (e *Executor) RunTask(ctx context.Context, call taskfile.Call) error { continue } - return &taskRunError{t.Task, err} + return &TaskRunError{t.Task, err} } } e.Logger.VerboseErrf(logger.Magenta, `task: "%s" finished`, call.Task) diff --git a/watch.go b/watch.go index 78ca06d9..b93e2d30 100644 --- a/watch.go +++ b/watch.go @@ -88,7 +88,7 @@ func (e *Executor) watchTasks(calls ...taskfile.Call) error { } func isContextError(err error) bool { - if taskRunErr, ok := err.(*taskRunError); ok { + if taskRunErr, ok := err.(*TaskRunError); ok { err = taskRunErr.err }