feat: many improvements
This commit is contained in:
parent
3e9c0e82da
commit
23652f5a04
1 changed files with 147 additions and 94 deletions
145
main.go
145
main.go
|
|
@ -3,13 +3,13 @@ package main
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/k0kubun/go-ansi"
|
||||||
|
"github.com/schollz/progressbar/v3"
|
||||||
"log"
|
"log"
|
||||||
"strings"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"github.com/k0kubun/go-ansi"
|
"strings"
|
||||||
"github.com/schollz/progressbar/v3"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Repository struct {
|
type Repository struct {
|
||||||
|
|
@ -21,6 +21,7 @@ var repoDestinationPre string
|
||||||
var includeArchived string
|
var includeArchived string
|
||||||
var gitlabToken string
|
var gitlabToken string
|
||||||
var gitlabHost string
|
var gitlabHost string
|
||||||
|
var pullError []string
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
||||||
|
|
@ -30,42 +31,10 @@ func main() {
|
||||||
log.Fatalf("Error loading environment variables: %v", err)
|
log.Fatalf("Error loading environment variables: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// require at least the destination argument
|
// manage all argument magic
|
||||||
if len(os.Args) <= 1 {
|
manageArguments()
|
||||||
fmt.Println("Usage: gogitlabber --destination=<directory>")
|
|
||||||
fmt.Println("Example: gogitlabber --destination=/tmp/repos")
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// parse arguments
|
// fetch repository information from gitlab
|
||||||
for _, arg := range os.Args[1:] {
|
|
||||||
switch {
|
|
||||||
|
|
||||||
case strings.HasPrefix(arg, "--destination="):
|
|
||||||
repoDestinationPre = strings.TrimPrefix(arg, "--destination=")
|
|
||||||
|
|
||||||
case strings.HasPrefix(arg, "--gitlab-api-token="):
|
|
||||||
gitlabToken = strings.TrimPrefix(arg, "--gitlab-api-token=")
|
|
||||||
|
|
||||||
case strings.HasPrefix(arg, "--gitlab-url="):
|
|
||||||
gitlabHost = strings.TrimPrefix(arg, "--gitlab-url=")
|
|
||||||
|
|
||||||
default:
|
|
||||||
fmt.Println("Usage: gogitlabber --destination=<directory>")
|
|
||||||
fmt.Println("Example: gogitlabber --destination=/tmp/repos")
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// fail if destination is unknown
|
|
||||||
if repoDestinationPre == "" {
|
|
||||||
fmt.Println("Fatal: No destination found.")
|
|
||||||
fmt.Println("Example: gogitlabber --destination=/tmp/repos")
|
|
||||||
fmt.Println("Usage: gogitlabber --destination=/tmp/repos")
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// fetch repository information
|
|
||||||
repositories, err := fetchRepositories()
|
repositories, err := fetchRepositories()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Error fetching repositories: %v", err)
|
log.Fatalf("Error fetching repositories: %v", err)
|
||||||
|
|
@ -73,9 +42,9 @@ func main() {
|
||||||
|
|
||||||
// manage found repositories
|
// manage found repositories
|
||||||
checkoutRepositories(repositories)
|
checkoutRepositories(repositories)
|
||||||
|
printPullerror(pullError)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func loadEnvironmentVariables() error {
|
func loadEnvironmentVariables() error {
|
||||||
gitlabToken = os.Getenv("GITLAB_API_KEY")
|
gitlabToken = os.Getenv("GITLAB_API_KEY")
|
||||||
if gitlabToken == "" {
|
if gitlabToken == "" {
|
||||||
|
|
@ -89,16 +58,87 @@ func loadEnvironmentVariables() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func manageArguments() {
|
||||||
|
|
||||||
|
// require at least the destination argument
|
||||||
|
if len(os.Args) <= 1 {
|
||||||
|
fmt.Println("Usage: gogitlabber --destination=<directory>")
|
||||||
|
fmt.Println("Example: gogitlabber --destination=$HOME/repos")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// parse arguments
|
||||||
|
for _, arg := range os.Args[1:] {
|
||||||
|
switch {
|
||||||
|
|
||||||
|
case strings.HasPrefix(arg, "--archived="):
|
||||||
|
includeArchived = strings.TrimPrefix(arg, "--archived=")
|
||||||
|
|
||||||
|
case strings.HasPrefix(arg, "--destination="):
|
||||||
|
repoDestinationPre = strings.TrimPrefix(arg, "--destination=")
|
||||||
|
|
||||||
|
case strings.HasPrefix(arg, "--gitlab-api-token="):
|
||||||
|
gitlabToken = strings.TrimPrefix(arg, "--gitlab-api-token=")
|
||||||
|
|
||||||
|
case strings.HasPrefix(arg, "--gitlab-url="):
|
||||||
|
gitlabHost = strings.TrimPrefix(arg, "--gitlab-url=")
|
||||||
|
|
||||||
|
default:
|
||||||
|
fmt.Println("Usage: gogitlabber --destination=<directory>")
|
||||||
|
fmt.Println("Example: gogitlabber --destination=$HOME/repos")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// --archive options:
|
||||||
|
// - any (fetch both)
|
||||||
|
// - only (fetch archived only)
|
||||||
|
// - excluded (fetch non-archived only - default)
|
||||||
|
if includeArchived == "" {
|
||||||
|
includeArchived = "excluded"
|
||||||
|
}
|
||||||
|
|
||||||
|
if includeArchived != "any" &&
|
||||||
|
includeArchived != "only" &&
|
||||||
|
includeArchived != "excluded" {
|
||||||
|
fmt.Println("Usage: gogitlabber --archived=(any|excluded|only)")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// fail if destination is unknown
|
||||||
|
if repoDestinationPre == "" {
|
||||||
|
fmt.Println("Fatal: No destination found.")
|
||||||
|
fmt.Println("Example: gogitlabber --destination=$HOME/repos")
|
||||||
|
fmt.Println("Usage: gogitlabber --destination=$HOME/repos")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// add slash if not provided to directory
|
||||||
|
if !strings.HasSuffix(repoDestinationPre, "/") {
|
||||||
|
repoDestinationPre += "/"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func fetchRepositories() ([]Repository, error) {
|
func fetchRepositories() ([]Repository, error) {
|
||||||
|
|
||||||
archived := "archived=false"
|
// default options
|
||||||
membership := "membership=true"
|
membership := "membership=true"
|
||||||
perpage := "per_page=100"
|
perpage := "per_page=100"
|
||||||
order := "order_by=name"
|
order := "order_by=name"
|
||||||
|
|
||||||
url := fmt.Sprintf("https://%s/api/v4/projects?%s&%s&%s&%s",
|
// configure archived options
|
||||||
gitlabHost, membership, order, archived, perpage)
|
var archived string
|
||||||
|
switch {
|
||||||
|
case includeArchived == "excluded":
|
||||||
|
archived = "&archived=false"
|
||||||
|
case includeArchived == "only":
|
||||||
|
archived = "&archived=true"
|
||||||
|
default:
|
||||||
|
archived = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
url := fmt.Sprintf("https://%s/api/v4/projects?%s&%s&%s%s",
|
||||||
|
gitlabHost, membership, order, perpage, archived)
|
||||||
|
|
||||||
req, err := http.NewRequest("GET", url, nil)
|
req, err := http.NewRequest("GET", url, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -126,7 +166,6 @@ func fetchRepositories() ([]Repository, error) {
|
||||||
return repositories, nil
|
return repositories, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func checkoutRepositories(repositories []Repository) {
|
func checkoutRepositories(repositories []Repository) {
|
||||||
repoCount := len(repositories)
|
repoCount := len(repositories)
|
||||||
|
|
||||||
|
|
@ -179,14 +218,28 @@ func checkoutRepositories(repositories []Repository) {
|
||||||
}
|
}
|
||||||
bar.Add(1)
|
bar.Add(1)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
// print empty line as the bar does not do that
|
||||||
|
fmt.Println("")
|
||||||
|
}
|
||||||
|
|
||||||
func pullRepositories(repoDestination string) {
|
func pullRepositories(repoDestination string) {
|
||||||
pullCmd := exec.Command("git", "-C", repoDestination, "pull", "origin")
|
pullCmd := exec.Command("git", "-C", repoDestination, "pull", "origin")
|
||||||
output, err := pullCmd.CombinedOutput()
|
pullOutput, err := pullCmd.CombinedOutput()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("❌ Error pulling %s: %v\n%s", repoDestination, err, string(output))
|
if strings.Contains(string(pullOutput),
|
||||||
|
"You have unstaged changes") {
|
||||||
|
pullError = append(pullError, repoDestination)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func printPullerror(pullError []string) {
|
||||||
|
|
||||||
|
if len(pullError) > 0 {
|
||||||
|
for _, repo := range pullError {
|
||||||
|
fmt.Printf("❕%s has unstaged changes.\n", repo)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue