Snippets

Brett Morrison A Go program to iterate through a specified owner's repositories on BitBucket and display the status of open Pull Requests

Updated by Brett Morrison

File pullrequests.go Modified

  • Ignore whitespace
  • Hide word diff
 //
 // Given a BB API, return JSON as a map interface
 //
-func getJSON(URL string) (map[string]interface{}, error) {
+func getJSON(URL *string) (map[string]interface{}, error) {
 	client := &http.Client{}
-	req, err := http.NewRequest("GET", URL, nil)
+	req, err := http.NewRequest("GET", *URL, nil)
 	if err != nil {
 		return nil, fmt.Errorf("request error: %s", err)
 	}
 	return jsonResponse, nil
 }
 
-func displayParticipantInfo(ID int, selfHrefLink string) error {
+func displayParticipantInfo(ID *int, selfHrefLink *string) error {
 	// Get more details about the PR
 	jsonResponseDet, err := getJSON(selfHrefLink)
 	if err != nil {
 		isOrNot = "IS"
 	}
 
-	fmt.Printf("    #%d %s READY TO MERGE, %d of %d REVIEWERS APPROVED\n\n", ID, isOrNot, numApprovedReviewers, numReviewers)
+	fmt.Printf("    #%d %s READY TO MERGE, %d of %d REVIEWERS APPROVED\n\n", *ID, isOrNot, numApprovedReviewers, numReviewers)
 
 	return nil
 }
 //
 // Given a PR URL, iterate through state and print info
 //
-func listPR(pullRequestsLink string) error {
-	var prAPI = pullRequestsLink
+func listPR(pullRequestsLink *string) error {
+	var prAPI = *pullRequestsLink
 
 	// PR API has pagination, code for > 1 page
 	for len(prAPI) > 0 {
-		jsonResponse, err := getJSON(prAPI)
+		jsonResponse, err := getJSON(&prAPI)
 		if err != nil {
 			return err
 		}
 			selfHrefLink := fmt.Sprint(selfHref)
 
 			// Display participant details about the PR
-			err := displayParticipantInfo(ID, selfHrefLink)
+			err := displayParticipantInfo(&ID, &selfHrefLink)
 			if err != nil {
 				return err
 			}
 	// Repo API has pagination, code for > 1 page
 	for len(reposAPI) > 0 {
 		// Get the list of repos for this user / group
-		jsonResponse, err := getJSON(reposAPI)
+		jsonResponse, err := getJSON(&reposAPI)
 		if err != nil {
 			fmt.Println(err)
 			os.Exit(1)
 			pullRequestsLink := fmt.Sprint(pullRequestsHref)
 			fmt.Println("Repo:", pullRequestsLink)
 
-			err := listPR(pullRequestsLink)
+			err := listPR(&pullRequestsLink)
 			if err != nil {
 				fmt.Println(err) // OK to continue here if error, no need to exit the program
 			}
Updated by Brett Morrison

File pullrequests.go Modified

  • Ignore whitespace
  • Hide word diff
 
 import (
 	"encoding/json"
-	"errors"
 	"flag"
 	"fmt"
 	"io"
Updated by Brett Morrison

File pullrequests.go Modified

  • Ignore whitespace
  • Hide word diff
 	client := &http.Client{}
 	req, err := http.NewRequest("GET", URL, nil)
 	if err != nil {
-		return nil, errors.New(fmt.Sprintf("request error: %s", err))
+		return nil, fmt.Errorf("request error: %s", err)
 	}
 
 	req.SetBasicAuth(bitbucketUserName, bitbucketPassword)
 
 	res, err := client.Do(req)
 	if err != nil {
-		return nil, errors.New(fmt.Sprintf("request error: %s", err))
+		return nil, fmt.Errorf("request error: %s", err)
 	}
 
 	defer res.Body.Close()
 
 	if res.StatusCode != 200 {
-		return nil, errors.New(fmt.Sprintf("response code: %d", res.StatusCode))
+		return nil, fmt.Errorf("response code: %d", res.StatusCode)
 	}
 
 	var dat interface{}
 
 	decoder := json.NewDecoder(res.Body)
 	if err := decoder.Decode(&dat); err == io.EOF {
-		return nil, errors.New(fmt.Sprintf("decode error: %s", err))
+		return nil, fmt.Errorf("decode error: %s", err)
 	}
 
 	jsonResponse := dat.(map[string]interface{})
Updated by Brett Morrison

File pullrequests.go Modified

  • Ignore whitespace
  • Hide word diff
 )
 
 // Setup the Authentication info
-const bbBaseUrl = "https://bitbucket.org/api/2.0"
+const bbBaseURL = "https://bitbucket.org/api/2.0"
 
 var bitbucketOwnerName string
 var bitbucketUserName string
 //
 // Given a BB API, return JSON as a map interface
 //
-func getJSON(url string) (map[string]interface{}, error) {
+func getJSON(URL string) (map[string]interface{}, error) {
 	client := &http.Client{}
-	req, err := http.NewRequest("GET", url, nil)
+	req, err := http.NewRequest("GET", URL, nil)
 	if err != nil {
-		return nil, errors.New(fmt.Sprintf("Request Error: %s", err))
+		return nil, errors.New(fmt.Sprintf("request error: %s", err))
 	}
 
 	req.SetBasicAuth(bitbucketUserName, bitbucketPassword)
 
 	res, err := client.Do(req)
 	if err != nil {
-		return nil, errors.New(fmt.Sprintf("Request Error: %s", err))
+		return nil, errors.New(fmt.Sprintf("request error: %s", err))
 	}
 
 	defer res.Body.Close()
 
 	if res.StatusCode != 200 {
-		return nil, errors.New(fmt.Sprintf("Response Code: %d", res.StatusCode))
+		return nil, errors.New(fmt.Sprintf("response code: %d", res.StatusCode))
 	}
 
 	var dat interface{}
 
 	decoder := json.NewDecoder(res.Body)
 	if err := decoder.Decode(&dat); err == io.EOF {
-		return nil, errors.New(fmt.Sprintf("Decode Error: %s", err))
+		return nil, errors.New(fmt.Sprintf("decode error: %s", err))
 	}
 
 	jsonResponse := dat.(map[string]interface{})
 	return jsonResponse, nil
 }
 
-func displayParticipantInfo(id int, selfHrefLink string) error {
+func displayParticipantInfo(ID int, selfHrefLink string) error {
 	// Get more details about the PR
 	jsonResponseDet, err := getJSON(selfHrefLink)
 	if err != nil {
 		isOrNot = "IS"
 	}
 
-	fmt.Printf("    #%d %s READY TO MERGE, %d of %d REVIEWERS APPROVED\n\n", id, isOrNot, numApprovedReviewers, numReviewers)
+	fmt.Printf("    #%d %s READY TO MERGE, %d of %d REVIEWERS APPROVED\n\n", ID, isOrNot, numApprovedReviewers, numReviewers)
 
 	return nil
 }
 
 //
-// Given a PR url, iterate through state and print info
+// Given a PR URL, iterate through state and print info
 //
 func listPR(pullRequestsLink string) error {
-	var prApi = pullRequestsLink
+	var prAPI = pullRequestsLink
 
 	// PR API has pagination, code for > 1 page
-	for len(prApi) > 0 {
-		jsonResponse, err := getJSON(prApi)
+	for len(prAPI) > 0 {
+		jsonResponse, err := getJSON(prAPI)
 		if err != nil {
 			return err
 		}
 		// For each PR in the repo
 		for _, value := range prsI {
 			valueMap := value.(map[string]interface{})
-			id := int(valueMap["id"].(float64))
+			ID := int(valueMap["id"].(float64))
 
 			// Display base info about the PR
 			fmt.Printf("    #%d %s (%s -> %s) by %s\n",
-				id,
+				ID,
 				valueMap["title"],
 				valueMap["source"].(map[string]interface{})["branch"].(map[string]interface{})["name"],
 				valueMap["destination"].(map[string]interface{})["branch"].(map[string]interface{})["name"],
 			selfHrefLink := fmt.Sprint(selfHref)
 
 			// Display participant details about the PR
-			err := displayParticipantInfo(id, selfHrefLink)
+			err := displayParticipantInfo(ID, selfHrefLink)
 			if err != nil {
 				return err
 			}
 		// Determine if there's more results - if so, loop control back
 		next := jsonResponse["next"]
 		if next != nil {
-			prApi = fmt.Sprint(next)
+			prAPI = fmt.Sprint(next)
 		} else {
-			prApi = ""
+			prAPI = ""
 		}
 	}
 
 		os.Exit(1)
 	}
 
-	var reposApi = bbBaseUrl + "/repositories/" + bitbucketOwnerName
+	var reposAPI = bbBaseURL + "/repositories/" + bitbucketOwnerName
 
 	// Repo API has pagination, code for > 1 page
-	for len(reposApi) > 0 {
+	for len(reposAPI) > 0 {
 		// Get the list of repos for this user / group
-		jsonResponse, err := getJSON(reposApi)
+		jsonResponse, err := getJSON(reposAPI)
 		if err != nil {
 			fmt.Println(err)
 			os.Exit(1)
 		// Determine if there's more results - if so, loop control back
 		next := jsonResponse["next"]
 		if next != nil {
-			reposApi = fmt.Sprint(next)
+			reposAPI = fmt.Sprint(next)
 		} else {
-			reposApi = ""
+			reposAPI = ""
 		}
 	}
 }
Updated by Brett Morrison

File pullrequests.go Modified

  • Ignore whitespace
  • Hide word diff
 // Brett Morrison, June 2015
 //
 // A simple program to display a list of open pull requests from BitBucket ✔
-// 
+//
 package main
 
 import (
-    "os"
-    "flag"
-    "fmt"
-    "io"
-    "encoding/json"
-    "net/http"
-    "errors"
+	"encoding/json"
+	"errors"
+	"flag"
+	"fmt"
+	"io"
+	"net/http"
+	"os"
 )
 
 // Setup the Authentication info
 // Given a BB API, return JSON as a map interface
 //
 func getJSON(url string) (map[string]interface{}, error) {
-    client := &http.Client{}
-    req, err := http.NewRequest("GET", url, nil)
-    if err != nil {
-         return nil, errors.New(fmt.Sprintf("Request Error: %s", err))
-    }
-
-    req.SetBasicAuth(bitbucketUserName, bitbucketPassword)
-
-    res, err := client.Do(req)
-    if err != nil {
-         return nil, errors.New(fmt.Sprintf("Request Error: %s", err))
-    }
-    
-    defer res.Body.Close()
-     
-    if (res.StatusCode != 200) {
-        return nil, errors.New(fmt.Sprintf("Response Code: %d", res.StatusCode))
-    }
-     
-    var dat interface{}     
-
-    decoder := json.NewDecoder(res.Body)
-    if err := decoder.Decode(&dat); err == io.EOF {
-         return nil, errors.New(fmt.Sprintf("Decode Error: %s", err))
-    }
-    
-    jsonResponse := dat.(map[string]interface{})
-    
-    return jsonResponse, nil
+	client := &http.Client{}
+	req, err := http.NewRequest("GET", url, nil)
+	if err != nil {
+		return nil, errors.New(fmt.Sprintf("Request Error: %s", err))
+	}
+
+	req.SetBasicAuth(bitbucketUserName, bitbucketPassword)
+
+	res, err := client.Do(req)
+	if err != nil {
+		return nil, errors.New(fmt.Sprintf("Request Error: %s", err))
+	}
+
+	defer res.Body.Close()
+
+	if res.StatusCode != 200 {
+		return nil, errors.New(fmt.Sprintf("Response Code: %d", res.StatusCode))
+	}
+
+	var dat interface{}
+
+	decoder := json.NewDecoder(res.Body)
+	if err := decoder.Decode(&dat); err == io.EOF {
+		return nil, errors.New(fmt.Sprintf("Decode Error: %s", err))
+	}
+
+	jsonResponse := dat.(map[string]interface{})
+
+	return jsonResponse, nil
 }
 
-func displayParticipantInfo(id int, selfHrefLink string) (error) {
-    // Get more details about the PR
-    jsonResponseDet, err := getJSON(selfHrefLink)
-    if err != nil {
-        return err
-    }
-    
-    // Get details about the participants
-    prsDet := jsonResponseDet["participants"]
-    prsDetI := prsDet.([]interface{})
-
-    // For determining if the PR is ready to merge
-    numApprovedReviewers := 0
-    numReviewers := 0
-    
-    // For each participant in the PR, display state depending on role
-    for _, value := range prsDetI {
-        valueMap := value.(map[string]interface{})
-        role := valueMap["role"]
-        approved := valueMap["approved"] == true
-        displayName := valueMap["user"].(map[string]interface{})["display_name"]
-        
-        // TODO Rewrite with one line RegEx?
-        var approvedS = " "
-        if approved {
-            approvedS = "X"
-        }
-
-        switch (role) {
-            case "REVIEWER":
-                fmt.Printf("        %s %s\n", approvedS, displayName)
-                numReviewers++
-                if (approved) {
-                    numApprovedReviewers++
-                }
-            case "PARTICIPANT":
-                fmt.Printf("        %s (%s)\n", approvedS, displayName)
-            default:
-                fmt.Printf("        %s %s (%s)\n", approvedS, displayName, role)
-        }
-    }
-
-    var isOrNot = "IS NOT"
-    if numReviewers > 0 && numReviewers == numApprovedReviewers {
-        isOrNot = "IS"
-    }
-
-    fmt.Printf("    #%d %s READY TO MERGE, %d of %d REVIEWERS APPROVED\n\n", id, isOrNot, numApprovedReviewers, numReviewers)
-    
-    return nil
+func displayParticipantInfo(id int, selfHrefLink string) error {
+	// Get more details about the PR
+	jsonResponseDet, err := getJSON(selfHrefLink)
+	if err != nil {
+		return err
+	}
+
+	// Get details about the participants
+	prsDet := jsonResponseDet["participants"]
+	prsDetI := prsDet.([]interface{})
+
+	// For determining if the PR is ready to merge
+	numApprovedReviewers := 0
+	numReviewers := 0
+
+	// For each participant in the PR, display state depending on role
+	for _, value := range prsDetI {
+		valueMap := value.(map[string]interface{})
+		role := valueMap["role"]
+		approved := valueMap["approved"] == true
+		displayName := valueMap["user"].(map[string]interface{})["display_name"]
+
+		// TODO Rewrite with one line RegEx?
+		var approvedS = " "
+		if approved {
+			approvedS = "X"
+		}
+
+		switch role {
+		case "REVIEWER":
+			fmt.Printf("        %s %s\n", approvedS, displayName)
+			numReviewers++
+			if approved {
+				numApprovedReviewers++
+			}
+		case "PARTICIPANT":
+			fmt.Printf("        %s (%s)\n", approvedS, displayName)
+		default:
+			fmt.Printf("        %s %s (%s)\n", approvedS, displayName, role)
+		}
+	}
+
+	var isOrNot = "IS NOT"
+	if numReviewers > 0 && numReviewers == numApprovedReviewers {
+		isOrNot = "IS"
+	}
+
+	fmt.Printf("    #%d %s READY TO MERGE, %d of %d REVIEWERS APPROVED\n\n", id, isOrNot, numApprovedReviewers, numReviewers)
+
+	return nil
 }
 
 //
 // Given a PR url, iterate through state and print info
 //
-func listPR(pullRequestsLink string) (error) {
-    var prApi = pullRequestsLink
-    
-    // PR API has pagination, code for > 1 page
-    for len(prApi) > 0 {
-        jsonResponse, err := getJSON(prApi)
-        if err != nil {
-            return err
-        }
-        
-        prs := jsonResponse["values"]
-        prsI := prs.([]interface{})
-    
-        // For each PR in the repo
-        for _, value := range prsI {
-            valueMap := value.(map[string]interface{})
-            id := int(valueMap["id"].(float64))
-            
-            // Display base info about the PR
-            fmt.Printf("    #%d %s (%s -> %s) by %s\n",
-                id,
-                valueMap["title"],
-                valueMap["source"].(map[string]interface{})["branch"].(map[string]interface{})["name"],
-                valueMap["destination"].(map[string]interface{})["branch"].(map[string]interface{})["name"],
-                valueMap["author"].(map[string]interface{})["display_name"])
-    
-            // Prep the URL for more details about the PR
-            links := valueMap["links"]
-            self := links.(map[string]interface{})["self"]
-            selfHref := self.(map[string]interface{})["href"]
-            selfHrefLink := fmt.Sprint(selfHref)
-    
-            // Display participant details about the PR    
-            err := displayParticipantInfo(id, selfHrefLink)
-            if (err != nil) {
-                return err
-            }
-        }
-
-        // Determine if there's more results - if so, loop control back
-        next := jsonResponse["next"]
-        if next != nil {
-            prApi = fmt.Sprint(next)
-        } else {
-            prApi = ""
-        }
-    }
-    
-    return nil
+func listPR(pullRequestsLink string) error {
+	var prApi = pullRequestsLink
+
+	// PR API has pagination, code for > 1 page
+	for len(prApi) > 0 {
+		jsonResponse, err := getJSON(prApi)
+		if err != nil {
+			return err
+		}
+
+		prs := jsonResponse["values"]
+		prsI := prs.([]interface{})
+
+		// For each PR in the repo
+		for _, value := range prsI {
+			valueMap := value.(map[string]interface{})
+			id := int(valueMap["id"].(float64))
+
+			// Display base info about the PR
+			fmt.Printf("    #%d %s (%s -> %s) by %s\n",
+				id,
+				valueMap["title"],
+				valueMap["source"].(map[string]interface{})["branch"].(map[string]interface{})["name"],
+				valueMap["destination"].(map[string]interface{})["branch"].(map[string]interface{})["name"],
+				valueMap["author"].(map[string]interface{})["display_name"])
+
+			// Prep the URL for more details about the PR
+			links := valueMap["links"]
+			self := links.(map[string]interface{})["self"]
+			selfHref := self.(map[string]interface{})["href"]
+			selfHrefLink := fmt.Sprint(selfHref)
+
+			// Display participant details about the PR
+			err := displayParticipantInfo(id, selfHrefLink)
+			if err != nil {
+				return err
+			}
+		}
+
+		// Determine if there's more results - if so, loop control back
+		next := jsonResponse["next"]
+		if next != nil {
+			prApi = fmt.Sprint(next)
+		} else {
+			prApi = ""
+		}
+	}
+
+	return nil
 }
 
 func init() {
-    flag.StringVar(&bitbucketOwnerName, "ownername", "", "Bitbucket repository owner account")
-    flag.StringVar(&bitbucketUserName, "username", "", "Bitbucket account username")
-    flag.StringVar(&bitbucketPassword, "password", "", "Bitbucket account password")
+	flag.StringVar(&bitbucketOwnerName, "ownername", "", "Bitbucket repository owner account")
+	flag.StringVar(&bitbucketUserName, "username", "", "Bitbucket account username")
+	flag.StringVar(&bitbucketPassword, "password", "", "Bitbucket account password")
 }
 
 func main() {
-    // Command line args
-    flag.Parse()
-    if len(os.Args) != 4 {
-        flag.Usage()
-        os.Exit(1)
-    }
-    
-    var reposApi = bbBaseUrl + "/repositories/" + bitbucketOwnerName
-    
-    // Repo API has pagination, code for > 1 page
-    for len(reposApi) > 0 {
-        // Get the list of repos for this user / group
-        jsonResponse, err := getJSON(reposApi)
-        if err != nil {
-            fmt.Println(err)
-            os.Exit(1)
-        }
-        
-        repos := jsonResponse["values"]
-        reposI := repos.([]interface{})
-        
-        // For each repo, get the PR URL and process
-     	for _, value := range reposI {
-            links := value.(map[string]interface{})["links"]
-            pullRequests := links.(map[string]interface{})["pullrequests"]
-            pullRequestsHref := pullRequests.(map[string]interface{})["href"]
-    
-            pullRequestsLink := fmt.Sprint(pullRequestsHref)
-            fmt.Println("Repo:", pullRequestsLink)
-    
-            err := listPR(pullRequestsLink)
-            if err != nil {
-                 fmt.Println(err) // OK to continue here if error, no need to exit the program
-            }
-     	}
-        
-        // Determine if there's more results - if so, loop control back
-        next := jsonResponse["next"]
-        if next != nil {
-            reposApi = fmt.Sprint(next)
-        } else {
-            reposApi = ""
-        }
-    }
+	// Command line args
+	flag.Parse()
+	if len(os.Args) != 4 {
+		flag.Usage()
+		os.Exit(1)
+	}
+
+	var reposApi = bbBaseUrl + "/repositories/" + bitbucketOwnerName
+
+	// Repo API has pagination, code for > 1 page
+	for len(reposApi) > 0 {
+		// Get the list of repos for this user / group
+		jsonResponse, err := getJSON(reposApi)
+		if err != nil {
+			fmt.Println(err)
+			os.Exit(1)
+		}
+
+		repos := jsonResponse["values"]
+		reposI := repos.([]interface{})
+
+		// For each repo, get the PR URL and process
+		for _, value := range reposI {
+			links := value.(map[string]interface{})["links"]
+			pullRequests := links.(map[string]interface{})["pullrequests"]
+			pullRequestsHref := pullRequests.(map[string]interface{})["href"]
+
+			pullRequestsLink := fmt.Sprint(pullRequestsHref)
+			fmt.Println("Repo:", pullRequestsLink)
+
+			err := listPR(pullRequestsLink)
+			if err != nil {
+				fmt.Println(err) // OK to continue here if error, no need to exit the program
+			}
+		}
+
+		// Determine if there's more results - if so, loop control back
+		next := jsonResponse["next"]
+		if next != nil {
+			reposApi = fmt.Sprint(next)
+		} else {
+			reposApi = ""
+		}
+	}
 }
  1. 1
  2. 2
HTTPS SSH

You can clone a snippet to your computer for local editing. Learn more.