Skip to content

Commit 77e0cc2

Browse files
committed
cmd/go/internal/modfetch: update for new gitrepo backend
Drop API-based access to Bitbucket, Gerrit, GitHub, now that we can (again) talk directly to their Git repos. Also drop general LatestAt query in favor of plain Latest (at current time on default branch), which is all that we needed and all that makes sense when talking directly to Git servers. For golang/go#24915 (still need hg, svn, bzr, fossil). Fixes golang/go#23955 (no GitHub API calls, so no rate limits). Fixes golang/go#24085 (no GitHub API calls, so no 403 responses). Fixes golang/go#24076 (GitHub enterprise's go-get=1 pages are now OK). Fixes golang/go#24102 (no more canonical GitHub import path checks). Change-Id: I99fadb09a565398da3ec88f17691217aca7bf571 Reviewed-on: https://go-review.googlesource.com/107657 Run-TryBot: Russ Cox <[email protected]> Reviewed-by: Bryan C. Mills <[email protected]>
1 parent 4d9b028 commit 77e0cc2

File tree

13 files changed

+80
-840
lines changed

13 files changed

+80
-840
lines changed

vendor/cmd/go/internal/modfetch/bitbucket/fetch.go

+3-159
Original file line numberDiff line numberDiff line change
@@ -6,173 +6,17 @@ package bitbucket
66

77
import (
88
"fmt"
9-
"io"
10-
"net/http"
11-
"net/url"
129
"strings"
13-
"time"
1410

1511
"cmd/go/internal/modfetch/codehost"
16-
web "cmd/go/internal/web2"
12+
"cmd/go/internal/modfetch/gitrepo"
1713
)
1814

1915
func Lookup(path string) (codehost.Repo, error) {
2016
f := strings.Split(path, "/")
2117
if len(f) < 3 || f[0] != "bitbucket.org" {
2218
return nil, fmt.Errorf("bitbucket repo must be bitbucket.org/org/project")
2319
}
24-
25-
// Check for moved, renamed, or incorrect case in repository.
26-
// Otherwise the API calls all appear to work.
27-
// We need to do better here, but it's unclear exactly what.
28-
var data struct {
29-
FullName string `json:"full_name"`
30-
}
31-
err := web.Get("https://api.bitbucket.org/2.0/repositories/"+url.PathEscape(f[1])+"/"+url.PathEscape(f[2]), web.DecodeJSON(&data))
32-
if err != nil {
33-
return nil, err
34-
}
35-
myFullName := f[1] + "/" + f[2]
36-
if myFullName != data.FullName {
37-
why := "moved"
38-
if strings.EqualFold(myFullName, data.FullName) {
39-
why = "wrong case"
40-
}
41-
return nil, fmt.Errorf("module path of repo is bitbucket.org/%s, not %s (%s)", data.FullName, path, why)
42-
}
43-
44-
return newRepo(f[1], f[2]), nil
45-
}
46-
47-
func newRepo(owner, repository string) codehost.Repo {
48-
return &repo{owner: owner, repo: repository}
49-
}
50-
51-
type repo struct {
52-
owner string
53-
repo string
54-
}
55-
56-
func (r *repo) Root() string {
57-
return "bitbucket.org/" + r.owner + "/" + r.repo
58-
}
59-
60-
func (r *repo) Tags(prefix string) ([]string, error) {
61-
var tags []string
62-
u := "https://api.bitbucket.org/2.0/repositories/" + url.PathEscape(r.owner) + "/" + url.PathEscape(r.repo) + "/refs/tags"
63-
var data struct {
64-
Values []struct {
65-
Name string `json:"name"`
66-
} `json:"values"`
67-
}
68-
var hdr http.Header
69-
err := web.Get(u, web.Header(&hdr), web.DecodeJSON(&data))
70-
if err != nil {
71-
return nil, err
72-
}
73-
for _, t := range data.Values {
74-
if strings.HasPrefix(t.Name, prefix) {
75-
tags = append(tags, t.Name)
76-
}
77-
}
78-
return tags, nil
79-
}
80-
81-
func (r *repo) LatestAt(t time.Time, branch string) (*codehost.RevInfo, error) {
82-
u := "https://api.bitbucket.org/2.0/repositories/" + url.PathEscape(r.owner) + "/" + url.PathEscape(r.repo) + "/commits/" + url.QueryEscape(branch) + "?pagelen=10"
83-
for u != "" {
84-
var commits struct {
85-
Values []struct {
86-
Hash string `json:"hash"`
87-
Date string `json:"date"`
88-
} `json:"values"`
89-
Next string `json:"next"`
90-
}
91-
err := web.Get(u, web.DecodeJSON(&commits))
92-
if err != nil {
93-
return nil, err
94-
}
95-
if len(commits.Values) == 0 {
96-
return nil, fmt.Errorf("no commits")
97-
}
98-
for _, commit := range commits.Values {
99-
d, err := time.Parse(time.RFC3339, commit.Date)
100-
if err != nil {
101-
return nil, err
102-
}
103-
if d.Before(t) {
104-
info := &codehost.RevInfo{
105-
Name: commit.Hash,
106-
Short: codehost.ShortenSHA1(commit.Hash),
107-
Time: d,
108-
}
109-
return info, nil
110-
}
111-
}
112-
u = commits.Next
113-
}
114-
return nil, fmt.Errorf("no commits")
115-
}
116-
117-
func (r *repo) Stat(rev string) (*codehost.RevInfo, error) {
118-
var tag string
119-
if !codehost.AllHex(rev) {
120-
tag = rev
121-
}
122-
var commit struct {
123-
Hash string `json:"hash"`
124-
Type string `json:"type"`
125-
Date string `json:"date"`
126-
}
127-
err := web.Get(
128-
"https://api.bitbucket.org/2.0/repositories/"+url.PathEscape(r.owner)+"/"+url.PathEscape(r.repo)+"/commit/"+rev,
129-
web.DecodeJSON(&commit),
130-
)
131-
if err != nil {
132-
return nil, err
133-
}
134-
rev = commit.Hash
135-
if rev == "" {
136-
return nil, fmt.Errorf("no commits")
137-
}
138-
d, err := time.Parse(time.RFC3339, commit.Date)
139-
if err != nil {
140-
return nil, err
141-
}
142-
info := &codehost.RevInfo{
143-
Name: rev,
144-
Short: codehost.ShortenSHA1(rev),
145-
Version: tag,
146-
Time: d,
147-
}
148-
return info, nil
149-
}
150-
151-
func (r *repo) ReadFile(rev, file string, maxSize int64) ([]byte, error) {
152-
// TODO: Use maxSize.
153-
// TODO: I could not find an API endpoint for getting information about an
154-
// individual file, and I do not know if the raw file download endpoint is
155-
// a stable API.
156-
var body []byte
157-
err := web.Get(
158-
"https://bitbucket.org/"+url.PathEscape(r.owner)+"/"+url.PathEscape(r.repo)+"/raw/"+url.PathEscape(rev)+"/"+url.PathEscape(file),
159-
web.ReadAllBody(&body),
160-
)
161-
return body, err
162-
}
163-
164-
func (r *repo) ReadZip(rev, subdir string, maxSize int64) (zip io.ReadCloser, actualSubdir string, err error) {
165-
// TODO: Make web.Get copy to file for us, with limit.
166-
var body io.ReadCloser
167-
err = web.Get(
168-
"https://bitbucket.org/"+url.PathEscape(r.owner)+"/"+url.PathEscape(r.repo)+"/get/"+url.PathEscape(rev)+".zip",
169-
web.Body(&body),
170-
)
171-
if err != nil {
172-
if body != nil {
173-
body.Close()
174-
}
175-
return nil, "", err
176-
}
177-
return body, "", nil
20+
path = f[0] + "/" + f[1] + "/" + f[2]
21+
return gitrepo.Repo("https://"+path, path)
17822
}

vendor/cmd/go/internal/modfetch/codehost/codehost.go

+3-5
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,9 @@ type Repo interface {
2929
// commit hash, branch, tag, and so on.
3030
Stat(rev string) (*RevInfo, error)
3131

32-
// LatestAt returns the latest revision at the given time.
33-
// If branch is non-empty, it restricts the query to revisions
34-
// on the named branch. The meaning of "branch" depends
35-
// on the underlying implementation.
36-
LatestAt(t time.Time, branch string) (*RevInfo, error)
32+
// Latest returns the latest revision on the default branch,
33+
// whatever that means in the underlying implementation.
34+
Latest() (*RevInfo, error)
3735

3836
// ReadFile reads the given file in the file tree corresponding to revision rev.
3937
// It should refuse to read more than maxSize bytes.

vendor/cmd/go/internal/modfetch/coderepo.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,8 @@ func (r *codeRepo) Stat(rev string) (*RevInfo, error) {
113113
return r.convert(info)
114114
}
115115

116-
func (r *codeRepo) LatestAt(t time.Time, branch string) (*RevInfo, error) {
117-
info, err := r.code.LatestAt(t, branch)
116+
func (r *codeRepo) Latest() (*RevInfo, error) {
117+
info, err := r.code.Latest()
118118
if err != nil {
119119
return nil, err
120120
}

vendor/cmd/go/internal/modfetch/coderepo_test.go

+34-68
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"cmd/go/internal/webtest"
1111
"io"
1212
"io/ioutil"
13+
"log"
1314
"os"
1415
"reflect"
1516
"strings"
@@ -21,6 +22,21 @@ func init() {
2122
isTest = true
2223
}
2324

25+
func TestMain(m *testing.M) {
26+
os.Exit(testMain(m))
27+
}
28+
29+
func testMain(m *testing.M) int {
30+
dir, err := ioutil.TempDir("", "gitrepo-test-")
31+
if err != nil {
32+
log.Fatal(err)
33+
}
34+
defer os.RemoveAll(dir)
35+
36+
codehost.WorkRoot = dir
37+
return m.Run()
38+
}
39+
2440
var codeRepoTests = []struct {
2541
path string
2642
lookerr string
@@ -119,12 +135,12 @@ var codeRepoTests = []struct {
119135
{
120136
path: "github.com/rsc/vgotest1/submod",
121137
rev: "v1.0.0",
122-
err: "404 Not Found", // TODO
138+
err: "unknown revision \"submod/v1.0.0\"",
123139
},
124140
{
125141
path: "github.com/rsc/vgotest1/submod",
126142
rev: "v1.0.3",
127-
err: "404 Not Found", // TODO
143+
err: "unknown revision \"submod/v1.0.3\"",
128144
},
129145
{
130146
path: "github.com/rsc/vgotest1/submod",
@@ -228,16 +244,6 @@ var codeRepoTests = []struct {
228244
time: time.Date(2018, 2, 14, 0, 45, 20, 0, time.UTC),
229245
gomod: "module \"rsc.io/quote\"\n",
230246
},
231-
{
232-
// redirect to bitbucket
233-
path: "example.net/vgotest",
234-
rev: "v1.0.0",
235-
version: "v1.0.0",
236-
name: "9152736a7559a4b73ca45d36fe457cb617c3b207",
237-
short: "9152736a7559",
238-
time: time.Date(2017, 8, 22, 3, 10, 13, 0, time.UTC),
239-
gomod: "module \"example.net/vgotest\"\n",
240-
},
241247
{
242248
// redirect to static hosting proxy
243249
path: "swtch.com/testmod",
@@ -308,13 +314,13 @@ var codeRepoTests = []struct {
308314
gomod: "module \"gopkg.in/yaml.v2\"\n\nrequire (\n\t\"gopkg.in/check.v1\" v0.0.0-20161208181325-20d25e280405\n)\n",
309315
},
310316
{
311-
path: "github.com/gobuffalo/buffalo",
312-
rev: "development",
313-
version: "v0.0.0-20180406185414-59b4005674b6",
314-
name: "59b4005674b633728e2bfc3bb09cc204f7c2d6f5",
315-
short: "59b4005674b6",
316-
time: time.Date(2018, 4, 6, 18, 54, 14, 0, time.UTC),
317-
gomod: "//vgo 0.0.4\n\nmodule github.com/gobuffalo/buffalo\n",
317+
path: "vcs-test.golang.org/go/mod/gitrepo1",
318+
rev: "master",
319+
version: "v0.0.0-20180417194322-ede458df7cd0",
320+
name: "ede458df7cd0fdca520df19a33158086a8a68e81",
321+
short: "ede458df7cd0",
322+
time: time.Date(2018, 4, 17, 19, 43, 22, 0, time.UTC),
323+
gomod: "//vgo 0.0.4\n\nmodule vcs-test.golang.org/go/mod/gitrepo1\n",
318324
},
319325
}
320326

@@ -528,63 +534,26 @@ func TestCodeRepoVersions(t *testing.T) {
528534
}
529535
}
530536

531-
var latestAtTests = []struct {
537+
var latestTests = []struct {
532538
path string
533-
time time.Time
534-
branch string
535539
version string
536540
err string
537541
}{
538542
{
539-
path: "github.com/rsc/vgotest1",
540-
time: time.Date(2018, 1, 20, 0, 0, 0, 0, time.UTC),
543+
path: "github.com/rsc/empty",
541544
err: "no commits",
542545
},
543546
{
544547
path: "github.com/rsc/vgotest1",
545-
time: time.Date(2018, 2, 20, 0, 0, 0, 0, time.UTC),
546548
version: "v0.0.0-20180219223237-a08abb797a67",
547549
},
548-
{
549-
path: "github.com/rsc/vgotest1",
550-
time: time.Date(2018, 2, 20, 0, 0, 0, 0, time.UTC),
551-
branch: "mybranch",
552-
version: "v0.0.0-20180219231006-80d85c5d4d17",
553-
},
554550
{
555551
path: "swtch.com/testmod",
556-
time: time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC),
557-
version: "v1.0.0",
558-
},
559-
{
560-
path: "swtch.com/testmod",
561-
time: time.Date(3000, 1, 1, 0, 0, 0, 0, time.UTC),
562552
version: "v1.1.1",
563553
},
564-
{
565-
path: "swtch.com/testmod",
566-
time: time.Date(3000, 1, 1, 0, 0, 0, 0, time.UTC),
567-
branch: "branch",
568-
err: "latest on branch not supported",
569-
},
570-
{
571-
path: "gopkg.in/check.v1",
572-
time: time.Date(2018, 2, 20, 15, 53, 33, 0, time.UTC),
573-
version: "v0.0.0-20161208181325-20d25e280405",
574-
},
575-
{
576-
path: "gopkg.in/yaml.v2",
577-
time: time.Date(2018, 2, 20, 15, 53, 33, 0, time.UTC),
578-
version: "v0.0.0-20180109114331-d670f9405373",
579-
},
580-
{
581-
path: "gopkg.in/russross/blackfriday.v2",
582-
time: time.Date(2018, 2, 20, 15, 53, 33, 0, time.UTC),
583-
version: "v0.0.0-20180212083338-119f356b88f8",
584-
},
585554
}
586555

587-
func TestLatestAt(t *testing.T) {
556+
func TestLatest(t *testing.T) {
588557
webtest.LoadOnce("testdata/webtest.txt")
589558
webtest.Hook()
590559
defer webtest.Unhook()
@@ -594,28 +563,25 @@ func TestLatestAt(t *testing.T) {
594563
t.Fatal(err)
595564
}
596565
defer os.RemoveAll(tmpdir)
597-
for _, tt := range latestAtTests {
598-
name := strings.Replace(tt.path, "/", "_", -1) + "/" + tt.time.Format("2006-01-02_15:04:05")
599-
if tt.branch != "" {
600-
name += "/" + tt.branch
601-
}
566+
for _, tt := range latestTests {
567+
name := strings.Replace(tt.path, "/", "_", -1)
602568
t.Run(name, func(t *testing.T) {
603569
repo, err := Lookup(tt.path)
604570
if err != nil {
605571
t.Fatalf("Lookup(%q): %v", tt.path, err)
606572
}
607-
info, err := repo.LatestAt(tt.time, tt.branch)
573+
info, err := repo.Latest()
608574
if err != nil {
609575
if tt.err != "" {
610576
if err.Error() == tt.err {
611577
return
612578
}
613-
t.Fatalf("LatestAt(%v, %q): %v, want %q", tt.time, tt.branch, err, tt.err)
579+
t.Fatalf("Latest(): %v, want %q", err, tt.err)
614580
}
615-
t.Fatalf("LatestAt(%v, %q): %v", tt.time, tt.branch, err)
581+
t.Fatalf("Latest(): %v", err)
616582
}
617583
if info.Version != tt.version {
618-
t.Fatalf("LatestAt(%v, %q) = %v, want %v", tt.time, tt.branch, info.Version, tt.version)
584+
t.Fatalf("Latest() = %v, want %v", info.Version, tt.version)
619585
}
620586
})
621587
}

0 commit comments

Comments
 (0)