package main import ( "flag" "fmt" "io" "log" "os" "os/exec" "path" "path/filepath" "time" ) var Error *log.Logger var Warning *log.Logger func init() { log.SetFlags(log.Ldate | log.Ltime) Error = log.New(io.MultiWriter(os.Stderr, os.Stdout), fmt.Sprintf("%sERROR:%s ", "\033[0;101m", "\033[0m"), log.Ldate|log.Ltime) Warning = log.New(io.MultiWriter(os.Stdout), fmt.Sprintf("%sWarning:%s ", "\033[0;93m", "\033[0m"), log.Ldate|log.Ltime) } var ROOT string func main() { scanIntervalF := flag.String("interval", "2s", "scan interval") flag.Parse() log.SetFlags(log.Lmicroseconds) scanInterval, err := time.ParseDuration(*scanIntervalF) if err != nil { Error.Printf("error parsing SCAN_INTERVAL: %v", err) return } cwd, err := os.Getwd() if err != nil { Error.Printf("error getting cwd: %v", err) return } ROOT = path.Clean(cwd) ROOT, err = filepath.Abs(ROOT) if err != nil { Error.Printf("error getting absolute path for ROOT: %v", err) return } log.Printf("Input args parsed as:") log.Printf("ROOT: %s", ROOT) log.Printf("SCAN_INTERVAL: %.0fs", scanInterval.Seconds()) // This shit DOES NOT run correctly on windows // It absolutely butchers CRLF -> LF // And shits the bed // Thinking there are changed files // Making empty commits // And other stupid shit // It does run on unix though for { log.Printf("Running at %s", time.Now().Format(time.RFC3339)) doRun() time.Sleep(scanInterval) } } func doRun() { file, err := os.Open(filepath.Join(ROOT, ".git/index.lock")) if err == nil { log.Printf("Index lock found, removing") file.Close() err = os.Remove(filepath.Join(ROOT, ".git/index.lock")) if err != nil { Error.Printf("Error removing index.lock: %v", err) return } } status, err := doStatus() if err != nil { Error.Printf("Error executing doStatus code %v with out: %v", err, status) return } if status == "" { log.Printf("Nothing to commit") return } log.Printf("Changes detected") res, err := doAddAll() if err != nil { Error.Printf("Error executing doAddAll with code %v and out: %v", err, res) return } log.Printf("Changes added to index: %v", res) res, err = setIdentity() if err != nil { Error.Printf("Error setting identity with code %v and out: %v", err, res) } res, err = doCommit() if err != nil { Error.Printf("Error executing doCommitAll with code %v and out: %v", err, res) return } log.Printf("Changes committed: %v", res) } func doStatus() (string, error) { gitStatus := exec.Command("git", "status", "-s") gitStatus.Dir = ROOT out, err := gitStatus.CombinedOutput() if err != nil { return string(out), err } return string(out), nil } func doAddAll() (string, error) { gitAdd := exec.Command("git", "add", ".") gitAdd.Dir = ROOT out, err := gitAdd.CombinedOutput() if err != nil { return string(out), err } return string(out), nil } func doCommit() (string, error) { gitCommit := exec.Command("git", "commit", "-am", "Update") gitCommit.Dir = ROOT out, err := gitCommit.CombinedOutput() if err != nil { return string(out), err } return string(out), nil } func setIdentity() (string, error) { res, err := setUsername() if err != nil { log.Println("Error executing setUsername:", err) return string(res), err } res, err = setEmail() if err != nil { log.Println("Error executing setEmail:", err) return string(res), err } return "", nil } func setUsername() (string, error) { gitConfig := exec.Command("git", "config", "user.name", "system") gitConfig.Dir = ROOT out, err := gitConfig.CombinedOutput() if err != nil { return string(out), err } return string(out), nil } func setEmail() (string, error) { gitConfig := exec.Command("git", "config", "user.email", "system@localhost") gitConfig.Dir = ROOT out, err := gitConfig.CombinedOutput() if err != nil { return string(out), err } return string(out), nil }