-
Notifications
You must be signed in to change notification settings - Fork 122
/
Copy pathgather.go
139 lines (105 loc) · 3.1 KB
/
gather.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
package exporter
import (
"encoding/json"
"fmt"
"path"
"strconv"
"strings"
log "github.com/sirupsen/logrus"
)
// gatherData - Collects the data from the API and stores into struct
func (e *Exporter) gatherData() ([]*Datum, error) {
data := []*Datum{}
responses, err := asyncHTTPGets(e.TargetURLs(), e.APIToken())
if err != nil {
return data, err
}
for _, response := range responses {
// Github can at times present an array, or an object for the same data set.
// This code checks handles this variation.
if isArray(response.body) {
ds := []*Datum{}
json.Unmarshal(response.body, &ds)
data = append(data, ds...)
} else {
d := new(Datum)
// Get releases
if strings.Contains(response.url, "/repos/") {
getReleases(e, response.url, &d.Releases)
}
// Get PRs
if strings.Contains(response.url, "/repos/") {
getPRs(e, response.url, &d.Pulls)
}
json.Unmarshal(response.body, &d)
data = append(data, d)
}
log.Infof("API data fetched for repository: %s", response.url)
}
//return data, rates, err
return data, nil
}
// getRates obtains the rate limit data for requests against the github API.
// Especially useful when operating without oauth and the subsequent lower cap.
func (e *Exporter) getRates() (*RateLimits, error) {
u := *e.APIURL()
u.Path = path.Join(u.Path, "rate_limit")
resp, err := getHTTPResponse(u.String(), e.APIToken())
if err != nil {
return &RateLimits{}, err
}
defer resp.Body.Close()
// Triggers if rate-limiting isn't enabled on private Github Enterprise installations
if resp.StatusCode == 404 {
return &RateLimits{}, fmt.Errorf("Rate Limiting not enabled in GitHub API")
}
limit, err := strconv.ParseFloat(resp.Header.Get("X-RateLimit-Limit"), 64)
if err != nil {
return &RateLimits{}, err
}
rem, err := strconv.ParseFloat(resp.Header.Get("X-RateLimit-Remaining"), 64)
if err != nil {
return &RateLimits{}, err
}
reset, err := strconv.ParseFloat(resp.Header.Get("X-RateLimit-Reset"), 64)
if err != nil {
return &RateLimits{}, err
}
return &RateLimits{
Limit: limit,
Remaining: rem,
Reset: reset,
}, err
}
func getReleases(e *Exporter, url string, data *[]Release) {
i := strings.Index(url, "?")
baseURL := url[:i]
releasesURL := baseURL + "/releases"
releasesResponse, err := asyncHTTPGets([]string{releasesURL}, e.APIToken())
if err != nil {
log.Errorf("Unable to obtain releases from API, Error: %s", err)
}
json.Unmarshal(releasesResponse[0].body, &data)
}
func getPRs(e *Exporter, url string, data *[]Pull) {
i := strings.Index(url, "?")
baseURL := url[:i]
pullsURL := baseURL + "/pulls"
pullsResponse, err := asyncHTTPGets([]string{pullsURL}, e.APIToken())
if err != nil {
log.Errorf("Unable to obtain pull requests from API, Error: %s", err)
}
json.Unmarshal(pullsResponse[0].body, &data)
}
// isArray simply looks for key details that determine if the JSON response is an array or not.
func isArray(body []byte) bool {
isArray := false
for _, c := range body {
if c == ' ' || c == '\t' || c == '\r' || c == '\n' {
continue
}
isArray = c == '['
break
}
return isArray
}