From fee0eaaed76a044f90ed812e0c14bf5d8582f16b Mon Sep 17 00:00:00 2001 From: Simon Cornet Date: Thu, 6 Mar 2025 10:02:43 +0100 Subject: [PATCH] fix: nil pointer dereference error when in debug mode --- cmd/gogitlabber/git.go | 28 ++++++++-------- cmd/gogitlabber/gitlab.go | 28 ++++++++++------ cmd/gogitlabber/input.go | 16 ++++----- cmd/gogitlabber/logging/logging.go | 53 ++++++++++++++++++++++++------ cmd/gogitlabber/main.go | 11 ++++--- cmd/gogitlabber/output.go | 4 +-- 6 files changed, 92 insertions(+), 48 deletions(-) diff --git a/cmd/gogitlabber/git.go b/cmd/gogitlabber/git.go index c0d4a9f..a6c9aef 100644 --- a/cmd/gogitlabber/git.go +++ b/cmd/gogitlabber/git.go @@ -38,7 +38,7 @@ func checkoutRepositories(repositories []Repository, concurrency int) { repoDestination := repoDestinationPre + repoName // log activity - logging.Print(debug, "Starting on repository: "+repoName, nil) + logging.Print("Starting on repository: "+repoName, nil) // make gitlab url url := fmt.Sprintf("https://gitlab-token:%s@%s/%s.git", gitlabToken, gitlabHost, repoName) @@ -47,7 +47,7 @@ func checkoutRepositories(repositories []Repository, concurrency int) { checkRepo := func(repoDestination string) string { checkCmd := exec.Command("git", "-C", repoDestination, "remote", "-v") checkOutput, _ := checkCmd.CombinedOutput() - logging.Print(debug, "Checking status for repository: "+repoName, nil) + logging.Print("Checking status for repository: "+repoName, nil) return string(checkOutput) } @@ -59,19 +59,19 @@ func checkoutRepositories(repositories []Repository, concurrency int) { case strings.Contains(string(repoStatus), "No such file or directory"): // log activity - logging.Print(debug, "Decided to clone repository: "+repoName, nil) + logging.Print("Decided to clone repository: "+repoName, nil) // clone the repo cloneRepository := func(repoDestination string, url string) (string, error) { cloneCmd := exec.Command("git", "clone", url, repoDestination) cloneOutput, err := cloneCmd.CombinedOutput() - logging.Print(debug, "Cloning repository: "+repoName+" to "+repoDestination, nil) + logging.Print("Cloning repository: "+repoName+" to "+repoDestination, nil) return string(cloneOutput), err } _, err := cloneRepository(repoDestination, url) if err != nil { - logging.Print(debug, "ERROR: %v\n", err) + logging.Print("ERROR: %v\n", err) } // set a lock, increment counters, update progressbar and unlock @@ -88,7 +88,7 @@ func checkoutRepositories(repositories []Repository, concurrency int) { // pull the latest case strings.Contains(string(repoStatus), url): - logging.Print(debug, "Decided to pull repository: "+repoName, nil) + logging.Print("Decided to pull repository: "+repoName, nil) pullRepository(repoName, repoDestination) if !debug { descriptionPrefixPre := "Pulling repository " @@ -98,8 +98,8 @@ func checkoutRepositories(repositories []Repository, concurrency int) { } default: - logging.Print(debug, "ERROR: decided not to clone or pull repository: "+repoName, nil) - logging.Print(debug, "ERROR: this is why: "+repoStatus, nil) + logging.Print("ERROR: decided not to clone or pull repository: "+repoName, nil) + logging.Print("ERROR: this is why: "+repoStatus, nil) // set a lock, increment counters and unlock mu.Lock() @@ -119,7 +119,7 @@ func checkoutRepositories(repositories []Repository, concurrency int) { func pullRepository(repoName string, repoDestination string) { // log activity - logging.Print(debug, "Pulling repository: "+repoName+" at "+repoDestination, nil) + logging.Print("Pulling repository: "+repoName+" at "+repoDestination, nil) // find remote findRemote := func(repoDestination string) (string, error) { @@ -129,9 +129,9 @@ func pullRepository(repoName string, repoDestination string) { return "", fmt.Errorf("finding remote: %v\n", err) } - logging.Print(debug, "Finding remote for repository: "+repoName+" at "+repoDestination, nil) + logging.Print("Finding remote for repository: "+repoName+" at "+repoDestination, nil) remote := strings.Split(strings.TrimSpace(string(remoteOutput)), "\n")[0] - logging.Print(debug, "Found remote; "+remote+" for repository: "+repoName+" at "+repoDestination, nil) + logging.Print("Found remote; "+remote+" for repository: "+repoName+" at "+repoDestination, nil) return remote, nil } remote, _ := findRemote(repoDestination) @@ -156,13 +156,13 @@ func pullRepository(repoName string, repoDestination string) { switch { case strings.Contains(string(pullOutput), "You have unstaged changes"): pullErrorMsg = append(pullErrorMsg, repoDestination) - logging.Print(debug, "Found unstaged changes for repository: "+repoName+" at "+repoDestination, nil) + logging.Print("Found unstaged changes for repository: "+repoName+" at "+repoDestination, nil) default: - logging.Print(debug, "ERROR: pulling "+repoName, nil) + logging.Print("ERROR: pulling "+repoName, nil) } } // log activity - logging.Print(debug, "Pulled repository: "+repoName+" at "+repoDestination, nil) + logging.Print("Pulled repository: "+repoName+" at "+repoDestination, nil) } diff --git a/cmd/gogitlabber/gitlab.go b/cmd/gogitlabber/gitlab.go index 25db451..fee8ca4 100644 --- a/cmd/gogitlabber/gitlab.go +++ b/cmd/gogitlabber/gitlab.go @@ -28,16 +28,16 @@ func fetchRepositoriesGitlab() ([]Repository, error) { url := fmt.Sprintf("https://%s/api/v4/projects?%s&%s&%s%s", gitlabHost, membership, order, perpage, archived) - logging.Print(debug, "HTTP: Creating API request", nil) + logging.Print("HTTP: Creating API request", nil) req, err := http.NewRequest("GET", url, nil) if err != nil { return nil, fmt.Errorf("ERROR: creating request: %v\n", err) } - logging.Print(debug, "HTTP: Adding PRIVATE-TOKEN header to API request", nil) + logging.Print("HTTP: Adding PRIVATE-TOKEN header to API request", nil) req.Header.Set("PRIVATE-TOKEN", gitlabToken) - logging.Print(debug, "HTTP: Making request", nil) + logging.Print("HTTP: Making request", nil) client := &http.Client{} resp, err := client.Do(req) if err != nil { @@ -49,7 +49,7 @@ func fetchRepositoriesGitlab() ([]Repository, error) { return nil, fmt.Errorf("ERROR: API request failed with status: %d\n", resp.StatusCode) } - logging.Print(debug, "HTTP: Decoding JSON response", nil) + logging.Print("HTTP: Decoding JSON response", nil) var repositories []Repository if err := json.NewDecoder(resp.Body).Decode(&repositories); err != nil { return nil, fmt.Errorf("ERROR: decoding response: %v\n", err) @@ -60,12 +60,20 @@ func fetchRepositoriesGitlab() ([]Repository, error) { } repoCount := len(repositories) - err = bar.Set(0) - if err != nil { - logging.Fatal("Could not reset the progressbar", err) - } - bar.ChangeMax(repoCount) - logging.Print(debug, "HTTP: Returning repositories found", nil) + logging.Print("Resetting the progressbar", nil) + if !debug { + err = bar.Set(0) + if err != nil { + logging.Fatal("Could not reset the progressbar", err) + } + } + + logging.Print("Increasing the max value of the progressbar", nil) + if !debug { + bar.ChangeMax(repoCount) + } + + logging.Print("HTTP: Returning repositories found", nil) return repositories, nil } diff --git a/cmd/gogitlabber/input.go b/cmd/gogitlabber/input.go index 900c603..05a9b68 100644 --- a/cmd/gogitlabber/input.go +++ b/cmd/gogitlabber/input.go @@ -24,7 +24,7 @@ func setDefaultsFromEnv() { if debugVal, err := strconv.ParseBool(envDebug); err == nil { debug = debugVal } else { - logging.Print(debug, "Warning: Invalid debug value in environment, using default", nil) + logging.Print("Warning: Invalid debug value in environment, using default", nil) } } @@ -44,7 +44,7 @@ func setDefaultsFromEnv() { if concurrencyVal, err := strconv.Atoi(envConcurrency); err == nil { concurrency = concurrencyVal } else { - logging.Print(debug, "Warning: Invalid concurrency value in environment, using default", nil) + logging.Print("Warning: Invalid concurrency value in environment, using default", nil) } } @@ -53,7 +53,7 @@ func setDefaultsFromEnv() { case "any", "exclusive", "excluded": includeArchived = envArchived default: - logging.Print(debug, "Warning: Invalid archived value in environment, using default", nil) + logging.Print("Warning: Invalid archived value in environment, using default", nil) } } } @@ -124,11 +124,11 @@ func manageArguments() { } // log configuration - logging.Print(debug, "Configuration: Using GitLab host: "+gitlabHost, nil) - logging.Print(debug, "Configuration: Using destination: "+repoDestinationPre, nil) - logging.Print(debug, "Configuration: Using concurrency: "+strconv.Itoa(concurrency), nil) - logging.Print(debug, "Configuration: Using archived option: "+includeArchived, nil) + logging.Print("Configuration: Using GitLab host: "+gitlabHost, nil) + logging.Print("Configuration: Using destination: "+repoDestinationPre, nil) + logging.Print("Configuration: Using concurrency: "+strconv.Itoa(concurrency), nil) + logging.Print("Configuration: Using archived option: "+includeArchived, nil) if debug { - logging.Print(debug, "Configuration: Debug mode enabled", nil) + logging.Print("Configuration: Debug mode enabled", nil) } } diff --git a/cmd/gogitlabber/logging/logging.go b/cmd/gogitlabber/logging/logging.go index 83b18d6..62f0437 100644 --- a/cmd/gogitlabber/logging/logging.go +++ b/cmd/gogitlabber/logging/logging.go @@ -1,23 +1,56 @@ package logging import ( + "fmt" + "io" "log" ) -func Print(debug bool, message string, err error) { - if debug { - if err != nil { - log.Printf("gogitlabber | DEBUG: %v error: %v\n", message, err) - } - if err == nil { - log.Printf("gogitlabber | DEBUG: %v\n", message) - } +// define application name used in prefix +var applicationName = "" + +func SetAppName(name string) { + applicationName = name +} + +func GetAppName() string { + return applicationName +} + +var debug bool + +func SetDebug(debugSetting bool) { + debug = debugSetting + if !debug { + log.SetOutput(io.Discard) } } +func GetDebug() bool { + return debug +} + +// Prints the formatted log, taking both a message (string) and optionally +// an error as inputs. +func Print(message string, err error) error { + if debug { + if err != nil { + log.Printf(applicationName+" | DEBUG: %v error: %v\n", message, err) + } + if err == nil { + log.Printf(applicationName+" | DEBUG: %v\n", message) + } + } else { + return fmt.Errorf("It seems you want to print a log while debug is off") + } + return nil +} + +// Prints the fatal error and exits the application. Takes both the message and +// optionally an error as inputs. func Fatal(message string, err error) { if err != nil { - log.Fatalf("gogitlabber | FATAL: %v error: %v\n", message, err) + log.Fatalf(applicationName+" | FATAL: %v error: %v\n", message, err) } - log.Fatalf("gogitlabber | FATAL: %v\n", message) + log.Fatalf(applicationName+" | FATAL: %v\n", message) } diff --git a/cmd/gogitlabber/main.go b/cmd/gogitlabber/main.go index 0082486..e4c16d1 100644 --- a/cmd/gogitlabber/main.go +++ b/cmd/gogitlabber/main.go @@ -2,8 +2,6 @@ package main import ( "gogitlabber/cmd/gogitlabber/logging" - "io" - "log" ) // userdata @@ -28,20 +26,25 @@ type Repository struct { func main() { + // set appname for logging + logging.SetAppName("gogitlabber") + // manage all argument magic manageArguments() + // set debugging + logging.SetDebug(debug) + // check for git err := verifyGitAvailable() if err != nil { logging.Fatal("git not found in path: %v", err) } - logging.Print(debug, "VALIDATION: git found in path", nil) + logging.Print("VALIDATION: git found in path", nil) // make initial progressbar if !debug { progressBar() - log.SetOutput(io.Discard) } // fetch repository information from gitlab diff --git a/cmd/gogitlabber/output.go b/cmd/gogitlabber/output.go index 461fc34..7036632 100644 --- a/cmd/gogitlabber/output.go +++ b/cmd/gogitlabber/output.go @@ -32,7 +32,7 @@ func progressBar() { ) // initialize progressbar - logging.Print(debug, "Initialize progressbar", nil) + logging.Print("Initialize progressbar", nil) err := bar.RenderBlank() progressBarAdd(1) if err != nil { @@ -42,7 +42,7 @@ func progressBar() { func progressBarAdd(amount int) { if err := bar.Add(amount); err != nil { - logging.Print(debug, "ERROR: Progress bar update error: %v\n", err) + logging.Print("ERROR: Progress bar update error: %v\n", err) } }