initial commit
Marco Andronaco andronacomarco@gmail.com
Fri, 14 Jun 2024 02:25:13 +0200
7 files changed,
136 insertions(+),
0 deletions(-)
A
.env.example
@@ -0,0 +1,3 @@
+REPO_DIR=/var/www/git +GITHUB_USERNAME=user +GITHUB_TOKEN=github_pat_access_token
A
LICENSE
@@ -0,0 +1,21 @@
+MIT License + +Copyright (c) 2024 Marco Andronaco + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE.
A
go.mod
@@ -0,0 +1,5 @@
+module github.com/BiRabittoh/reposync + +go 1.22.4 + +require github.com/joho/godotenv v1.5.1
A
go.sum
@@ -0,0 +1,2 @@
+github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= +github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
A
main.go
@@ -0,0 +1,98 @@
+package main + +import ( + "encoding/json" + "fmt" + "io" + "log" + "net/http" + "os" + "os/exec" + "path/filepath" + + "github.com/joho/godotenv" +) + +type Repo struct { + Name string `json:"name"` + HTMLUrl string `json:"html_url"` +} + +func getRepos(username, token string) ([]Repo, error) { + url := fmt.Sprintf("https://api.github.com/users/%s/repos", username) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return nil, err + } + req.SetBasicAuth(username, token) + + client := &http.Client{} + resp, err := client.Do(req) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + return nil, fmt.Errorf("failed to fetch repositories: %s", resp.Status) + } + + body, err := io.ReadAll(resp.Body) + if err != nil { + return nil, err + } + + var repos []Repo + if err := json.Unmarshal(body, &repos); err != nil { + return nil, err + } + + return repos, nil +} + +func runGitCommand(args ...string) error { + cmd := exec.Command("git", args...) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + return cmd.Run() +} + +func syncRepo(repo Repo, targetDir string) error { + repoPath := filepath.Join(targetDir, repo.Name) + if _, err := os.Stat(repoPath); os.IsNotExist(err) { + fmt.Printf("Cloning repository %s...\n", repo.Name) + return runGitCommand("clone", repo.HTMLUrl, repoPath) + } else { + fmt.Printf("Pulling updates for repository %s...\n", repo.Name) + cmd := exec.Command("git", "-C", repoPath, "pull") + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + return cmd.Run() + } +} + +func main() { + err := godotenv.Load() + if err != nil { + println("Failed to load .env file: %v\n", err) + } + + ghUser := os.Getenv("GITHUB_USERNAME") + ghToken := os.Getenv("GITHUB_TOKEN") + repoDir := os.Getenv("REPO_DIR") + + if ghUser == "" || ghToken == "" || repoDir == "" { + log.Fatalf("GitHub username and token must be provided\n") + } + + repos, err := getRepos(ghUser, ghToken) + if err != nil { + log.Fatalf("Failed to fetch repositories: %v\n", err) + } + + for _, repo := range repos { + if err := syncRepo(repo, repoDir); err != nil { + log.Printf("Failed to sync repository %s: %v\n", repo.Name, err) + } + } +}