package main import ( "flag" "os" "path" "path/filepath" "time" logger "git.site.quack-lab.dev/dave/cylogger" "github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5/plumbing/object" ) var ROOT string func main() { scanIntervalF := flag.String("interval", "2s", "scan interval") flag.Parse() scanInterval, err := time.ParseDuration(*scanIntervalF) if err != nil { logger.Error("error parsing SCAN_INTERVAL: %v", err) return } cwd, err := os.Getwd() if err != nil { logger.Error("error getting cwd: %v", err) return } ROOT = path.Clean(cwd) ROOT, err = filepath.Abs(ROOT) if err != nil { logger.Error("error getting absolute path for ROOT: %v", err) return } logger.Info("Input args parsed as:") logger.Info("ROOT: %s", ROOT) logger.Info("SCAN_INTERVAL: %.0fs", scanInterval.Seconds()) for { logger.Info("Running at %s", time.Now().Format(time.RFC3339)) doRun() time.Sleep(scanInterval) } } func doRun() { // Open the repository r, err := git.PlainOpen(ROOT) if err != nil { // If the repository does not exist, create it if err == git.ErrRepositoryNotExists { r, err = git.PlainInit(ROOT, false) // Initialize a new repository if err != nil { logger.Error("Error creating repository: %v", err) return } logger.Info("New repository created at: %s", ROOT) // Create .gitignore file gitignorePath := filepath.Join(ROOT, ".gitignore") if err := os.WriteFile(gitignorePath, []byte("*.log\n"), 0644); err != nil { logger.Error("Error creating .gitignore: %v", err) return } // Get the worktree for initial commit w, err := r.Worktree() if err != nil { logger.Error("Error getting worktree: %v", err) return } // Add .gitignore if _, err := w.Add(".gitignore"); err != nil { logger.Error("Error adding .gitignore: %v", err) return } // Create initial commit if _, err := w.Commit("Initial commit", &git.CommitOptions{ Author: &object.Signature{ Name: "system", Email: "system@localhost", When: time.Now(), }, }); err != nil { logger.Error("Error creating initial commit: %v", err) return } logger.Info("Initial commit created with .gitignore") return } else { logger.Error("Error opening repository: %v", err) return } } // Get the worktree w, err := r.Worktree() if err != nil { logger.Error("Error getting worktree: %v", err) return } // Check status status, err := w.Status() if err != nil { logger.Error("Error getting status: %v", err) return } if status.IsClean() { logger.Info("Nothing to commit") return } // Count changes by type var added, modified, deleted int for _, s := range status { switch s.Worktree { case git.Modified: modified++ case git.Added: added++ case git.Deleted: deleted++ } } logger.Info("Changes detected: %d added, %d modified, %d deleted", added, modified, deleted) // Add all changes err = w.AddWithOptions(&git.AddOptions{All: true}) if err != nil { logger.Error("Error adding changes: %v", err) return } logger.Info("Changes added to index") // Set identity err = setIdentity(r) if err != nil { logger.Error("Error setting identity: %v", err) return } // Get current branch head, err := r.Head() if err != nil { logger.Error("Error getting HEAD: %v", err) return } // Commit changes commit, err := w.Commit("Update", &git.CommitOptions{ Author: &object.Signature{ Name: "system", Email: "system@localhost", When: time.Now(), }, }) if err != nil { logger.Error("Error committing changes: %v", err) return } // Get commit details commitObj, err := r.CommitObject(commit) if err != nil { logger.Error("Error getting commit details: %v", err) return } logger.Info("Changes committed successfully:") logger.Info(" Branch: %s", head.Name().Short()) logger.Info(" Commit: %s", commitObj.Hash.String()) logger.Info(" Author: %s <%s>", commitObj.Author.Name, commitObj.Author.Email) logger.Info(" Date: %s", commitObj.Author.When.Format(time.RFC3339)) logger.Info(" Message: %s", commitObj.Message) } func setIdentity(r *git.Repository) error { cfg, err := r.Config() if err != nil { return err } cfg.User.Name = "system" cfg.User.Email = "system@localhost" return r.SetConfig(cfg) }