main.go (view raw)
1package main
2
3import (
4 "encoding/json"
5 "fmt"
6 "io"
7 "log"
8 "net/http"
9 "os"
10 "os/exec"
11 "path/filepath"
12
13 "github.com/joho/godotenv"
14)
15
16type Repo struct {
17 Name string `json:"name"`
18 HTMLUrl string `json:"html_url"`
19}
20
21func getRepos(username, token string) ([]Repo, error) {
22 url := fmt.Sprintf("https://api.github.com/users/%s/repos", username)
23 req, err := http.NewRequest("GET", url, nil)
24 if err != nil {
25 return nil, err
26 }
27 req.SetBasicAuth(username, token)
28
29 client := &http.Client{}
30 resp, err := client.Do(req)
31 if err != nil {
32 return nil, err
33 }
34 defer resp.Body.Close()
35
36 if resp.StatusCode != http.StatusOK {
37 return nil, fmt.Errorf("failed to fetch repositories: %s", resp.Status)
38 }
39
40 body, err := io.ReadAll(resp.Body)
41 if err != nil {
42 return nil, err
43 }
44
45 var repos []Repo
46 if err := json.Unmarshal(body, &repos); err != nil {
47 return nil, err
48 }
49
50 return repos, nil
51}
52
53func runGitCommand(args ...string) error {
54 cmd := exec.Command("git", args...)
55 cmd.Stdout = os.Stdout
56 cmd.Stderr = os.Stderr
57 return cmd.Run()
58}
59
60func syncRepo(repo Repo, targetDir string) error {
61 repoPath := filepath.Join(targetDir, repo.Name)
62 if _, err := os.Stat(repoPath); os.IsNotExist(err) {
63 fmt.Printf("Cloning repository %s...\n", repo.Name)
64 return runGitCommand("clone", repo.HTMLUrl, repoPath)
65 } else {
66 fmt.Printf("Pulling updates for repository %s...\n", repo.Name)
67 cmd := exec.Command("git", "-C", repoPath, "pull")
68 cmd.Stdout = os.Stdout
69 cmd.Stderr = os.Stderr
70 return cmd.Run()
71 }
72}
73
74func main() {
75 err := godotenv.Load()
76 if err != nil {
77 println("Failed to load .env file: %v\n", err)
78 }
79
80 ghUser := os.Getenv("GITHUB_USERNAME")
81 ghToken := os.Getenv("GITHUB_TOKEN")
82 repoDir := os.Getenv("REPO_DIR")
83
84 if ghUser == "" || ghToken == "" || repoDir == "" {
85 log.Fatalf("GitHub username and token must be provided\n")
86 }
87
88 repos, err := getRepos(ghUser, ghToken)
89 if err != nil {
90 log.Fatalf("Failed to fetch repositories: %v\n", err)
91 }
92
93 for _, repo := range repos {
94 if err := syncRepo(repo, repoDir); err != nil {
95 log.Printf("Failed to sync repository %s: %v\n", repo.Name, err)
96 }
97 }
98}