github.com/ungtb10d/cli/v2@v2.0.0-20221110210412-98537dd9d6a1/pkg/cmd/repo/garden/http.go (about) 1 package garden 2 3 import ( 4 "encoding/json" 5 "errors" 6 "fmt" 7 "io" 8 "net/http" 9 "strings" 10 "time" 11 12 "github.com/ungtb10d/cli/v2/internal/ghinstance" 13 "github.com/ungtb10d/cli/v2/internal/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 := io.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 }