Skip to content

Commit db00c37

Browse files
committed
switch to github.com/google/go-github/github
With this change, the GITHUB_USERNAME, GITHUB_PASSWORD and GITHUB_OTP environment variables are introduced. Authenticating to GitHub is useful to obtain a higher rate limit. Furthermore, an in-memory cache is now used to reduce the number of requests sent to GitHub in the first place. fixes https://bugs.debian.org/898397
1 parent 667ff7d commit db00c37

File tree

3 files changed

+59
-105
lines changed

3 files changed

+59
-105
lines changed

description.go

Lines changed: 13 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,14 @@ package main
22

33
import (
44
"bytes"
5-
"encoding/base64"
6-
"encoding/json"
5+
"context"
76
"fmt"
8-
"net/http"
97
"os/exec"
108
"strings"
119

1210
"github.com/russross/blackfriday"
1311
)
1412

15-
type readmeReply struct {
16-
Content string `json:"content"`
17-
Encoding string `json:"encoding"`
18-
Name string `json:"name"`
19-
}
20-
2113
func reformatForControl(raw string) string {
2214
// Reformat the wrapped description to conform to Debian’s control format.
2315
for strings.Contains(raw, "\n\n") {
@@ -30,26 +22,18 @@ func getLongDescriptionForGopkg(gopkg string) (string, error) {
3022
if !strings.HasPrefix(gopkg, "github.com/") {
3123
return "", nil
3224
}
33-
resp, err := http.Get("https://api.github.com/repos/" + gopkg[len("github.com/"):] + "/readme")
34-
if err != nil {
35-
return "", err
25+
parts := strings.Split(strings.TrimPrefix(gopkg, "github.com/"), "/")
26+
if got, want := len(parts), 2; got != want {
27+
return "", fmt.Errorf("invalid GitHub repo: %q does not follow github.com/owner/repo", gopkg)
3628
}
37-
defer resp.Body.Close()
29+
owner, repo := parts[0], parts[1]
3830

39-
if resp.StatusCode != http.StatusOK {
40-
return "", fmt.Errorf("unexpected HTTP status: got %d, want %d", resp.StatusCode, http.StatusOK)
41-
}
42-
43-
var rr readmeReply
44-
if err := json.NewDecoder(resp.Body).Decode(&rr); err != nil {
31+
rr, _, err := gitHub.Repositories.GetReadme(context.TODO(), owner, repo, nil)
32+
if err != nil {
4533
return "", err
4634
}
4735

48-
if rr.Encoding != "base64" {
49-
return "", fmt.Errorf("unexpected encoding: got %q, want %q", rr.Encoding, "base64")
50-
}
51-
52-
content, err := base64.StdEncoding.DecodeString(rr.Content)
36+
content, err := rr.GetContent()
5337
if err != nil {
5438
return "", err
5539
}
@@ -61,14 +45,14 @@ func getLongDescriptionForGopkg(gopkg string) (string, error) {
6145
// fairly involved, but it’d be the most correct solution to the problem at
6246
// hand. Our current code just knows markdown, which is good enough since
6347
// most (Go?) projects in fact use markdown for their README files.
64-
if !strings.HasSuffix(rr.Name, "md") &&
65-
!strings.HasSuffix(rr.Name, "markdown") &&
66-
!strings.HasSuffix(rr.Name, "mdown") &&
67-
!strings.HasSuffix(rr.Name, "mkdn") {
48+
if !strings.HasSuffix(rr.GetName(), "md") &&
49+
!strings.HasSuffix(rr.GetName(), "markdown") &&
50+
!strings.HasSuffix(rr.GetName(), "mdown") &&
51+
!strings.HasSuffix(rr.GetName(), "mkdn") {
6852
return reformatForControl(strings.TrimSpace(string(content))), nil
6953
}
7054

71-
output := blackfriday.Markdown(content, &TextRenderer{}, 0)
55+
output := blackfriday.Markdown([]byte(content), &TextRenderer{}, 0)
7256
// Shell out to fmt(1) to line-wrap the output.
7357
cmd := exec.Command("fmt")
7458
cmd.Stdin = bytes.NewBuffer(output)

main.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,13 @@ package main
33
import (
44
"fmt"
55
"os"
6+
7+
"github.com/google/go-github/github"
8+
"github.com/gregjones/httpcache"
9+
)
10+
11+
var (
12+
gitHub *github.Client
613
)
714

815
func usage() {
@@ -19,6 +26,14 @@ func usage() {
1926
}
2027

2128
func main() {
29+
transport := github.BasicAuthTransport{
30+
Username: os.Getenv("GITHUB_USERNAME"),
31+
Password: os.Getenv("GITHUB_PASSWORD"),
32+
OTP: os.Getenv("GITHUB_OTP"),
33+
Transport: httpcache.NewMemoryCacheTransport(),
34+
}
35+
gitHub = github.NewClient(transport.Client())
36+
2237
// Retrieve args and Shift binary name off argument list.
2338
args := os.Args[1:]
2439

metadata.go

Lines changed: 31 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,17 @@
11
package main
22

33
import (
4-
"encoding/json"
4+
"context"
55
"fmt"
66
"net/http"
77
"regexp"
88
"strings"
9-
"time"
109

1110
"golang.org/x/net/html"
1211
)
1312

14-
type licensesReply struct {
15-
Key string `json:"key"`
16-
Name string `json:"name"`
17-
URL string `json:"url"`
18-
Featured bool `json:"featured"`
19-
}
20-
21-
type ownerReply struct {
22-
URL string `json:"url"`
23-
}
24-
25-
type repositoryReply struct {
26-
License licensesReply `json:"license"`
27-
CreatedAt string `json:"created_at"`
28-
Description string `json:"description"`
29-
Owner ownerReply `json:"owner"`
30-
}
31-
32-
type licenseReply struct {
33-
Body string `json:"body"`
34-
}
35-
36-
type usersReply struct {
37-
Name string `json:"name"`
38-
}
39-
4013
// To update, use:
41-
// curl -s -H 'Accept: application/vnd.github.drax-preview+json' https://api.github.com/licenses | jq '.[].key'
14+
// curl -s https://api.github.com/licenses | jq '.[].key'
4215
// then compare with https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/#license-specification
4316
var githubLicenseToDebianLicense = map[string]string{
4417
//"agpl-3.0" (not in debian?)
@@ -85,7 +58,7 @@ var debianLicenseText = map[string]string{
8558

8659
var githubRegexp = regexp.MustCompile(`github\.com/([^/]+/[^/]+)`)
8760

88-
func findGitHubRepo(gopkg string) (string, error) {
61+
func findGitHubOwnerRepo(gopkg string) (string, error) {
8962
if strings.HasPrefix(gopkg, "github.com/") {
9063
return strings.TrimPrefix(gopkg, "github.com/"), nil
9164
}
@@ -136,27 +109,30 @@ func findGitHubRepo(gopkg string) (string, error) {
136109
}
137110
}
138111

139-
func getLicenseForGopkg(gopkg string) (string, string, error) {
140-
repo, err := findGitHubRepo(gopkg)
112+
func findGitHubRepo(gopkg string) (owner string, repo string, _ error) {
113+
ownerrepo, err := findGitHubOwnerRepo(gopkg)
141114
if err != nil {
142115
return "", "", err
143116
}
144-
// TODO: cache this reply
145-
req, err := http.NewRequest("GET", "https://api.github.com/repos/"+repo, nil)
146-
if err != nil {
147-
return "", "", err
117+
parts := strings.Split(ownerrepo, "/")
118+
if got, want := len(parts), 2; got != want {
119+
return "", "", fmt.Errorf("invalid GitHub repo: %q does not follow owner/repo", repo)
148120
}
149-
req.Header.Set("Accept", "application/vnd.github.drax-preview+json")
150-
resp, err := http.DefaultClient.Do(req)
121+
return parts[0], parts[1], nil
122+
}
123+
124+
func getLicenseForGopkg(gopkg string) (string, string, error) {
125+
owner, repo, err := findGitHubRepo(gopkg)
151126
if err != nil {
152127
return "", "", err
153128
}
154-
defer resp.Body.Close()
155-
var r repositoryReply
156-
if err := json.NewDecoder(resp.Body).Decode(&r); err != nil {
129+
130+
rl, _, err := gitHub.Repositories.License(context.TODO(), owner, repo)
131+
if err != nil {
157132
return "", "", err
158133
}
159-
if deblicense, ok := githubLicenseToDebianLicense[r.License.Key]; ok {
134+
135+
if deblicense, ok := githubLicenseToDebianLicense[rl.GetLicense().GetKey()]; ok {
160136
fulltext := debianLicenseText[deblicense]
161137
if fulltext == "" {
162138
fulltext = "TODO"
@@ -168,74 +144,53 @@ func getLicenseForGopkg(gopkg string) (string, string, error) {
168144
}
169145

170146
func getAuthorAndCopyrightForGopkg(gopkg string) (string, string, error) {
171-
repo, err := findGitHubRepo(gopkg)
172-
if err != nil {
173-
return "", "", err
174-
}
175-
resp, err := http.Get("https://api.github.com/repos/" + repo)
147+
owner, repo, err := findGitHubRepo(gopkg)
176148
if err != nil {
177149
return "", "", err
178150
}
179-
defer resp.Body.Close()
180-
181-
var rr repositoryReply
182-
if err := json.NewDecoder(resp.Body).Decode(&rr); err != nil {
183-
return "", "", err
184-
}
185151

186-
creation, err := time.Parse("2006-01-02T15:04:05Z", rr.CreatedAt)
152+
rr, _, err := gitHub.Repositories.Get(context.TODO(), owner, repo)
187153
if err != nil {
188154
return "", "", err
189155
}
190156

191-
if strings.TrimSpace(rr.Owner.URL) == "" {
157+
if strings.TrimSpace(rr.GetOwner().GetURL()) == "" {
192158
return "", "", fmt.Errorf("Repository owner URL not present in API response")
193159
}
194160

195-
resp, err = http.Get(rr.Owner.URL)
161+
ur, _, err := gitHub.Users.Get(context.TODO(), rr.GetOwner().GetLogin())
196162
if err != nil {
197163
return "", "", err
198164
}
199-
defer resp.Body.Close()
200165

201-
var ur usersReply
202-
if err := json.NewDecoder(resp.Body).Decode(&ur); err != nil {
203-
return "", "", err
204-
}
205-
206-
copyright := creation.Format("2006") + " " + ur.Name
166+
copyright := rr.CreatedAt.Format("2006") + " " + ur.GetName()
207167
if strings.HasPrefix(repo, "google/") {
208168
// As per https://opensource.google.com/docs/creating/, Google retains
209169
// the copyright for repositories underneath github.com/google/.
210-
copyright = creation.Format("2006") + " Google Inc."
170+
copyright = rr.CreatedAt.Format("2006") + " Google Inc."
211171
}
212172

213-
return ur.Name, copyright, nil
173+
return ur.GetName(), copyright, nil
214174
}
215175

216176
func getDescriptionForGopkg(gopkg string) (string, error) {
217-
repo, err := findGitHubRepo(gopkg)
177+
owner, repo, err := findGitHubRepo(gopkg)
218178
if err != nil {
219179
return "", err
220180
}
221-
resp, err := http.Get("https://api.github.com/repos/" + repo)
222-
if err != nil {
223-
return "", err
224-
}
225-
defer resp.Body.Close()
226181

227-
var rr repositoryReply
228-
if err := json.NewDecoder(resp.Body).Decode(&rr); err != nil {
182+
rr, _, err := gitHub.Repositories.Get(context.TODO(), owner, repo)
183+
if err != nil {
229184
return "", err
230185
}
231186

232-
return strings.TrimSpace(rr.Description), nil
187+
return strings.TrimSpace(rr.GetDescription()), nil
233188
}
234189

235190
func getHomepageForGopkg(gopkg string) string {
236-
repo, err := findGitHubRepo(gopkg)
191+
owner, repo, err := findGitHubRepo(gopkg)
237192
if err != nil {
238193
return "TODO"
239194
}
240-
return "https://github.com/" + repo
195+
return "https://github.com/" + owner + "/" + repo
241196
}

0 commit comments

Comments
 (0)