watchman/client/main.go

147 lines
2.9 KiB
Go
Executable File

package main
import (
"flag"
"fmt"
"local/watchman/client/remote"
"local/watchman/client/watchman"
"log"
"os"
"os/signal"
)
func envOrDefault(key, alt string) string {
if v := os.Getenv(key); v != "" {
return v
}
log.Printf("ENV variable %q not set, defaulting to %q", key, alt)
return alt
}
var defaultKey = envOrDefault("WATCHMANKEY", "key")
var defaultID = envOrDefault("WATCHMANID", "ID")
type empty struct{}
func catchInterrupt() chan os.Signal {
stop := make(chan os.Signal)
signal.Notify(stop, os.Interrupt)
return stop
}
func main() {
stopWatch := make(chan empty)
fnames := make(chan string)
packs := make(chan *watchman.Package)
pullPath := flag.String("path", "", "path to pull")
flag.Parse()
if *pullPath != "" {
go packPuller(packs, stopWatch)
packs <- &watchman.Package{Path: *pullPath}
stopWatch <- empty{}
return
}
log.Print("Watching for changes...")
go watchFiles("testdir", fnames, stopWatch)
log.Print("Packing changes...")
go filePacker(packs, fnames, stopWatch)
log.Print("Pushing changes...")
go packPusher(packs, stopWatch)
log.Print("Waiting for signal...")
<-catchInterrupt()
for i := 0; i < 3; i++ {
stopWatch <- empty{}
}
fmt.Println()
log.Print("Exiting")
}
func packPuller(packs <-chan *watchman.Package, stop <-chan empty) {
rem, err := remote.New()
if err != nil {
log.Fatal("can't connect to remote:", err)
}
exiting := false
for !exiting {
select {
case pack := <-packs:
pack.ID = defaultID
backpack, err := rem.Pull(pack)
if err != nil {
log.Print("error pulling:", err)
break
}
if backpack == nil {
break
}
decrypted, err := watchman.UnpackNDecrypt(backpack, defaultKey)
if err != nil {
log.Print("error unpacking and decrypting:", err)
break
}
log.Print(string(decrypted))
case <-stop:
exiting = true
}
}
}
func packPusher(packs <-chan *watchman.Package, stop <-chan empty) {
rem, err := remote.New()
if err != nil {
log.Fatal("can't connect to remote:", err)
}
exiting := false
for !exiting {
select {
case pack := <-packs:
if err := rem.Push(pack); err != nil {
log.Print("error pushing:", err)
}
case <-stop:
exiting = true
}
}
}
func filePacker(packs chan<- *watchman.Package, fnames <-chan string, stop <-chan empty) {
exiting := false
for !exiting {
select {
case fname := <-fnames:
pack, err := watchman.EncryptNPack(fname, defaultKey, defaultID)
if err != nil {
log.Printf("err packingNencrypting file %q: %v", fname, err)
break
}
packs <- pack
case <-stop:
exiting = true
}
}
}
func watchFiles(path string, fnames chan<- string, stop <-chan empty) {
watcher := watchman.NewWatcher(path)
if err := watcher.Start(); err != nil {
panic(err)
}
exiting := false
for !exiting {
select {
case fname := <-watcher.Files:
fnames <- fname
case <-stop:
exiting = true
watcher.Stop()
return
}
}
}