|
@ -3,30 +3,142 @@ package main
|
3
|
3
|
import (
|
4
|
4
|
"bytes"
|
5
|
5
|
"fmt"
|
|
6
|
"log"
|
6
|
7
|
"os"
|
|
8
|
"os/exec"
|
|
9
|
"path"
|
7
|
10
|
"path/filepath"
|
|
11
|
"regexp"
|
|
12
|
"runtime"
|
|
13
|
"strings"
|
8
|
14
|
|
9
|
15
|
"code.revolvingcow.com/revolvingcow/code/cmd"
|
10
|
16
|
)
|
11
|
17
|
|
|
18
|
// Main entry point for the application.
|
12
|
19
|
func main() {
|
13
|
|
filepath.Walk(cmd.GetWorkingDirectory(), walk)
|
14
|
|
}
|
|
20
|
cmd.ConfigureEnvironment()
|
15
|
21
|
|
16
|
|
func walk(path string, fileInfo os.FileInfo, e error) error {
|
17
|
|
if e != nil {
|
18
|
|
return e
|
|
22
|
root := cmd.GetWorkingDirectory()
|
|
23
|
if len(os.Args[1:]) > 0 {
|
|
24
|
root = os.Args[1:][0]
|
19
|
25
|
}
|
|
26
|
c := hunter(root)
|
20
|
27
|
|
21
|
|
fmt.Println(path)
|
22
|
|
var buffer bytes.Buffer
|
|
28
|
for m := range c {
|
|
29
|
gatherer(m)
|
|
30
|
}
|
|
31
|
}
|
|
32
|
|
|
33
|
// Walk the directory tree in search of version control repositories.
|
|
34
|
func hunter(root string) chan string {
|
|
35
|
c := make(chan string)
|
|
36
|
search := fmt.Sprintf(".%s", strings.Join(cmd.GetVersionControlSystems(), "."))
|
|
37
|
|
|
38
|
go func() {
|
|
39
|
filepath.Walk(root, func(p string, fi os.FileInfo, e error) error {
|
|
40
|
// If there is an error already present then pass it along
|
|
41
|
if e != nil {
|
|
42
|
return e
|
|
43
|
}
|
|
44
|
|
|
45
|
if fi.IsDir() {
|
|
46
|
name := fi.Name()
|
|
47
|
|
|
48
|
// Look for hidden directories
|
|
49
|
if strings.HasPrefix(name, ".") {
|
|
50
|
// If the directory belongs to a VCS then pass the message along
|
|
51
|
if strings.Contains(search, name) {
|
|
52
|
c <- p
|
|
53
|
}
|
|
54
|
|
|
55
|
// Skip all hidden directories regardless if they harbor version control information
|
|
56
|
return filepath.SkipDir
|
|
57
|
}
|
|
58
|
}
|
|
59
|
|
|
60
|
return nil
|
|
61
|
})
|
|
62
|
|
|
63
|
defer close(c)
|
|
64
|
}()
|
23
|
65
|
|
|
66
|
return c
|
|
67
|
}
|
|
68
|
|
|
69
|
// Gather the information from the repositories and determine how many incoming changesets are available.
|
|
70
|
// Post an environment aware notification for repositories with pending changesets.
|
|
71
|
func gatherer(directory string) {
|
|
72
|
repo := path.Dir(directory)
|
|
73
|
|
|
74
|
// Execute the appropriate subcommand for `incoming`
|
|
75
|
var buffer bytes.Buffer
|
24
|
76
|
app := &cmd.App{
|
25
|
|
Directory: path,
|
26
|
77
|
Args: []string{"incoming"},
|
27
|
|
//Stdout: &buffer,
|
28
|
|
Stderr: &buffer,
|
|
78
|
Directory: repo,
|
|
79
|
Stdout: &buffer,
|
29
|
80
|
}
|
30
|
81
|
|
31
|
|
return app.Run()
|
|
82
|
err := app.Run()
|
|
83
|
if err == nil {
|
|
84
|
count := 0
|
|
85
|
base := path.Base(directory)
|
|
86
|
b := buffer.String()
|
|
87
|
|
|
88
|
// Special logic to count the individual changesets
|
|
89
|
switch {
|
|
90
|
case base == ".git":
|
|
91
|
re := regexp.MustCompile("commit")
|
|
92
|
count = len(re.FindAllString(b, -1))
|
|
93
|
break
|
|
94
|
case base == ".hg":
|
|
95
|
re := regexp.MustCompile("changeset")
|
|
96
|
count = len(re.FindAllString(b, -1))
|
|
97
|
break
|
|
98
|
case base == ".tf":
|
|
99
|
re := regexp.MustCompile("revno")
|
|
100
|
count = len(re.FindAllString(b, -1))
|
|
101
|
break
|
|
102
|
case base == ".bzr":
|
|
103
|
re := regexp.MustCompile("commit")
|
|
104
|
count = len(re.FindAllString(b, -1))
|
|
105
|
break
|
|
106
|
}
|
|
107
|
|
|
108
|
if count > 0 {
|
|
109
|
a := []string{}
|
|
110
|
|
|
111
|
// Log to standard output
|
|
112
|
log.Println("Repository found at", path.Base(repo), "with", count, "incoming changes")
|
|
113
|
|
|
114
|
// Build an array for command execuation based on the environment
|
|
115
|
switch runtime.GOOS {
|
|
116
|
case "darwin":
|
|
117
|
a = append(a, "growlnotify")
|
|
118
|
a = append(a, "-n")
|
|
119
|
a = append(a, "code-notify")
|
|
120
|
a = append(a, "-m")
|
|
121
|
a = append(a, fmt.Sprintf("%s: incoming changeset(s)", path.Base(repo)))
|
|
122
|
a = append(a, fmt.Sprintf("%d changesets upstream\n\nDirectory:\n%s", count, repo))
|
|
123
|
break
|
|
124
|
case "linux":
|
|
125
|
a = append(a, "notify-send")
|
|
126
|
a = append(a, "-a")
|
|
127
|
a = append(a, "code-notify")
|
|
128
|
a = append(a, fmt.Sprintf("%s: incoming changeset(s)", path.Base(repo)))
|
|
129
|
a = append(a, fmt.Sprintf("%d changesets upstream\n\nDirectory:\n%s", count, repo))
|
|
130
|
break
|
|
131
|
case "windows":
|
|
132
|
a = append(a, "growlnotify")
|
|
133
|
a = append(a, "/t:")
|
|
134
|
a = append(a, fmt.Sprintf("%s: incoming changeset(s)", path.Base(repo)))
|
|
135
|
a = append(a, fmt.Sprintf("%d changesets upstream\n\nDirectory:\n%s", count, repo))
|
|
136
|
break
|
|
137
|
}
|
|
138
|
|
|
139
|
// Send the notification to the system
|
|
140
|
cmd := exec.Command(a[0], a[1:]...)
|
|
141
|
cmd.Run()
|
|
142
|
}
|
|
143
|
}
|
32
|
144
|
}
|