No Description

code-notify.go 3.8KB

    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 := 1 * 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() } } }