Files
mindforge/mindforge.cronjob/internal/git/git.go
Jose Henrique 07cacfeb29
All checks were successful
Mindforge Cronjob Build and Deploy / Build Mindforge Cronjob Image (push) Successful in 38s
Mindforge Cronjob Build and Deploy / Deploy Mindforge Cronjob (internal) (push) Successful in 13s
fixing ssh again :)
2026-03-14 11:59:33 -03:00

122 lines
3.2 KiB
Go

package git
import (
"bytes"
"fmt"
"os"
"os/exec"
"strings"
"time"
)
// Service defines the interface for git operations
type Service interface {
CheckConnection(url string) error
FetchContents(url string) error
GetModifications(days int) (map[string]string, error)
}
type gitService struct {
repoDir string
}
// NewGitService creates a new Git service
func NewGitService() Service {
return &gitService{
repoDir: "./cloned_repo",
}
}
func shouldUseSSH() bool {
_, err := os.Stat("/root/.ssh/id_rsa")
return err == nil
}
func (s *gitService) CheckConnection(url string) error {
cmd := exec.Command("git", "ls-remote", url)
if shouldUseSSH() {
cmd.Env = append(os.Environ(), "GIT_SSH_COMMAND=ssh -i /root/.ssh/id_rsa -o StrictHostKeyChecking=no")
}
if err := cmd.Run(); err != nil {
return fmt.Errorf("failed to check git connection: %w", err)
}
fmt.Println("Git connection checked successfully")
return nil
}
func (s *gitService) FetchContents(url string) error {
// Remove the repo directory if it already exists from a previous run
fmt.Println("Removing repo directory")
_ = os.RemoveAll(s.repoDir)
fmt.Println("Cloning repository")
var cmd *exec.Cmd
if shouldUseSSH() {
cmd = exec.Command("git", "clone", url, s.repoDir)
cmd.Env = append(os.Environ(), "GIT_SSH_COMMAND=ssh -i /root/.ssh/id_rsa -o StrictHostKeyChecking=no")
} else {
cmd = exec.Command("git", "clone", url, s.repoDir)
}
var stderr bytes.Buffer
cmd.Stderr = &stderr
if err := cmd.Run(); err != nil {
return fmt.Errorf("failed to fetch contents: %w, stderr: %s", err, stderr.String())
}
fmt.Println("Repository cloned successfully")
return nil
}
func (s *gitService) GetModifications(days int) (map[string]string, error) {
mods := make(map[string]string)
// Determine the commit to diff against (the latest commit *before* 'days' ago)
since := time.Now().AddDate(0, 0, -days).Format(time.RFC3339)
cmdBase := exec.Command("git", "rev-list", "-1", "--before", since, "HEAD")
cmdBase.Dir = s.repoDir
out, err := cmdBase.Output()
baseCommit := strings.TrimSpace(string(out))
if err != nil || baseCommit == "" {
// If there is no commit before 'days' ago, diff against the empty tree
// (this gets all files created in the repository's entire history if it's newer than 'days')
baseCommit = "4b825dc642cb6eb9a060e54bf8d69288fbee4904"
}
// Get the list of modified files between the base commit and HEAD
cmdFiles := exec.Command("git", "diff", "--name-only", baseCommit, "HEAD")
cmdFiles.Dir = s.repoDir
filesOut, err := cmdFiles.Output()
if err != nil {
return nil, fmt.Errorf("failed to get modified files: %w", err)
}
files := strings.Split(strings.TrimSpace(string(filesOut)), "\n")
for _, file := range files {
if file == "" {
continue
}
// Filter only .md files
if !strings.HasSuffix(file, ".md") {
continue
}
// Remove first folder from file path
file = strings.Join(strings.Split(file, "/")[1:], "/")
// Get the specific diff for this file
cmdDiff := exec.Command("git", "diff", baseCommit, "HEAD", "--", file)
cmdDiff.Dir = s.repoDir
diffOut, err := cmdDiff.Output()
if err != nil {
return nil, fmt.Errorf("failed to get diff for file %s: %w", file, err)
}
mods[file] = string(diffOut)
}
return mods, nil
}