aboutsummaryrefslogtreecommitdiffstats
path: root/clients/common
diff options
context:
space:
mode:
authorMáximo Cuadros <mcuadros@gmail.com>2016-11-08 23:46:38 +0100
committerGitHub <noreply@github.com>2016-11-08 23:46:38 +0100
commitac095bb12c4d29722b60ba9f20590fa7cfa6bc7d (patch)
tree223f36f336ba3414b1e45cac8af6c4744a5d7ef6 /clients/common
parente523701393598f4fa241dd407af9ff8925507a1a (diff)
downloadgo-git-ac095bb12c4d29722b60ba9f20590fa7cfa6bc7d.tar.gz
new plumbing package (#118)
* plumbing: now core was renamed to core, and formats and clients moved inside
Diffstat (limited to 'clients/common')
-rw-r--r--clients/common/common.go218
-rw-r--r--clients/common/common_test.go126
2 files changed, 0 insertions, 344 deletions
diff --git a/clients/common/common.go b/clients/common/common.go
deleted file mode 100644
index c7cac00..0000000
--- a/clients/common/common.go
+++ /dev/null
@@ -1,218 +0,0 @@
-// Package common contains interfaces and non-specific protocol entities
-package common
-
-import (
- "bytes"
- "errors"
- "fmt"
- "io"
- "io/ioutil"
- "net/url"
- "regexp"
- "strings"
-
- "gopkg.in/src-d/go-git.v4/core"
- "gopkg.in/src-d/go-git.v4/formats/packp"
- "gopkg.in/src-d/go-git.v4/formats/packp/advrefs"
- "gopkg.in/src-d/go-git.v4/formats/packp/pktline"
- "gopkg.in/src-d/go-git.v4/storage/memory"
-)
-
-var (
- ErrRepositoryNotFound = errors.New("repository not found")
- ErrAuthorizationRequired = errors.New("authorization required")
- ErrEmptyGitUploadPack = errors.New("empty git-upload-pack given")
- ErrInvalidAuthMethod = errors.New("invalid auth method")
-)
-
-const GitUploadPackServiceName = "git-upload-pack"
-
-type GitUploadPackService interface {
- Connect() error
- SetAuth(AuthMethod) error
- Info() (*GitUploadPackInfo, error)
- Fetch(*GitUploadPackRequest) (io.ReadCloser, error)
- Disconnect() error
-}
-
-type AuthMethod interface {
- Name() string
- String() string
-}
-
-type Endpoint url.URL
-
-var (
- isSchemeRegExp = regexp.MustCompile("^[^:]+://")
- scpLikeUrlRegExp = regexp.MustCompile("^(?P<user>[^@]+@)?(?P<host>[^:]+):/?(?P<path>.+)$")
-)
-
-func NewEndpoint(endpoint string) (Endpoint, error) {
- endpoint = transformSCPLikeIfNeeded(endpoint)
-
- u, err := url.Parse(endpoint)
- if err != nil {
- return Endpoint{}, core.NewPermanentError(err)
- }
-
- if !u.IsAbs() {
- return Endpoint{}, core.NewPermanentError(fmt.Errorf(
- "invalid endpoint: %s", endpoint,
- ))
- }
-
- return Endpoint(*u), nil
-}
-
-func transformSCPLikeIfNeeded(endpoint string) string {
- if !isSchemeRegExp.MatchString(endpoint) && scpLikeUrlRegExp.MatchString(endpoint) {
- m := scpLikeUrlRegExp.FindStringSubmatch(endpoint)
- return fmt.Sprintf("ssh://%s%s/%s", m[1], m[2], m[3])
- }
-
- return endpoint
-}
-
-func (e *Endpoint) String() string {
- u := url.URL(*e)
- return u.String()
-}
-
-type GitUploadPackInfo struct {
- Capabilities *packp.Capabilities
- Refs memory.ReferenceStorage
-}
-
-func NewGitUploadPackInfo() *GitUploadPackInfo {
- return &GitUploadPackInfo{
- Capabilities: packp.NewCapabilities(),
- Refs: make(memory.ReferenceStorage, 0),
- }
-}
-
-func (i *GitUploadPackInfo) Decode(r io.Reader) error {
- d := advrefs.NewDecoder(r)
- ar := advrefs.New()
- if err := d.Decode(ar); err != nil {
- if err == advrefs.ErrEmpty {
- return core.NewPermanentError(err)
- }
- return core.NewUnexpectedError(err)
- }
-
- i.Capabilities = ar.Capabilities
-
- if err := i.addRefs(ar); err != nil {
- return core.NewUnexpectedError(err)
- }
-
- return nil
-}
-
-func (i *GitUploadPackInfo) addRefs(ar *advrefs.AdvRefs) error {
- for name, hash := range ar.References {
- ref := core.NewReferenceFromStrings(name, hash.String())
- i.Refs.SetReference(ref)
- }
-
- return i.addSymbolicRefs(ar)
-}
-
-func (i *GitUploadPackInfo) addSymbolicRefs(ar *advrefs.AdvRefs) error {
- if !hasSymrefs(ar) {
- return nil
- }
-
- for _, symref := range ar.Capabilities.Get("symref").Values {
- chunks := strings.Split(symref, ":")
- if len(chunks) != 2 {
- err := fmt.Errorf("bad number of `:` in symref value (%q)", symref)
- return core.NewUnexpectedError(err)
- }
- name := core.ReferenceName(chunks[0])
- target := core.ReferenceName(chunks[1])
- ref := core.NewSymbolicReference(name, target)
- i.Refs.SetReference(ref)
- }
-
- return nil
-}
-
-func hasSymrefs(ar *advrefs.AdvRefs) bool {
- return ar.Capabilities.Supports("symref")
-}
-
-func (i *GitUploadPackInfo) Head() *core.Reference {
- ref, _ := core.ResolveReference(i.Refs, core.HEAD)
- return ref
-}
-
-func (i *GitUploadPackInfo) String() string {
- return string(i.Bytes())
-}
-
-func (i *GitUploadPackInfo) Bytes() []byte {
- var buf bytes.Buffer
- e := pktline.NewEncoder(&buf)
-
- _ = e.EncodeString("# service=git-upload-pack\n")
-
- // inserting a flush-pkt here violates the protocol spec, but some
- // servers do it, like Github.com
- e.Flush()
-
- _ = e.Encodef("%s HEAD\x00%s\n", i.Head().Hash(), i.Capabilities.String())
-
- for _, ref := range i.Refs {
- if ref.Type() != core.HashReference {
- continue
- }
-
- _ = e.Encodef("%s %s\n", ref.Hash(), ref.Name())
- }
-
- e.Flush()
-
- return buf.Bytes()
-}
-
-type GitUploadPackRequest struct {
- Wants []core.Hash
- Haves []core.Hash
- Depth int
-}
-
-func (r *GitUploadPackRequest) Want(h ...core.Hash) {
- r.Wants = append(r.Wants, h...)
-}
-
-func (r *GitUploadPackRequest) Have(h ...core.Hash) {
- r.Haves = append(r.Haves, h...)
-}
-
-func (r *GitUploadPackRequest) String() string {
- b, _ := ioutil.ReadAll(r.Reader())
- return string(b)
-}
-
-func (r *GitUploadPackRequest) Reader() *strings.Reader {
- var buf bytes.Buffer
- e := pktline.NewEncoder(&buf)
-
- for _, want := range r.Wants {
- _ = e.Encodef("want %s\n", want)
- }
-
- for _, have := range r.Haves {
- _ = e.Encodef("have %s\n", have)
- }
-
- if r.Depth != 0 {
- _ = e.Encodef("deepen %d\n", r.Depth)
- }
-
- _ = e.Flush()
- _ = e.EncodeString("done\n")
-
- return strings.NewReader(buf.String())
-}
diff --git a/clients/common/common_test.go b/clients/common/common_test.go
deleted file mode 100644
index 5809584..0000000
--- a/clients/common/common_test.go
+++ /dev/null
@@ -1,126 +0,0 @@
-package common
-
-import (
- "bytes"
- "encoding/base64"
- "testing"
-
- "gopkg.in/src-d/go-git.v4/core"
- "gopkg.in/src-d/go-git.v4/formats/packp"
-
- . "gopkg.in/check.v1"
-)
-
-func Test(t *testing.T) { TestingT(t) }
-
-type SuiteCommon struct{}
-
-var _ = Suite(&SuiteCommon{})
-
-func (s *SuiteCommon) TestNewEndpoint(c *C) {
- e, err := NewEndpoint("ssh://git@github.com/user/repository.git")
- c.Assert(err, IsNil)
- c.Assert(e.String(), Equals, "ssh://git@github.com/user/repository.git")
-}
-
-func (s *SuiteCommon) TestNewEndpointSCPLike(c *C) {
- e, err := NewEndpoint("git@github.com:user/repository.git")
- c.Assert(err, IsNil)
- c.Assert(e.String(), Equals, "ssh://git@github.com/user/repository.git")
-}
-
-func (s *SuiteCommon) TestNewEndpointWrongForgat(c *C) {
- e, err := NewEndpoint("foo")
- c.Assert(err, Not(IsNil))
- c.Assert(e.Host, Equals, "")
-}
-
-const CapabilitiesFixture = "6ecf0ef2c2dffb796033e5a02219af86ec6584e5 HEADmulti_ack thin-pack side-band side-band-64k ofs-delta shallow no-progress include-tag multi_ack_detailed no-done symref=HEAD:refs/heads/master agent=git/2:2.4.8~dbussink-fix-enterprise-tokens-compilation-1167-gc7006cf"
-
-func (s *SuiteCommon) TestCapabilitiesSymbolicReference(c *C) {
- cap := packp.NewCapabilities()
- cap.Decode(CapabilitiesFixture)
- c.Assert(cap.SymbolicReference("HEAD"), Equals, "refs/heads/master")
-}
-
-const GitUploadPackInfoFixture = "MDAxZSMgc2VydmljZT1naXQtdXBsb2FkLXBhY2sKMDAwMDAxMGM2ZWNmMGVmMmMyZGZmYjc5NjAzM2U1YTAyMjE5YWY4NmVjNjU4NGU1IEhFQUQAbXVsdGlfYWNrIHRoaW4tcGFjayBzaWRlLWJhbmQgc2lkZS1iYW5kLTY0ayBvZnMtZGVsdGEgc2hhbGxvdyBuby1wcm9ncmVzcyBpbmNsdWRlLXRhZyBtdWx0aV9hY2tfZGV0YWlsZWQgbm8tZG9uZSBzeW1yZWY9SEVBRDpyZWZzL2hlYWRzL21hc3RlciBhZ2VudD1naXQvMjoyLjQuOH5kYnVzc2luay1maXgtZW50ZXJwcmlzZS10b2tlbnMtY29tcGlsYXRpb24tMTE2Ny1nYzcwMDZjZgowMDNmZThkM2ZmYWI1NTI4OTVjMTliOWZjZjdhYTI2NGQyNzdjZGUzMzg4MSByZWZzL2hlYWRzL2JyYW5jaAowMDNmNmVjZjBlZjJjMmRmZmI3OTYwMzNlNWEwMjIxOWFmODZlYzY1ODRlNSByZWZzL2hlYWRzL21hc3RlcgowMDNlYjhlNDcxZjU4YmNiY2E2M2IwN2JkYTIwZTQyODE5MDQwOWMyZGI0NyByZWZzL3B1bGwvMS9oZWFkCjAwMDA="
-
-func (s *SuiteCommon) TestGitUploadPackInfo(c *C) {
- b, _ := base64.StdEncoding.DecodeString(GitUploadPackInfoFixture)
-
- i := NewGitUploadPackInfo()
- err := i.Decode(bytes.NewBuffer(b))
- c.Assert(err, IsNil)
-
- name := i.Capabilities.SymbolicReference("HEAD")
- c.Assert(name, Equals, "refs/heads/master")
- c.Assert(i.Refs, HasLen, 4)
-
- ref := i.Refs[core.ReferenceName(name)]
- c.Assert(ref, NotNil)
- c.Assert(ref.Hash().String(), Equals, "6ecf0ef2c2dffb796033e5a02219af86ec6584e5")
-
- ref = i.Refs[core.HEAD]
- c.Assert(ref, NotNil)
- c.Assert(ref.Target(), Equals, core.ReferenceName(name))
-}
-
-const GitUploadPackInfoNoHEADFixture = "MDAxZSMgc2VydmljZT1naXQtdXBsb2FkLXBhY2sKMDAwMDAwYmNkN2UxZmVlMjYxMjM0YmIzYTQzYzA5NmY1NTg3NDhhNTY5ZDc5ZWZmIHJlZnMvaGVhZHMvdjQAbXVsdGlfYWNrIHRoaW4tcGFjayBzaWRlLWJhbmQgc2lkZS1iYW5kLTY0ayBvZnMtZGVsdGEgc2hhbGxvdyBuby1wcm9ncmVzcyBpbmNsdWRlLXRhZyBtdWx0aV9hY2tfZGV0YWlsZWQgbm8tZG9uZSBhZ2VudD1naXQvMS45LjEKMDAwMA=="
-
-func (s *SuiteCommon) TestGitUploadPackInfoNoHEAD(c *C) {
- b, _ := base64.StdEncoding.DecodeString(GitUploadPackInfoNoHEADFixture)
-
- i := NewGitUploadPackInfo()
- err := i.Decode(bytes.NewBuffer(b))
- c.Assert(err, IsNil)
-
- name := i.Capabilities.SymbolicReference("HEAD")
- c.Assert(name, Equals, "")
- c.Assert(i.Refs, HasLen, 1)
-
- ref := i.Refs["refs/heads/v4"]
- c.Assert(ref, NotNil)
- c.Assert(ref.Hash().String(), Equals, "d7e1fee261234bb3a43c096f558748a569d79eff")
-}
-
-func (s *SuiteCommon) TestGitUploadPackInfoEmpty(c *C) {
- b := bytes.NewBuffer(nil)
-
- i := NewGitUploadPackInfo()
- err := i.Decode(b)
- c.Assert(err, ErrorMatches, "permanent.*empty.*")
-}
-
-func (s *SuiteCommon) TestGitUploadPackEncode(c *C) {
- info := NewGitUploadPackInfo()
- info.Capabilities.Add("symref", "HEAD:refs/heads/master")
-
- ref := core.ReferenceName("refs/heads/master")
- hash := core.NewHash("6ecf0ef2c2dffb796033e5a02219af86ec6584e5")
- info.Refs = map[core.ReferenceName]*core.Reference{
- core.HEAD: core.NewSymbolicReference(core.HEAD, ref),
- ref: core.NewHashReference(ref, hash),
- }
-
- c.Assert(info.Head(), NotNil)
- c.Assert(info.String(), Equals,
- "001e# service=git-upload-pack\n"+
- "000000506ecf0ef2c2dffb796033e5a02219af86ec6584e5 HEAD\x00symref=HEAD:refs/heads/master\n"+
- "003f6ecf0ef2c2dffb796033e5a02219af86ec6584e5 refs/heads/master\n"+
- "0000",
- )
-}
-
-func (s *SuiteCommon) TestGitUploadPackRequest(c *C) {
- r := &GitUploadPackRequest{}
- r.Want(core.NewHash("d82f291cde9987322c8a0c81a325e1ba6159684c"))
- r.Want(core.NewHash("2b41ef280fdb67a9b250678686a0c3e03b0a9989"))
- r.Have(core.NewHash("6ecf0ef2c2dffb796033e5a02219af86ec6584e5"))
-
- c.Assert(r.String(), Equals,
- "0032want d82f291cde9987322c8a0c81a325e1ba6159684c\n"+
- "0032want 2b41ef280fdb67a9b250678686a0c3e03b0a9989\n"+
- "0032have 6ecf0ef2c2dffb796033e5a02219af86ec6584e5\n0000"+
- "0009done\n",
- )
-}