mirror of
				https://github.com/go-task/task.git
				synced 2025-10-30 23:58:01 +02:00 
			
		
		
		
	Merge branch 'Eun-master'
This commit is contained in:
		
							
								
								
									
										33
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										33
									
								
								README.md
									
									
									
									
									
								
							| @@ -640,6 +640,39 @@ tasks: | ||||
| Dry run mode (`--dry`) compiles and steps through each task, printing the commands | ||||
| that would be run without executing them. This is useful for debugging your Taskfiles. | ||||
|  | ||||
| ## 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_error`: | ||||
|  | ||||
| ```yml | ||||
| version: '2' | ||||
|  | ||||
| tasks: | ||||
|   echo: | ||||
|     cmds: | ||||
|       - cmd: exit 1 | ||||
|         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 | ||||
|   | ||||
| @@ -7,10 +7,11 @@ 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 | ||||
| @@ -38,12 +39,14 @@ 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:"ignore_error"` | ||||
| 	} | ||||
| 	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 { | ||||
|   | ||||
| @@ -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"` | ||||
| } | ||||
|   | ||||
							
								
								
									
										14
									
								
								task.go
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								task.go
									
									
									
									
									
								
							| @@ -19,6 +19,7 @@ import ( | ||||
|  | ||||
| 	"github.com/Masterminds/semver" | ||||
| 	"golang.org/x/sync/errgroup" | ||||
| 	"mvdan.cc/sh/interp" | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| @@ -181,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} | ||||
| 		} | ||||
| 	} | ||||
| @@ -221,7 +228,7 @@ func (e *Executor) runCommand(ctx context.Context, t *taskfile.Task, call taskfi | ||||
| 		defer stdOut.Close() | ||||
| 		defer stdErr.Close() | ||||
|  | ||||
| 		return execext.RunCommand(&execext.RunCommandOptions{ | ||||
| 		err := execext.RunCommand(&execext.RunCommandOptions{ | ||||
| 			Context: ctx, | ||||
| 			Command: cmd.Cmd, | ||||
| 			Dir:     t.Dir, | ||||
| @@ -230,6 +237,11 @@ func (e *Executor) runCommand(ctx context.Context, t *taskfile.Task, call taskfi | ||||
| 			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 | ||||
| 	} | ||||
|   | ||||
							
								
								
									
										17
									
								
								task_test.go
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								task_test.go
									
									
									
									
									
								
							| @@ -53,7 +53,6 @@ func (fct fileContentTest) Run(t *testing.T) { | ||||
| 			assert.Equal(t, expectContent, s, "unexpected file content") | ||||
| 		}) | ||||
| 	} | ||||
|  | ||||
| } | ||||
|  | ||||
| func TestEnv(t *testing.T) { | ||||
| @@ -414,6 +413,22 @@ func TestTaskVersion(t *testing.T) { | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestTaskIgnoreErrors(t *testing.T) { | ||||
| 	const dir = "testdata/ignore_errors" | ||||
|  | ||||
| 	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"})) | ||||
| 	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) { | ||||
| 	const dir = "testdata/expand" | ||||
|  | ||||
|   | ||||
							
								
								
									
										20
									
								
								testdata/ignore_errors/Taskfile.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								testdata/ignore_errors/Taskfile.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,20 @@ | ||||
| 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 | ||||
|         ignore_error: true | ||||
|  | ||||
|   cmd-should-fail: | ||||
|     cmds: | ||||
|       - cmd: exit 1 | ||||
							
								
								
									
										33
									
								
								variables.go
									
									
									
									
									
								
							
							
						
						
									
										33
									
								
								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 { | ||||
| @@ -58,12 +59,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 { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user