@@ -11,6 +11,8 @@ import (
11
11
"sync/atomic"
12
12
"time"
13
13
14
+ "mvdan.cc/sh/v3/interp"
15
+
14
16
"github.com/go-task/task/v3/errors"
15
17
"github.com/go-task/task/v3/internal/compiler"
16
18
"github.com/go-task/task/v3/internal/env"
@@ -247,9 +249,11 @@ func (e *Executor) RunTask(ctx context.Context, call *ast.Call) error {
247
249
e .Logger .Errf (logger .Red , "task: cannot make directory %q: %v\n " , t .Dir , err )
248
250
}
249
251
252
+ var deferredExitCode uint8
253
+
250
254
for i := range t .Cmds {
251
255
if t .Cmds [i ].Defer {
252
- defer e .runDeferred (t , call , i )
256
+ defer e .runDeferred (t , call , i , & deferredExitCode )
253
257
continue
254
258
}
255
259
@@ -258,9 +262,13 @@ func (e *Executor) RunTask(ctx context.Context, call *ast.Call) error {
258
262
e .Logger .VerboseErrf (logger .Yellow , "task: error cleaning status on error: %v\n " , err2 )
259
263
}
260
264
261
- if execext .IsExitError (err ) && t .IgnoreError {
262
- e .Logger .VerboseErrf (logger .Yellow , "task: task error ignored: %v\n " , err )
263
- continue
265
+ exitCode , isExitError := interp .IsExitStatus (err )
266
+ if isExitError {
267
+ if t .IgnoreError {
268
+ e .Logger .VerboseErrf (logger .Yellow , "task: task error ignored: %v\n " , err )
269
+ continue
270
+ }
271
+ deferredExitCode = exitCode
264
272
}
265
273
266
274
if call .Indirect {
@@ -312,10 +320,21 @@ func (e *Executor) runDeps(ctx context.Context, t *ast.Task) error {
312
320
return g .Wait ()
313
321
}
314
322
315
- func (e * Executor ) runDeferred (t * ast.Task , call * ast.Call , i int ) {
323
+ func (e * Executor ) runDeferred (t * ast.Task , call * ast.Call , i int , deferredExitCode * uint8 ) {
316
324
ctx , cancel := context .WithCancel (context .Background ())
317
325
defer cancel ()
318
326
327
+ cmd := t .Cmds [i ]
328
+ vars , _ := e .Compiler .FastGetVariables (t , call )
329
+ cache := & templater.Cache {Vars : vars }
330
+ extra := map [string ]any {}
331
+
332
+ if deferredExitCode != nil && * deferredExitCode > 0 {
333
+ extra ["EXIT_CODE" ] = fmt .Sprintf ("%d" , * deferredExitCode )
334
+ }
335
+
336
+ cmd .Cmd = templater .ReplaceWithExtra (cmd .Cmd , cache , extra )
337
+
319
338
if err := e .runCommand (ctx , t , call , i ); err != nil {
320
339
e .Logger .VerboseErrf (logger .Yellow , "task: ignored error in deferred cmd: %s\n " , err .Error ())
321
340
}
@@ -372,7 +391,7 @@ func (e *Executor) runCommand(ctx context.Context, t *ast.Task, call *ast.Call,
372
391
if closeErr := close (err ); closeErr != nil {
373
392
e .Logger .Errf (logger .Red , "task: unable to close writer: %v\n " , closeErr )
374
393
}
375
- if execext . IsExitError (err ) && cmd .IgnoreError {
394
+ if _ , isExitError := interp . IsExitStatus (err ); isExitError && cmd .IgnoreError {
376
395
e .Logger .VerboseErrf (logger .Yellow , "task: [%s] command error ignored: %v\n " , t .Name (), err )
377
396
return nil
378
397
}
0 commit comments