forked from dshills/goauto
-
Notifications
You must be signed in to change notification settings - Fork 0
/
workflow.go
116 lines (105 loc) · 2.66 KB
/
workflow.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
// Copyright 2015 Davin Hills. All rights reserved.
// MIT license. License details can be found in the LICENSE file.
package goauto
import (
"fmt"
"regexp"
"time"
)
// A Workflow represents a set of tasks for files matching one or more regex patterns
type Workflow struct {
Name string
Concurrent bool
Op Op
Regexs []*regexp.Regexp
Tasks []Tasker
}
// NewWorkflow returns a Workflow with tasks
func NewWorkflow(tasks ...Tasker) *Workflow {
wf := new(Workflow)
wf.WatchOp(Create | Write | Remove | Rename)
wf.Add(tasks...)
return wf
}
// WatchPattern adds one or more regex for matching files for this workflow
// An invalid regexp pattern will return an error
// Sets file operations to Create|Write|Remove|Rename if not set
func (wf *Workflow) WatchPattern(patterns ...string) error {
if wf.Op == 0 {
wf.WatchOp(Create | Write | Remove | Rename)
}
for _, p := range patterns {
r, err := regexp.Compile(p)
if err != nil {
return err
}
wf.Regexs = append(wf.Regexs, r)
}
return nil
}
// WatchOp sets the file operations to match
// The default is Create | Write | Remove | Rename
func (wf *Workflow) WatchOp(op Op) {
wf.Op = op
}
func (wf *Workflow) matchOp(op Op) bool {
switch {
case wf.Op&Create == op&Create:
return true
case wf.Op&Write == op&Write:
return true
case wf.Op&Remove == op&Remove:
return true
case wf.Op&Rename == op&Rename:
return true
case wf.Op&Chmod == op&Chmod:
return true
}
return false
}
// Match checks a file name against the regexp of the Workflow and the file operation
func (wf *Workflow) Match(fpath string, op Op) bool {
if wf.matchOp(op) {
for _, r := range wf.Regexs {
if r.MatchString(fpath) {
return true
}
}
}
return false
}
// Add adds a task to the workflow
func (wf *Workflow) Add(tasks ...Tasker) {
for _, t := range tasks {
wf.Tasks = append(wf.Tasks, t)
}
}
func (wf *Workflow) runner(info *TaskInfo) {
if info.Verbose {
fmt.Fprintf(info.Tout, ">> %v %v for %v\n\n", time.Now().Format("2006/01/02 3:04pm"), wf.Name, info.Src)
}
fname := info.Src
info.Collect = []string{fname}
var err error
for _, t := range wf.Tasks {
info.Target = "" // reset the Target
if err = t.Run(info); err != nil {
fmt.Fprintln(info.Terr, err)
fmt.Fprintf(info.Terr, "Fail! Workflow %v did not complete for %v\n\n\n", wf.Name, fname)
return
}
if info.Target != "" {
// if the task set a target use it for the Src in the next task
info.Src = info.Target
info.Collect = append(info.Collect, info.Target)
}
}
}
// Run will start the execution of tasks
func (wf *Workflow) Run(info *TaskInfo) {
if wf.Concurrent {
go wf.runner(info)
return
}
wf.runner(info)
}