-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcode-notify.go
159 lines (135 loc) · 3.76 KB
/
code-notify.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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
package main
import (
"bytes"
"fmt"
"log"
"os"
"os/exec"
"path"
"path/filepath"
"regexp"
"runtime"
"strings"
"time"
"code.revolvingcow.com/revolvingcow/code/cmd"
)
// Main entry point for the application.
func main() {
// Configure any environment variables that may need to be applied
cmd.ConfigureEnvironment()
// Find the root directory to start the hunt
root := cmd.GetWorkingDirectory()
if len(os.Args[1:]) > 0 {
root = os.Args[1:][0]
}
// Loop through the repositories on an interval
interval := 15 * time.Minute
doEvery(interval, func() {
c := hunter(root)
for m := range c {
gatherer(m)
}
})
}
// Repeat a piece of logic on an interval
func doEvery(d time.Duration, f func()) {
log.Println("Execution scheduled every", d)
for _ = range time.Tick(d) {
log.Println("Scanning repositories for incoming changesets...")
f()
}
}
// Walk the directory tree in search of version control repositories.
func hunter(root string) chan string {
c := make(chan string)
search := fmt.Sprintf(".%s", strings.Join(cmd.GetVersionControlSystems(), "."))
go func() {
filepath.Walk(root, func(p string, fi os.FileInfo, e error) error {
// If there is an error already present then pass it along
if e != nil {
return e
}
if fi.IsDir() {
name := fi.Name()
// Look for hidden directories
if strings.HasPrefix(name, ".") {
// If the directory belongs to a VCS then pass the message along
if strings.Contains(search, name) {
c <- p
}
// Skip all hidden directories regardless if they harbor version control information
return filepath.SkipDir
}
}
return nil
})
defer close(c)
}()
return c
}
// Gather the information from the repositories and determine how many incoming changesets are available.
// Post an environment aware notification for repositories with pending changesets.
func gatherer(directory string) {
repo := path.Dir(directory)
// Execute the appropriate subcommand for `incoming`
var buffer bytes.Buffer
app := &cmd.App{
Args: []string{"incoming"},
Directory: repo,
Stdout: &buffer,
}
err := app.Run()
if err == nil {
base := path.Base(directory)
b := buffer.String()
// Special logic to count the individual changesets
var re *regexp.Regexp
switch {
case base == ".git":
re = regexp.MustCompile("commit")
break
case base == ".hg":
re = regexp.MustCompile("changeset")
break
case base == ".tf":
re = regexp.MustCompile("[\r\n]([0-9]+)")
break
case base == ".bzr":
re = regexp.MustCompile("commit")
break
}
count := len(re.FindAllString(b, -1))
if count > 0 {
a := []string{}
// Log to standard output
log.Println("Repository found at", path.Base(repo), "with", count, "incoming changes")
// Build an array for command execuation based on the environment
switch runtime.GOOS {
case "darwin":
a = append(a, "growlnotify")
a = append(a, "-n")
a = append(a, "code-notify")
a = append(a, "-m")
a = append(a, fmt.Sprintf("%s: incoming changeset(s)", path.Base(repo)))
a = append(a, fmt.Sprintf("%d changesets upstream\n\nDirectory:\n%s", count, repo))
break
case "linux":
a = append(a, "notify-send")
a = append(a, "-a")
a = append(a, "code-notify")
a = append(a, fmt.Sprintf("%s: incoming changeset(s)", path.Base(repo)))
a = append(a, fmt.Sprintf("%d changesets upstream\n\nDirectory:\n%s", count, repo))
break
case "windows":
a = append(a, "growlnotify")
a = append(a, "/t:")
a = append(a, fmt.Sprintf("%s: incoming changeset(s)", path.Base(repo)))
a = append(a, fmt.Sprintf("%d changesets upstream\n\nDirectory:\n%s", count, repo))
break
}
// Send the notification to the system
cmd := exec.Command(a[0], a[1:]...)
cmd.Run()
}
}
}