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

Commit da5ab9d

Browse files
committed
Merge pull request #10 from alcortesm/file-client
Adds external protocol insertion for the clients and protocol selection based on the scheme
2 parents 990573b + c8c4a69 commit da5ab9d

File tree

7 files changed

+180
-27
lines changed

7 files changed

+180
-27
lines changed

clients/common.go

Lines changed: 61 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +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 (
15+
"fmt"
16+
"net/url"
17+
418
"gopkg.in/src-d/go-git.v2/clients/common"
519
"gopkg.in/src-d/go-git.v2/clients/http"
20+
"gopkg.in/src-d/go-git.v2/clients/ssh"
621
)
722

8-
func NewGitUploadPackService() common.GitUploadPackService {
9-
return http.NewGitUploadPackService()
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+
48+
// NewGitUploadPackService returns the appropiate upload pack service
49+
// among of the set of known protocols: HTTP, SSH. See `InstallProtocol`
50+
// to add or modify protocols.
51+
func NewGitUploadPackService(repoURL string) (common.GitUploadPackService, error) {
52+
u, err := url.Parse(repoURL)
53+
if err != nil {
54+
return nil, fmt.Errorf("invalid url %q", repoURL)
55+
}
56+
srvFn, ok := KnownProtocols[u.Scheme]
57+
if !ok {
58+
return nil, fmt.Errorf("unsupported scheme %q", u.Scheme)
59+
}
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
1069
}

clients/common_test.go

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
package clients
2+
3+
import (
4+
"fmt"
5+
"io"
6+
"testing"
7+
8+
. "gopkg.in/check.v1"
9+
"gopkg.in/src-d/go-git.v2/clients/common"
10+
)
11+
12+
func Test(t *testing.T) { TestingT(t) }
13+
14+
type SuiteCommon struct{}
15+
16+
var _ = Suite(&SuiteCommon{})
17+
18+
func (s *SuiteCommon) TestNewGitUploadPackService(c *C) {
19+
var tests = [...]struct {
20+
input string
21+
err bool
22+
expected string
23+
}{
24+
{"://example.com", true, "<nil>"},
25+
{"badscheme://github.com/src-d/go-git", true, "<nil>"},
26+
{"http://github.com/src-d/go-git", false, "*http.GitUploadPackService"},
27+
{"https://github.com/src-d/go-git", false, "*http.GitUploadPackService"},
28+
{"ssh://github.com/src-d/go-git", false, "*ssh.GitUploadPackService"},
29+
}
30+
31+
for i, t := range tests {
32+
output, err := NewGitUploadPackService(t.input)
33+
c.Assert(err != nil, Equals, t.err, Commentf("%d) %q: wrong error value", i, t.input))
34+
c.Assert(typeAsString(output), Equals, t.expected, Commentf("%d) %q: wrong type", i, t.input))
35+
}
36+
}
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/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

clients/ssh/git_upload_pack_test.go

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ const (
2525
)
2626

2727
func (s *SuiteRemote) TestConnect(c *C) {
28-
r := NewGitUploadPackService()
28+
r := NewGitUploadPackService(fixRepo)
2929
c.Assert(r.Connect(fixRepo), Equals, ErrAuthRequired)
3030
}
3131

@@ -62,25 +62,25 @@ func (s *SuiteRemote) TestConnectWithPublicKeysCallback(c *C) {
6262
c.Assert(err, IsNil)
6363
defer func() { c.Assert(agent.close(), IsNil) }()
6464

65-
r := NewGitUploadPackService()
65+
r := NewGitUploadPackService(fixRepo)
6666
c.Assert(r.ConnectWithAuth(fixRepo, agent.auth), IsNil)
6767
defer func() { c.Assert(r.Disconnect(), IsNil) }()
6868
c.Assert(r.connected, Equals, true)
6969
c.Assert(r.auth, Equals, agent.auth)
7070
}
7171

7272
func (s *SuiteRemote) TestConnectBadVcs(c *C) {
73-
r := NewGitUploadPackService()
73+
r := NewGitUploadPackService(fixRepoBadVcs)
7474
c.Assert(r.ConnectWithAuth(fixRepoBadVcs, nil), ErrorMatches, fmt.Sprintf(".*%s.*", fixRepoBadVcs))
7575
}
7676

7777
func (s *SuiteRemote) TestConnectNonGit(c *C) {
78-
r := NewGitUploadPackService()
78+
r := NewGitUploadPackService(fixRepoNonGit)
7979
c.Assert(r.ConnectWithAuth(fixRepoNonGit, nil), Equals, ErrUnsupportedVCS)
8080
}
8181

8282
func (s *SuiteRemote) TestConnectNonGithub(c *C) {
83-
r := NewGitUploadPackService()
83+
r := NewGitUploadPackService(fixGitRepoNonGithub)
8484
c.Assert(r.ConnectWithAuth(fixGitRepoNonGithub, nil), Equals, ErrUnsupportedRepo)
8585
}
8686

@@ -92,7 +92,7 @@ func (*mockAuth) Name() string { return "" }
9292
func (*mockAuth) String() string { return "" }
9393

9494
func (s *SuiteRemote) TestConnectWithAuthWrongType(c *C) {
95-
r := NewGitUploadPackService()
95+
r := NewGitUploadPackService(fixRepo)
9696
c.Assert(r.ConnectWithAuth(fixRepo, &mockAuth{}), Equals, ErrInvalidAuthMethod)
9797
c.Assert(r.connected, Equals, false)
9898
}
@@ -102,7 +102,7 @@ func (s *SuiteRemote) TestAlreadyConnected(c *C) {
102102
c.Assert(err, IsNil)
103103
defer func() { c.Assert(agent.close(), IsNil) }()
104104

105-
r := NewGitUploadPackService()
105+
r := NewGitUploadPackService(fixRepo)
106106
c.Assert(r.ConnectWithAuth(fixRepo, agent.auth), IsNil)
107107
defer func() { c.Assert(r.Disconnect(), IsNil) }()
108108
c.Assert(r.ConnectWithAuth(fixRepo, agent.auth), Equals, ErrAlreadyConnected)
@@ -114,14 +114,14 @@ func (s *SuiteRemote) TestDisconnect(c *C) {
114114
c.Assert(err, IsNil)
115115
defer func() { c.Assert(agent.close(), IsNil) }()
116116

117-
r := NewGitUploadPackService()
117+
r := NewGitUploadPackService(fixRepo)
118118
c.Assert(r.ConnectWithAuth(fixRepo, agent.auth), IsNil)
119119
c.Assert(r.Disconnect(), IsNil)
120120
c.Assert(r.connected, Equals, false)
121121
}
122122

123123
func (s *SuiteRemote) TestDisconnectedWhenNonConnected(c *C) {
124-
r := NewGitUploadPackService()
124+
r := NewGitUploadPackService("Dear Twinkle")
125125
c.Assert(r.Disconnect(), Equals, ErrNotConnected)
126126
}
127127

@@ -130,7 +130,7 @@ func (s *SuiteRemote) TestAlreadyDisconnected(c *C) {
130130
c.Assert(err, IsNil)
131131
defer func() { c.Assert(agent.close(), IsNil) }()
132132

133-
r := NewGitUploadPackService()
133+
r := NewGitUploadPackService(fixRepo)
134134
c.Assert(r.ConnectWithAuth(fixRepo, agent.auth), IsNil)
135135
c.Assert(r.Disconnect(), IsNil)
136136
c.Assert(r.Disconnect(), Equals, ErrNotConnected)
@@ -142,7 +142,7 @@ func (s *SuiteRemote) TestServeralConnections(c *C) {
142142
c.Assert(err, IsNil)
143143
defer func() { c.Assert(agent.close(), IsNil) }()
144144

145-
r := NewGitUploadPackService()
145+
r := NewGitUploadPackService(fixRepo)
146146
c.Assert(r.ConnectWithAuth(fixRepo, agent.auth), IsNil)
147147
c.Assert(r.Disconnect(), IsNil)
148148

@@ -158,7 +158,7 @@ func (s *SuiteRemote) TestServeralConnections(c *C) {
158158
}
159159

160160
func (s *SuiteRemote) TestInfoNotConnected(c *C) {
161-
r := NewGitUploadPackService()
161+
r := NewGitUploadPackService(fixRepo)
162162
_, err := r.Info()
163163
c.Assert(err, Equals, ErrNotConnected)
164164
}
@@ -168,7 +168,7 @@ func (s *SuiteRemote) TestDefaultBranch(c *C) {
168168
c.Assert(err, IsNil)
169169
defer func() { c.Assert(agent.close(), IsNil) }()
170170

171-
r := NewGitUploadPackService()
171+
r := NewGitUploadPackService(fixRepo)
172172
c.Assert(r.ConnectWithAuth(fixRepo, agent.auth), IsNil)
173173
defer func() { c.Assert(r.Disconnect(), IsNil) }()
174174

@@ -182,7 +182,7 @@ func (s *SuiteRemote) TestCapabilities(c *C) {
182182
c.Assert(err, IsNil)
183183
defer func() { c.Assert(agent.close(), IsNil) }()
184184

185-
r := NewGitUploadPackService()
185+
r := NewGitUploadPackService(fixRepo)
186186
c.Assert(r.ConnectWithAuth(fixRepo, agent.auth), IsNil)
187187
defer func() { c.Assert(r.Disconnect(), IsNil) }()
188188

@@ -192,7 +192,7 @@ func (s *SuiteRemote) TestCapabilities(c *C) {
192192
}
193193

194194
func (s *SuiteRemote) TestFetchNotConnected(c *C) {
195-
r := NewGitUploadPackService()
195+
r := NewGitUploadPackService("foo bar")
196196
pr := &common.GitUploadPackRequest{}
197197
pr.Want(core.NewHash("6ecf0ef2c2dffb796033e5a02219af86ec6584e5"))
198198
_, err := r.Fetch(pr)
@@ -204,7 +204,7 @@ func (s *SuiteRemote) TestFetch(c *C) {
204204
c.Assert(err, IsNil)
205205
defer func() { c.Assert(agent.close(), IsNil) }()
206206

207-
r := NewGitUploadPackService()
207+
r := NewGitUploadPackService(fixRepo)
208208
c.Assert(r.ConnectWithAuth(fixRepo, agent.auth), IsNil)
209209
defer func() { c.Assert(r.Disconnect(), IsNil) }()
210210

remote.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,14 @@ func NewAuthenticatedRemote(url string, auth common.AuthMethod) (*Remote, error)
3030
return nil, err
3131
}
3232

33+
upSrv, err := clients.NewGitUploadPackService(url)
34+
if err != nil {
35+
return nil, err
36+
}
3337
return &Remote{
3438
Endpoint: end,
3539
Auth: auth,
36-
upSrv: clients.NewGitUploadPackService(),
40+
upSrv: upSrv,
3741
}, nil
3842
}
3943

0 commit comments

Comments
 (0)