github.com/secman-team/gh-api@v1.8.2/pkg/cmd/repo/garden/http.go (about)

     1  package garden
     2  
     3  import (
     4  	"encoding/json"
     5  	"errors"
     6  	"fmt"
     7  	"io/ioutil"
     8  	"net/http"
     9  	"strings"
    10  	"time"
    11  
    12  	"github.com/secman-team/gh-api/core/ghinstance"
    13  	"github.com/secman-team/gh-api/core/ghrepo"
    14  )
    15  
    16  func getCommits(client *http.Client, repo ghrepo.Interface, maxCommits int) ([]*Commit, error) {
    17  	type Item struct {
    18  		Author struct {
    19  			Login string
    20  		}
    21  		Sha string
    22  	}
    23  
    24  	type Result []Item
    25  
    26  	commits := []*Commit{}
    27  
    28  	pathF := func(page int) string {
    29  		return fmt.Sprintf("repos/%s/%s/commits?per_page=100&page=%d", repo.RepoOwner(), repo.RepoName(), page)
    30  	}
    31  
    32  	page := 1
    33  	paginating := true
    34  	for paginating {
    35  		if len(commits) >= maxCommits {
    36  			break
    37  		}
    38  		result := Result{}
    39  		resp, err := getResponse(client, repo.RepoHost(), pathF(page), &result)
    40  		if err != nil {
    41  			return nil, err
    42  		}
    43  		for _, r := range result {
    44  			colorFunc := shaToColorFunc(r.Sha)
    45  			handle := r.Author.Login
    46  			if handle == "" {
    47  				handle = "a mysterious stranger"
    48  			}
    49  			commits = append(commits, &Commit{
    50  				Handle: handle,
    51  				Sha:    r.Sha,
    52  				Char:   colorFunc(string(handle[0])),
    53  			})
    54  		}
    55  		link := resp.Header["Link"]
    56  		if len(link) == 0 || !strings.Contains(link[0], "last") {
    57  			paginating = false
    58  		}
    59  		page++
    60  		time.Sleep(500)
    61  	}
    62  
    63  	// reverse to get older commits first
    64  	for i, j := 0, len(commits)-1; i < j; i, j = i+1, j-1 {
    65  		commits[i], commits[j] = commits[j], commits[i]
    66  	}
    67  
    68  	return commits, nil
    69  }
    70  
    71  func getResponse(client *http.Client, host, path string, data interface{}) (*http.Response, error) {
    72  	url := ghinstance.RESTPrefix(host) + path
    73  	req, err := http.NewRequest("GET", url, nil)
    74  	if err != nil {
    75  		return nil, err
    76  	}
    77  
    78  	req.Header.Set("Content-Type", "application/json; charset=utf-8")
    79  	resp, err := client.Do(req)
    80  	if err != nil {
    81  		return nil, err
    82  	}
    83  	defer resp.Body.Close()
    84  
    85  	success := resp.StatusCode >= 200 && resp.StatusCode < 300
    86  	if !success {
    87  		return nil, errors.New("api call failed")
    88  	}
    89  
    90  	if resp.StatusCode == http.StatusNoContent {
    91  		return resp, nil
    92  	}
    93  
    94  	b, err := ioutil.ReadAll(resp.Body)
    95  	if err != nil {
    96  		return nil, err
    97  	}
    98  
    99  	err = json.Unmarshal(b, &data)
   100  	if err != nil {
   101  		return nil, err
   102  	}
   103  
   104  	return resp, nil
   105  }