From 447b138f8b8f989bf66d84a43d7e0f2c50b9ab44 Mon Sep 17 00:00:00 2001 From: Sebastiaan de Schaetzen Date: Thu, 24 Apr 2025 12:00:12 +0200 Subject: [PATCH] Convert to Go --- .idea/.gitignore | 10 +++++++ autobuilder.go | 76 ++++++++++++++++++++++++++++++++++++++++++++++++ autobuilder.py | 45 ---------------------------- gitea.go | 75 +++++++++++++++++++++++++++++++++++++++++++++++ requirements.txt | 1 - 5 files changed, 161 insertions(+), 46 deletions(-) create mode 100644 .idea/.gitignore create mode 100644 autobuilder.go delete mode 100644 autobuilder.py create mode 100644 gitea.go delete mode 100644 requirements.txt diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..7bc07ec --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,10 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Environment-dependent path to Maven home directory +/mavenHomeManager.xml +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/autobuilder.go b/autobuilder.go new file mode 100644 index 0000000..f1037bb --- /dev/null +++ b/autobuilder.go @@ -0,0 +1,76 @@ +package main + +import ( + "fmt" + "log" + "os" + "os/exec" + "path/filepath" +) + +func cloneRepository(repo Repository, workDir string) error { + cmd := exec.Command("git", "clone", repo.CloneURL, filepath.Join(workDir, repo.Name)) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + err := cmd.Run() + if err != nil { + return fmt.Errorf("failed to clone %s: %w", repo.Name, err) + } + return nil +} + +func main() { + token := os.Getenv("TOKEN") + if token == "" { + log.Fatalf("TOKEN environment variable not set") + } + + client := GiteaClient{ + BaseURL: "https://gitea.seeseepuff.be", + Token: token, + } + + org := "archlinux" + workDir := "./work/" + + err := os.RemoveAll(workDir) + if err != nil { + log.Fatalf("failed to remove %s: %v", workDir, err) + } + err = os.MkdirAll(workDir, os.ModePerm) + if err != nil { + log.Fatalf("failed to create %s: %v", workDir, err) + } + + repos, err := client.getRepositories(org) + if err != nil { + log.Fatalf("Failed to get repositories: %v", err) + } + + success := true + for _, repo := range repos { + log.Printf("Checking %s", repo.FullName) + hasFile, err := client.hasPKGBUILD(repo) + + if err != nil { + log.Printf("Error checking for PKGBUILD: %v", err) + success = false + continue + } + + if !hasFile { + log.Println("PKGBUILD not found, skipping") + continue + } + + if err := cloneRepository(repo, workDir); err != nil { + success = false + log.Printf("Error cloning repository: %v", err) + } + + } + + if !success { + os.Exit(1) + } +} diff --git a/autobuilder.py b/autobuilder.py deleted file mode 100644 index 4a54a08..0000000 --- a/autobuilder.py +++ /dev/null @@ -1,45 +0,0 @@ -import gitea as gt -import os -import subprocess -import shutil - -class BadEncodingException(Exception): - pass - -class CloneException(Exception): - pass - -TOKEN = os.environ['TOKEN'] - -gitea = gt.Gitea("https://gitea.seeseepuff.be", TOKEN) -org = gt.Organization.request(gitea, "archlinux") -workDir = "./work/" - -def main() -> None: - repositories = org.get_repositories() - for repository in repositories: - print(repository.get_full_name()) - - try: - # Check if the repository has a PKGBUILD file. - # If it does, clone it. - metadata = gitea.requests_get(f"/repos/{repository.owner.username}/{repository.name}/contents/PKGBUILD") - # Empty repositories will just return an empty dict. - if metadata == {}: - continue - - clone_repository(repository) - except gt.NotFoundException: - print("PKGBUILD not found") - continue - -def clone_repository(repository: gt.Repository) -> None: - process = subprocess.Popen(["git", "clone", repository.clone_url, f"{workDir}{repository.name}"]) - result = process.wait() - if result != 0: - raise CloneException(f"Failed to clone {repository.name}") - -if __name__ == "__main__": - shutil.rmtree(workDir, ignore_errors=True) - os.makedirs(workDir, exist_ok=True) - main() \ No newline at end of file diff --git a/gitea.go b/gitea.go new file mode 100644 index 0000000..8a3870e --- /dev/null +++ b/gitea.go @@ -0,0 +1,75 @@ +package main + +import ( + "encoding/json" + "errors" + "fmt" + "io" + "net/http" +) + +type GiteaClient struct { + BaseURL string + Token string +} + +type Repository struct { + Name string `json:"name"` + CloneURL string `json:"clone_url"` + Owner Owner `json:"owner"` + FullName string `json:"full_name"` +} + +type Owner struct { + Username string `json:"username"` +} + +func (g *GiteaClient) getRepositories(org string) (list []Repository, rerr error) { + url := fmt.Sprintf("%s/api/v1/orgs/%s/repos", g.BaseURL, org) + req, _ := http.NewRequest("GET", url, nil) + req.Header.Set("Authorization", "token "+g.Token) + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return nil, err + } + defer func(Body io.ReadCloser) { + err := Body.Close() + if err != nil { + rerr = err + } + }(resp.Body) + + var repos []Repository + if err := json.NewDecoder(resp.Body).Decode(&repos); err != nil { + return nil, err + } + return repos, nil +} + +func (g *GiteaClient) hasPKGBUILD(repo Repository) (present bool, rerr error) { + url := fmt.Sprintf("%s/api/v1/repos/%s/%s/contents/PKGBUILD", g.BaseURL, repo.Owner.Username, repo.Name) + req, _ := http.NewRequest("GET", url, nil) + req.Header.Set("Authorization", "token "+g.Token) + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return false, err + } + defer func(Body io.ReadCloser) { + err := Body.Close() + if err != nil { + rerr = err + } + }(resp.Body) + + if resp.StatusCode == http.StatusNotFound { + return false, nil + } + if resp.StatusCode != http.StatusOK { + return false, errors.New("unexpected status code") + } + + body, _ := io.ReadAll(resp.Body) + return len(body) > 0, nil +} diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 407939a..0000000 --- a/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -py-gitea \ No newline at end of file