feat: improve logging and added verbose output
This commit is contained in:
parent
a95389f25d
commit
e0f87d7ef9
6 changed files with 104 additions and 46 deletions
|
|
@ -2,7 +2,6 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
@ -54,10 +53,6 @@ func checkoutRepositories(repositories []Repository, concurrency int) {
|
||||||
switch {
|
switch {
|
||||||
case strings.Contains(string(repoStatus), "No such file or directory"):
|
case strings.Contains(string(repoStatus), "No such file or directory"):
|
||||||
|
|
||||||
// update the progress bar
|
|
||||||
descriptionPrefixPre := "Cloning repository "
|
|
||||||
descriptionPrefix := descriptionPrefixPre + repoName + " ..."
|
|
||||||
|
|
||||||
// clone the repo
|
// clone the repo
|
||||||
cloneRepository := func(repoDestination string, url string) (string, error) {
|
cloneRepository := func(repoDestination string, url string) (string, error) {
|
||||||
cloneCmd := exec.Command("git", "clone", url, repoDestination)
|
cloneCmd := exec.Command("git", "clone", url, repoDestination)
|
||||||
|
|
@ -67,29 +62,41 @@ func checkoutRepositories(repositories []Repository, concurrency int) {
|
||||||
}
|
}
|
||||||
_, err := cloneRepository(repoDestination, url)
|
_, err := cloneRepository(repoDestination, url)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("ERROR: %v\n", err)
|
logPrint("ERROR: %v\n", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// set a lock, increment counters and unlock
|
// set a lock, increment counters, update progressbar and unlock
|
||||||
mu.Lock()
|
mu.Lock()
|
||||||
clonedCount++
|
clonedCount++
|
||||||
bar.Describe(descriptionPrefix)
|
if !verbose {
|
||||||
progressBarAdd(1)
|
// update the progress bar
|
||||||
|
descriptionPrefixPre := "Cloning repository "
|
||||||
|
descriptionPrefix := descriptionPrefixPre + repoName + " ..."
|
||||||
|
bar.Describe(descriptionPrefix)
|
||||||
|
progressBarAdd(1)
|
||||||
|
}
|
||||||
mu.Unlock()
|
mu.Unlock()
|
||||||
|
|
||||||
// pull the latest
|
// pull the latest
|
||||||
case strings.Contains(string(repoStatus), url):
|
case strings.Contains(string(repoStatus), url):
|
||||||
pullRepository(repoName, repoDestination)
|
pullRepository(repoName, repoDestination)
|
||||||
progressBarAdd(1)
|
if !verbose {
|
||||||
|
descriptionPrefixPre := "Pulling repository "
|
||||||
|
descriptionPrefix := descriptionPrefixPre + repoName + " ..."
|
||||||
|
bar.Describe(descriptionPrefix)
|
||||||
|
progressBarAdd(1)
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
log.Printf("ERROR: decided not to clone or pull repository %v\n", repoName)
|
logPrint("ERROR: decided not to clone or pull repository" + repoName, nil)
|
||||||
log.Printf("ERROR: this is why: %v\n", repoStatus)
|
logPrint("ERROR: this is why: " + repoStatus, nil)
|
||||||
|
|
||||||
// set a lock, increment counters and unlock
|
// set a lock, increment counters and unlock
|
||||||
mu.Lock()
|
mu.Lock()
|
||||||
errorCount++
|
errorCount++
|
||||||
progressBarAdd(1)
|
if !verbose {
|
||||||
|
progressBarAdd(1)
|
||||||
|
}
|
||||||
mu.Unlock()
|
mu.Unlock()
|
||||||
}
|
}
|
||||||
}(repo)
|
}(repo)
|
||||||
|
|
@ -101,10 +108,6 @@ func checkoutRepositories(repositories []Repository, concurrency int) {
|
||||||
|
|
||||||
func pullRepository(repoName string, repoDestination string) {
|
func pullRepository(repoName string, repoDestination string) {
|
||||||
|
|
||||||
// update the progress bar
|
|
||||||
descriptionPrefixPre := "Pulling repository "
|
|
||||||
descriptionPrefix := descriptionPrefixPre + repoName + " ..."
|
|
||||||
|
|
||||||
// find remote
|
// find remote
|
||||||
findRemote := func(repoDestination string) (string, error) {
|
findRemote := func(repoDestination string) (string, error) {
|
||||||
remoteCmd := exec.Command("git", "-C", repoDestination, "remote", "show")
|
remoteCmd := exec.Command("git", "-C", repoDestination, "remote", "show")
|
||||||
|
|
@ -124,7 +127,6 @@ func pullRepository(repoName string, repoDestination string) {
|
||||||
|
|
||||||
// set a lock, increment counters and unlock
|
// set a lock, increment counters and unlock
|
||||||
mu.Lock()
|
mu.Lock()
|
||||||
bar.Describe(descriptionPrefix)
|
|
||||||
pulledCount++
|
pulledCount++
|
||||||
mu.Unlock()
|
mu.Unlock()
|
||||||
|
|
||||||
|
|
@ -141,7 +143,7 @@ func pullRepository(repoName string, repoDestination string) {
|
||||||
pullErrorMsg = append(pullErrorMsg, repoDestination)
|
pullErrorMsg = append(pullErrorMsg, repoDestination)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
log.Printf("ERROR: pulling %v\n", err)
|
logPrint("ERROR: pulling " + repoName, nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ func fetchRepositoriesGitlab() ([]Repository, error) {
|
||||||
|
|
||||||
req, err := http.NewRequest("GET", url, nil)
|
req, err := http.NewRequest("GET", url, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("creating request: %v\n", err)
|
return nil, fmt.Errorf("ERROR: creating request: %v\n", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
req.Header.Set("PRIVATE-TOKEN", gitlabToken)
|
req.Header.Set("PRIVATE-TOKEN", gitlabToken)
|
||||||
|
|
@ -37,21 +37,21 @@ func fetchRepositoriesGitlab() ([]Repository, error) {
|
||||||
client := &http.Client{}
|
client := &http.Client{}
|
||||||
resp, err := client.Do(req)
|
resp, err := client.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("making request: %v\n", err)
|
return nil, fmt.Errorf("ERROR: making request: %v\n", err)
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
||||||
if resp.StatusCode != http.StatusOK {
|
if resp.StatusCode != http.StatusOK {
|
||||||
return nil, fmt.Errorf("API request failed with status: %d\n", resp.StatusCode)
|
return nil, fmt.Errorf("ERROR: API request failed with status: %d\n", resp.StatusCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
var repositories []Repository
|
var repositories []Repository
|
||||||
if err := json.NewDecoder(resp.Body).Decode(&repositories); err != nil {
|
if err := json.NewDecoder(resp.Body).Decode(&repositories); err != nil {
|
||||||
return nil, fmt.Errorf("decoding response: %v\n", err)
|
return nil, fmt.Errorf("ERROR: decoding response: %v\n", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(repositories) < 1 {
|
if len(repositories) < 1 {
|
||||||
return repositories, fmt.Errorf("no repositories found\n")
|
return repositories, fmt.Errorf("ERROR: no repositories found\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
return repositories, nil
|
return repositories, nil
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ func manageArguments() {
|
||||||
var destinationFlag = flag.String("destination", "$HOME/Documents", "Specify where to check the repositories out\n example: -destination=$HOME/repos\nenv = GOGITLABBER_DESTINATION\n")
|
var destinationFlag = flag.String("destination", "$HOME/Documents", "Specify where to check the repositories out\n example: -destination=$HOME/repos\nenv = GOGITLABBER_DESTINATION\n")
|
||||||
var hostFlag = flag.String("gitlab-url", "gitlab.com", "Specify GitLab host\n example: -gitlab-url=gitlab.com\nenv = GITLAB_URL\n")
|
var hostFlag = flag.String("gitlab-url", "gitlab.com", "Specify GitLab host\n example: -gitlab-url=gitlab.com\nenv = GITLAB_URL\n")
|
||||||
var tokenFlag = flag.String("gitlab-api-token", "", "Specify GitLab API token\n example: -gitlab-api=glpat-xxxx\nenv = GITLAB_API_TOKEN\n")
|
var tokenFlag = flag.String("gitlab-api-token", "", "Specify GitLab API token\n example: -gitlab-api=glpat-xxxx\nenv = GITLAB_API_TOKEN\n")
|
||||||
|
var verboseFlag = flag.Bool("verbose", false, "Specify verbosity\n example: -verbose=true\nenv = GOGITLABBER_VERBOSE\n")
|
||||||
|
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
|
|
@ -25,32 +26,50 @@ func manageArguments() {
|
||||||
gitlabToken = *tokenFlag
|
gitlabToken = *tokenFlag
|
||||||
includeArchived = *archivedFlag
|
includeArchived = *archivedFlag
|
||||||
repoDestinationPre = *destinationFlag
|
repoDestinationPre = *destinationFlag
|
||||||
|
verbose = *verboseFlag
|
||||||
|
|
||||||
|
// manage verbosity option
|
||||||
|
switch envVerbose := os.Getenv("GOGITLABBER_VERBOSE"); {
|
||||||
|
case envVerbose != "":
|
||||||
|
var err error
|
||||||
|
verbose, err = strconv.ParseBool(envVerbose)
|
||||||
|
logPrint("CONFIG: verbose option found", nil)
|
||||||
|
if err != nil {
|
||||||
|
logFatal("FATAL: config; not a valid bool", nil)
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
flag.Usage()
|
||||||
|
logFatal("FATAL: config; no verbose option found", nil)
|
||||||
|
}
|
||||||
|
|
||||||
// manage gitlab api option
|
// manage gitlab api option
|
||||||
switch envToken := os.Getenv("GITLAB_API_TOKEN"); {
|
switch envToken := os.Getenv("GITLAB_API_TOKEN"); {
|
||||||
case envToken != "":
|
case envToken != "":
|
||||||
gitlabToken = envToken
|
gitlabToken = envToken
|
||||||
|
logPrint("CONFIG: Gitlab API Token found", nil)
|
||||||
default:
|
default:
|
||||||
flag.Usage()
|
flag.Usage()
|
||||||
log.Printf("FATAL: config; gitlab api token not found\n")
|
logFatal("CONFIG: Giltab API Token not found", nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// manage gitlab url option
|
// manage gitlab url option
|
||||||
switch envHost := os.Getenv("GITLAB_URL"); {
|
switch envHost := os.Getenv("GITLAB_URL"); {
|
||||||
case envHost != "":
|
case envHost != "":
|
||||||
gitlabHost = envHost
|
gitlabHost = envHost
|
||||||
|
logPrint("CONFIG: Gitlab host found", nil)
|
||||||
default:
|
default:
|
||||||
flag.Usage()
|
flag.Usage()
|
||||||
log.Fatalf("FATAL: config; gitlab host not found\n")
|
logFatal("CONFIG: Gitlab host not found", nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// manage destination option
|
// manage destination option
|
||||||
switch envRepoDest := os.Getenv("GOGITLABBER_DESTINATION"); {
|
switch envRepoDest := os.Getenv("GOGITLABBER_DESTINATION"); {
|
||||||
case envRepoDest != "":
|
case envRepoDest != "":
|
||||||
repoDestinationPre = envRepoDest
|
repoDestinationPre = envRepoDest
|
||||||
|
logPrint("CONFIG: destination found", nil)
|
||||||
default:
|
default:
|
||||||
flag.Usage()
|
flag.Usage()
|
||||||
log.Fatalf("FATAL: config; destination not found\n")
|
logFatal("CONFIG: destination not found", nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// add slash 🎩🎸 if not provided
|
// add slash 🎩🎸 if not provided
|
||||||
|
|
@ -60,36 +79,41 @@ func manageArguments() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// manage concurrency option
|
// manage concurrency option
|
||||||
switch envConcurrency := os.Getenv("GOGITLABBER_CONCURRENCY"); {
|
switch envConcurrency := os.Getenv("GOGITLABBER_CONCURRENCY"); {
|
||||||
case envConcurrency == "":
|
case envConcurrency == "":
|
||||||
concurrency = 15
|
concurrency = 15
|
||||||
case envConcurrency != "":
|
case envConcurrency != "":
|
||||||
concurrencyValue, err := strconv.Atoi(envConcurrency)
|
concurrencyValue, err := strconv.Atoi(envConcurrency)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("FATAL: invalid concurrency value in environment: %v", err)
|
logFatal("invalid concurrency value in environment: %v", err)
|
||||||
}
|
}
|
||||||
concurrency = concurrencyValue
|
concurrency = concurrencyValue
|
||||||
default:
|
logPrint("CONFIG: concurrency option found", nil)
|
||||||
flag.Usage()
|
default:
|
||||||
log.Fatalf("FATAL: config; concurrency not found\n")
|
flag.Usage()
|
||||||
}
|
log.Fatalln("FATAL: config; concurrency not found")
|
||||||
|
}
|
||||||
|
|
||||||
// manage archived option
|
// manage archived option
|
||||||
switch envArchived := os.Getenv("GOGITLABBER_ARCHIVED"); {
|
switch envArchived := os.Getenv("GOGITLABBER_ARCHIVED"); {
|
||||||
case envArchived == "":
|
case envArchived == "":
|
||||||
includeArchived = "excluded"
|
includeArchived = "excluded"
|
||||||
|
logPrint("CONFIG: archive option found", nil)
|
||||||
|
|
||||||
case envArchived == "any":
|
case envArchived == "any":
|
||||||
includeArchived = envArchived
|
includeArchived = envArchived
|
||||||
|
logPrint("CONFIG: archive option found", nil)
|
||||||
|
|
||||||
case envArchived == "exclusive":
|
case envArchived == "exclusive":
|
||||||
includeArchived = envArchived
|
includeArchived = envArchived
|
||||||
|
logPrint("CONFIG: archive option found", nil)
|
||||||
|
|
||||||
case envArchived == "excluded":
|
case envArchived == "excluded":
|
||||||
includeArchived = envArchived
|
includeArchived = envArchived
|
||||||
|
logPrint("CONFIG: archive option found", nil)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
flag.Usage()
|
flag.Usage()
|
||||||
log.Fatalf("FATAL: config; no or wrong archive option found\n")
|
logFatal("FATAL: config; no or wrong archive option found", nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,9 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import "log"
|
import (
|
||||||
|
"io"
|
||||||
|
"log"
|
||||||
|
)
|
||||||
|
|
||||||
// userdata
|
// userdata
|
||||||
var concurrency int
|
var concurrency int
|
||||||
|
|
@ -8,6 +11,7 @@ var gitlabHost string
|
||||||
var gitlabToken string
|
var gitlabToken string
|
||||||
var includeArchived string
|
var includeArchived string
|
||||||
var repoDestinationPre string
|
var repoDestinationPre string
|
||||||
|
var verbose bool
|
||||||
|
|
||||||
// keep count 🧛
|
// keep count 🧛
|
||||||
var clonedCount int
|
var clonedCount int
|
||||||
|
|
@ -27,16 +31,26 @@ func main() {
|
||||||
manageArguments()
|
manageArguments()
|
||||||
|
|
||||||
// check for git
|
// check for git
|
||||||
verifyGitAvailable()
|
err := verifyGitAvailable()
|
||||||
|
if err != nil {
|
||||||
|
logFatal("FATAL: git not found in path: %v", err)
|
||||||
|
}
|
||||||
|
logPrint("Git is available. Proceeding with the program.", nil)
|
||||||
|
|
||||||
// fetch repository information from gitlab
|
// fetch repository information from gitlab
|
||||||
repositories, err := fetchRepositoriesGitlab()
|
repositories, err := fetchRepositoriesGitlab()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("FATAL: %v", err)
|
logFatal("FATAL: %v", err)
|
||||||
|
}
|
||||||
|
logPrint("Logged into GitLab, Repositories found. Proceeding with the program.", nil)
|
||||||
|
|
||||||
|
// print progressbar ony if not in verbose mode
|
||||||
|
if !verbose {
|
||||||
|
progressBar(repositories)
|
||||||
|
log.SetOutput(io.Discard)
|
||||||
}
|
}
|
||||||
|
|
||||||
// manage found repositories
|
// manage found repositories
|
||||||
progressBar(repositories)
|
|
||||||
checkoutRepositories(repositories, concurrency)
|
checkoutRepositories(repositories, concurrency)
|
||||||
printSummary()
|
printSummary()
|
||||||
printPullError(pullErrorMsg)
|
printPullError(pullErrorMsg)
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ func progressBar(repositories []Repository) {
|
||||||
|
|
||||||
func progressBarAdd(amount int) {
|
func progressBarAdd(amount int) {
|
||||||
if err := bar.Add(amount); err != nil {
|
if err := bar.Add(amount); err != nil {
|
||||||
log.Printf("ERROR: Progress bar update error: %v\n", err)
|
logPrint("ERROR: Progress bar update error: %v\n", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -66,3 +66,21 @@ func printPullError(pullErrorMsg []string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func logPrint(message string, err error) {
|
||||||
|
if verbose == true {
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("gogitlabber | %v error: %v\n", message, err)
|
||||||
|
}
|
||||||
|
if err == nil {
|
||||||
|
log.Printf("gogitlabber | %v\n", message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func logFatal(message string, err error) {
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("gogitlabber | FATAL: %v error: %v\n", message, err)
|
||||||
|
}
|
||||||
|
log.Fatalf("gogitlabber | FATAL: %v\n", message)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,13 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
|
||||||
"os/exec"
|
"os/exec"
|
||||||
)
|
)
|
||||||
|
|
||||||
func verifyGitAvailable() {
|
func verifyGitAvailable() error {
|
||||||
_, err := exec.LookPath("git")
|
_, err := exec.LookPath("git")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal("could not find git in path")
|
return err
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue