diff --git a/internal/taskfile/task.go b/internal/taskfile/task.go index 1afcbfa3..a686f04b 100644 --- a/internal/taskfile/task.go +++ b/internal/taskfile/task.go @@ -1,5 +1,8 @@ package taskfile +import "os" +import "sync" + // Tasks represents a group of tasks type Tasks map[string]*Task @@ -14,6 +17,7 @@ type Task struct { Generates []string Status []string Dir string + mkdirMutex sync.Mutex Vars Vars Env Vars Silent bool @@ -21,3 +25,22 @@ type Task struct { Prefix string IgnoreError bool `yaml:"ignore_error"` } + +// Mkdir creates the directory Task.Dir. +// Safe to be called concurrently. +func (t *Task) Mkdir() error { + if t.Dir == "" { + // No "dir:" attribute, so we do nothing. + return nil + } + + t.mkdirMutex.Lock() + defer t.mkdirMutex.Unlock() + + if _, err := os.Stat(t.Dir); os.IsNotExist(err) { + if err := os.MkdirAll(t.Dir, 0755); err != nil { + return err + } + } + return nil +} diff --git a/task.go b/task.go index 9789cf35..bca22c4d 100644 --- a/task.go +++ b/task.go @@ -202,13 +202,8 @@ func (e *Executor) RunTask(ctx context.Context, call taskfile.Call) error { // When using the "dir:" attribute it can happen that the directory doesn't exist. // If so, we create it. - if t.Dir != "" { - if _, err := os.Stat(t.Dir); os.IsNotExist(err) { - if err := os.MkdirAll(t.Dir, 0755); err != nil { - e.Logger.Errf("task: cannot make directory %q: %v", t.Dir, err) - return err - } - } + if err := t.Mkdir(); err != nil { + e.Logger.Errf("task: cannot make directory %q: %v", t.Dir, err) } for i := range t.Cmds {