Skip to content
This repository was archived by the owner on Sep 11, 2020. It is now read-only.

Commit c8c4a69

Browse files
committed
Add install protocols capabilities to GitUploadPackService
1 parent bf98b60 commit c8c4a69

File tree

8 files changed

+136
-71
lines changed

8 files changed

+136
-71
lines changed

clients/common.go

Lines changed: 49 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,69 @@
1+
// Go-git needs the packfile and the refs of the repo. The
2+
// `NewGitUploadPackService` function returns an object that allows to
3+
// download them.
4+
//
5+
// Go-git supports HTTP and SSH (see `KnownProtocols`) for downloading
6+
// the packfile and the refs, but you can also install your own
7+
// protocols (see `InstallProtocol` below).
8+
//
9+
// Each protocol has its own implementation of
10+
// `NewGitUploadPackService`, but you should generally not use them
11+
// directly, use this package's `NewGitUploadPackService` instead.
112
package clients
213

314
import (
415
"fmt"
516
"net/url"
617

718
"gopkg.in/src-d/go-git.v2/clients/common"
8-
"gopkg.in/src-d/go-git.v2/clients/file"
919
"gopkg.in/src-d/go-git.v2/clients/http"
1020
"gopkg.in/src-d/go-git.v2/clients/ssh"
1121
)
1222

23+
// ServiceFromURLFunc defines a service returning function for a given
24+
// URL.
25+
type ServiceFromURLFunc func(url string) common.GitUploadPackService
26+
27+
// DefaultProtocols are the protocols supported by default.
28+
// Wrapping is needed because you can not cast a function that
29+
// returns an implementation of an interface to a function that
30+
// returns the interface.
31+
var DefaultProtocols = map[string]ServiceFromURLFunc{
32+
"http": func(s string) common.GitUploadPackService { return http.NewGitUploadPackService(s) },
33+
"https": func(s string) common.GitUploadPackService { return http.NewGitUploadPackService(s) },
34+
"ssh": func(s string) common.GitUploadPackService { return ssh.NewGitUploadPackService(s) },
35+
}
36+
37+
// KnownProtocols holds the current set of known protocols. Initially
38+
// it gets its contents from `DefaultProtocols`. See `InstallProtocol`
39+
// below to add or modify this variable.
40+
var KnownProtocols = make(map[string]ServiceFromURLFunc, len(DefaultProtocols))
41+
42+
func init() {
43+
for k, v := range DefaultProtocols {
44+
KnownProtocols[k] = v
45+
}
46+
}
47+
1348
// NewGitUploadPackService returns the appropiate upload pack service
14-
// among of the set of supported protocols: HTTP, SSH or file.
15-
// TODO: should this get a scheme as an argument instead of an URL?
49+
// among of the set of known protocols: HTTP, SSH. See `InstallProtocol`
50+
// to add or modify protocols.
1651
func NewGitUploadPackService(repoURL string) (common.GitUploadPackService, error) {
1752
u, err := url.Parse(repoURL)
1853
if err != nil {
1954
return nil, fmt.Errorf("invalid url %q", repoURL)
2055
}
21-
switch u.Scheme {
22-
case "http", "https":
23-
return http.NewGitUploadPackService(), nil
24-
case "ssh":
25-
return ssh.NewGitUploadPackService(), nil
26-
case "file":
27-
return file.NewGitUploadPackService(), nil
28-
default:
56+
srvFn, ok := KnownProtocols[u.Scheme]
57+
if !ok {
2958
return nil, fmt.Errorf("unsupported scheme %q", u.Scheme)
3059
}
60+
return srvFn(repoURL), nil
61+
}
62+
63+
// InstallProtocol adds or modifies an existing protocol.
64+
func InstallProtocol(scheme string, serviceFn ServiceFromURLFunc) {
65+
if serviceFn == nil {
66+
panic("nil service")
67+
}
68+
KnownProtocols[scheme] = serviceFn
3169
}

clients/common_test.go

Lines changed: 56 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@ package clients
22

33
import (
44
"fmt"
5+
"io"
56
"testing"
67

78
. "gopkg.in/check.v1"
9+
"gopkg.in/src-d/go-git.v2/clients/common"
810
)
911

1012
func Test(t *testing.T) { TestingT(t) }
@@ -19,20 +21,68 @@ func (s *SuiteCommon) TestNewGitUploadPackService(c *C) {
1921
err bool
2022
expected string
2123
}{
22-
{"ht/ml://example.com", true, "<nil>"},
23-
{"", true, "<nil>"},
24-
{"-", true, "<nil>"},
25-
{"!@", true, "<nil>"},
24+
{"://example.com", true, "<nil>"},
2625
{"badscheme://github.com/src-d/go-git", true, "<nil>"},
2726
{"http://github.com/src-d/go-git", false, "*http.GitUploadPackService"},
2827
{"https://github.com/src-d/go-git", false, "*http.GitUploadPackService"},
2928
{"ssh://github.com/src-d/go-git", false, "*ssh.GitUploadPackService"},
30-
{"file://github.com/src-d/go-git", false, "*file.GitUploadPackService"},
3129
}
3230

3331
for i, t := range tests {
3432
output, err := NewGitUploadPackService(t.input)
3533
c.Assert(err != nil, Equals, t.err, Commentf("%d) %q: wrong error value", i, t.input))
36-
c.Assert(fmt.Sprintf("%T", output), Equals, t.expected, Commentf("%d) %q: wrong type", i, t.input))
34+
c.Assert(typeAsString(output), Equals, t.expected, Commentf("%d) %q: wrong type", i, t.input))
3735
}
3836
}
37+
38+
type dummyProtocolService struct{}
39+
40+
func newDummyProtocolService(url string) common.GitUploadPackService {
41+
return &dummyProtocolService{}
42+
}
43+
44+
func (s *dummyProtocolService) Connect(url common.Endpoint) error {
45+
return nil
46+
}
47+
48+
func (s *dummyProtocolService) ConnectWithAuth(url common.Endpoint, auth common.AuthMethod) error {
49+
return nil
50+
}
51+
52+
func (s *dummyProtocolService) Info() (*common.GitUploadPackInfo, error) {
53+
return nil, nil
54+
}
55+
56+
func (s *dummyProtocolService) Fetch(r *common.GitUploadPackRequest) (io.ReadCloser, error) {
57+
return nil, nil
58+
}
59+
60+
func (s *SuiteCommon) TestInstallProtocol(c *C) {
61+
var tests = [...]struct {
62+
scheme string
63+
serviceFn ServiceFromURLFunc
64+
panic bool
65+
}{
66+
{"panic", nil, true},
67+
{"newscheme", newDummyProtocolService, false},
68+
{"http", newDummyProtocolService, false},
69+
}
70+
71+
for i, t := range tests {
72+
if t.panic {
73+
fmt.Println(t.serviceFn == nil)
74+
c.Assert(func() { InstallProtocol(t.scheme, t.serviceFn) }, PanicMatches, `nil service`)
75+
continue
76+
}
77+
InstallProtocol(t.scheme, t.serviceFn)
78+
c.Assert(typeAsString(KnownProtocols[t.scheme]), Equals, typeAsString(t.serviceFn), Commentf("%d) wrong service", i))
79+
// reset to default protocols after installing
80+
if v, ok := DefaultProtocols[t.scheme]; ok {
81+
InstallProtocol(t.scheme, v)
82+
}
83+
}
84+
}
85+
86+
func typeAsString(v interface{}) string {
87+
return fmt.Sprintf("%T", v)
88+
}

clients/file/git_upload_pack.go

Lines changed: 0 additions & 29 deletions
This file was deleted.

clients/http/git_upload_pack.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ type GitUploadPackService struct {
1818
auth HTTPAuthMethod
1919
}
2020

21-
func NewGitUploadPackService() *GitUploadPackService {
21+
func NewGitUploadPackService(url string) *GitUploadPackService {
22+
// url ignored
2223
return &GitUploadPackService{
2324
Client: http.DefaultClient,
2425
}

clients/http/git_upload_pack_test.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,13 @@ var _ = Suite(&SuiteRemote{})
1515
const RepositoryFixture = "https://github.com/tyba/git-fixture"
1616

1717
func (s *SuiteRemote) TestConnect(c *C) {
18-
r := NewGitUploadPackService()
18+
r := NewGitUploadPackService(RepositoryFixture)
1919
c.Assert(r.Connect(RepositoryFixture), IsNil)
2020
}
2121

2222
func (s *SuiteRemote) TestConnectWithAuth(c *C) {
2323
auth := &BasicAuth{}
24-
r := NewGitUploadPackService()
24+
r := NewGitUploadPackService(RepositoryFixture)
2525
c.Assert(r.ConnectWithAuth(RepositoryFixture, auth), IsNil)
2626
c.Assert(r.auth, Equals, auth)
2727
}
@@ -32,12 +32,12 @@ func (*mockAuth) Name() string { return "" }
3232
func (*mockAuth) String() string { return "" }
3333

3434
func (s *SuiteRemote) TestConnectWithAuthWrongType(c *C) {
35-
r := NewGitUploadPackService()
35+
r := NewGitUploadPackService(RepositoryFixture)
3636
c.Assert(r.ConnectWithAuth(RepositoryFixture, &mockAuth{}), Equals, InvalidAuthMethodErr)
3737
}
3838

3939
func (s *SuiteRemote) TestDefaultBranch(c *C) {
40-
r := NewGitUploadPackService()
40+
r := NewGitUploadPackService(RepositoryFixture)
4141
c.Assert(r.Connect(RepositoryFixture), IsNil)
4242

4343
info, err := r.Info()
@@ -46,7 +46,7 @@ func (s *SuiteRemote) TestDefaultBranch(c *C) {
4646
}
4747

4848
func (s *SuiteRemote) TestCapabilities(c *C) {
49-
r := NewGitUploadPackService()
49+
r := NewGitUploadPackService(RepositoryFixture)
5050
c.Assert(r.Connect(RepositoryFixture), IsNil)
5151

5252
info, err := r.Info()
@@ -55,7 +55,7 @@ func (s *SuiteRemote) TestCapabilities(c *C) {
5555
}
5656

5757
func (s *SuiteRemote) TestFetch(c *C) {
58-
r := NewGitUploadPackService()
58+
r := NewGitUploadPackService(RepositoryFixture)
5959
c.Assert(r.Connect(RepositoryFixture), IsNil)
6060

6161
req := &common.GitUploadPackRequest{}

clients/ssh/git_upload_pack.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ type GitUploadPackService struct {
4242

4343
// NewGitUploadPackService initialises a GitUploadPackService.
4444
// TODO: remove this, as the struct is zero-value safe.
45-
func NewGitUploadPackService() *GitUploadPackService {
45+
func NewGitUploadPackService(url string) *GitUploadPackService {
46+
// url ignored
4647
return &GitUploadPackService{}
4748
}
4849

0 commit comments

Comments
 (0)