Skip to content

Commit d6c1855

Browse files
committed
Add CHANGELOG, documentation and small improvements to #626
1 parent fd9132c commit d6c1855

File tree

4 files changed

+45
-6
lines changed

4 files changed

+45
-6
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
## Unreleased
44

5+
- It's now possible to schedule cleanup commands to run once a task finishes
6+
with the `defer:` keyword
7+
([Documentation](https://taskfile.dev/#/usage?id=doing-task-cleanup-with-defer), [#475](https://github.com/go-task/task/issues/475), [#626](https://github.com/go-task/task/pull/626/files)).
58
- Remove long deprecated and undocumented `$` variable prefix and `^` command
69
prefix
710
([#642](https://github.com/go-task/task/issues/642), [#644](https://github.com/go-task/task/issues/644), [#645](https://github.com/go-task/task/pull/645)).

docs/usage.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -608,6 +608,45 @@ tasks:
608608
- yarn {{.CLI_ARGS}}
609609
```
610610

611+
## Doing task cleanup with `defer`
612+
613+
With the `defer` keyword, it's possible to schedule cleanup to be run once
614+
the task finishes. The difference with just putting it as the last command is
615+
that this command will run even when the task fails.
616+
617+
In the example below `rm -rf tmpdir/` will run even if the third command fails:
618+
619+
```yaml
620+
version: '3'
621+
622+
tasks:
623+
default:
624+
cmds:
625+
- mkdir -p tmpdir/
626+
- defer: rm -rf tmpdir/
627+
- echo 'Do work on tmpdir/'
628+
```
629+
630+
If you want to move the cleanup command into another task, that's possible as
631+
well:
632+
633+
```yaml
634+
version: '3'
635+
636+
tasks:
637+
default:
638+
cmds:
639+
- mkdir -p tmpdir/
640+
- defer: { task: cleanup }
641+
- echo 'Do work on tmpdir/'
642+
643+
cleanup: rm -rf tmpdir/
644+
```
645+
646+
> NOTE: Due to the nature of how the
647+
[Go's own `defer` work](https://go.dev/tour/flowcontrol/13), the deferred
648+
commands are executed in the reverse order if you schedule multiple of them.
649+
611650
## Go's template engine
612651

613652
Task parse commands as [Go's template engine][gotemplate] before executing

task.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import (
88
"os"
99
"sync"
1010
"sync/atomic"
11-
"time"
1211

1312
"github.com/go-task/task/v3/internal/compiler"
1413
compilerv2 "github.com/go-task/task/v3/internal/compiler/v2"
@@ -402,8 +401,9 @@ func (e *Executor) runDeps(ctx context.Context, t *taskfile.Task) error {
402401
}
403402

404403
func (e *Executor) runDeferred(t *taskfile.Task, call taskfile.Call, i int) {
405-
ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
404+
ctx, cancel := context.WithCancel(context.Background())
406405
defer cancel()
406+
407407
if err := e.runCommand(ctx, t, call, i); err != nil {
408408
e.Logger.VerboseErrf(logger.Yellow, `task: ignored error in deferred cmd: %s`, err.Error())
409409
}

taskfile/cmd.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,7 @@ func (c *Cmd) UnmarshalYAML(unmarshal func(interface{}) error) error {
4343
return nil
4444
}
4545
var deferredCall struct {
46-
Defer struct {
47-
Task string
48-
Vars *Vars
49-
}
46+
Defer Call
5047
}
5148
if err := unmarshal(&deferredCall); err == nil && deferredCall.Defer.Task != "" {
5249
c.Defer = true

0 commit comments

Comments
 (0)