diff options
-rw-r--r-- | clients/common/common.go | 75 | ||||
-rw-r--r-- | clients/common/common_test.go | 39 | ||||
-rw-r--r-- | common_test.go | 5 | ||||
-rw-r--r-- | remote.go | 7 |
4 files changed, 105 insertions, 21 deletions
diff --git a/clients/common/common.go b/clients/common/common.go index 0140847..105e242 100644 --- a/clients/common/common.go +++ b/clients/common/common.go @@ -50,6 +50,40 @@ func parseCapabilities(line string) Capabilities { return Capabilities(values) } +func (c Capabilities) Decode(raw string) { + parts := strings.SplitN(raw, "HEAD", 2) + if len(parts) == 2 { + raw = parts[1] + } + + params := strings.Split(raw, " ") + for _, p := range params { + s := strings.SplitN(p, "=", 2) + + var value string + if len(s) == 2 { + value = s[1] + } + + c[s[0]] = append(c[s[0]], value) + } +} + +func (c Capabilities) String() string { + var o string + for key, values := range c { + if len(values) == 0 { + o += key + " " + } + + for _, value := range values { + o += fmt.Sprintf("%s=%s ", key, value) + } + } + + return o[:len(o)-1] +} + // Supports returns true if capability is preent func (r Capabilities) Supports(capability string) bool { _, ok := r[capability] @@ -81,14 +115,10 @@ func (r Capabilities) SymbolicReference(sym string) string { return "" } -type RemoteHead struct { - Id internal.Hash - Name string -} - type GitUploadPackInfo struct { Capabilities Capabilities - Refs map[string]*RemoteHead + Head string + Refs map[string]internal.Hash } func NewGitUploadPackInfo(d *pktline.Decoder) (*GitUploadPackInfo, error) { @@ -111,14 +141,15 @@ func (r *GitUploadPackInfo) read(d *pktline.Decoder) error { } isEmpty := true - r.Refs = map[string]*RemoteHead{} + r.Refs = map[string]internal.Hash{} for _, line := range lines { if !r.isValidLine(line) { continue } if r.Capabilities == nil { - r.Capabilities = parseCapabilities(line) + r.Capabilities = Capabilities{} + r.Capabilities.Decode(line) continue } @@ -142,17 +173,31 @@ func (r *GitUploadPackInfo) isValidLine(line string) bool { } func (r *GitUploadPackInfo) readLine(line string) { - rh := r.getRemoteHead(line) - r.Refs[rh.Name] = rh -} - -func (r *GitUploadPackInfo) getRemoteHead(line string) *RemoteHead { parts := strings.Split(strings.Trim(line, " \n"), " ") if len(parts) != 2 { - return nil + return } - return &RemoteHead{internal.NewHash(parts[0]), parts[1]} + r.Refs[parts[1]] = internal.NewHash(parts[0]) +} + +func (r *GitUploadPackInfo) String() string { + return string(r.Bytes()) +} + +func (r *GitUploadPackInfo) Bytes() []byte { + e := pktline.NewEncoder() + e.AddLine("# service=git-upload-pack") + e.AddFlush() + e.AddLine(fmt.Sprintf("%s HEAD%s", r.Refs[r.Head], r.Capabilities.String())) + + for name, id := range r.Refs { + e.AddLine(fmt.Sprintf("%s %s", id, name)) + } + + e.AddFlush() + b, _ := ioutil.ReadAll(e.Reader()) + return b } type GitUploadPackRequest struct { diff --git a/clients/common/common_test.go b/clients/common/common_test.go index b397ac9..ab2de7c 100644 --- a/clients/common/common_test.go +++ b/clients/common/common_test.go @@ -49,8 +49,7 @@ func (s *SuiteCommon) TestGitUploadPackInfo(c *C) { ref := info.Capabilities.SymbolicReference("HEAD") c.Assert(ref, Equals, "refs/heads/master") - c.Assert(info.Refs[ref].Id.String(), Equals, "6ecf0ef2c2dffb796033e5a02219af86ec6584e5") - c.Assert(info.Refs[ref].Name, Equals, "refs/heads/master") + c.Assert(info.Refs[ref].String(), Equals, "6ecf0ef2c2dffb796033e5a02219af86ec6584e5") } func (s *SuiteCommon) TestGitUploadPackInfoEmpty(c *C) { @@ -59,6 +58,42 @@ func (s *SuiteCommon) TestGitUploadPackInfoEmpty(c *C) { c.Assert(err, ErrorMatches, "permanent.*empty.*") } +func (s *SuiteCommon) TestCapabilitiesDecode(c *C) { + cap := Capabilities{} + cap.Decode("symref=foo symref=qux thin-pack") + + c.Assert(cap, HasLen, 2) + c.Assert(cap["symref"], DeepEquals, []string{"foo", "qux"}) + c.Assert(cap["thin-pack"], DeepEquals, []string{""}) +} + +func (s *SuiteCommon) TestCapabilitiesString(c *C) { + cap := Capabilities{ + "symref": []string{"foo", "qux"}, + } + + c.Assert(cap.String(), Equals, "symref=foo symref=qux") +} + +func (s *SuiteCommon) TestGitUploadPackEncode(c *C) { + info := &GitUploadPackInfo{} + info.Capabilities = map[string][]string{ + "symref": []string{"HEAD:refs/heads/master"}, + } + + info.Head = "refs/heads/master" + info.Refs = map[string]internal.Hash{ + "refs/heads/master": internal.NewHash("6ecf0ef2c2dffb796033e5a02219af86ec6584e5"), + } + + c.Assert(info.String(), Equals, + "001e# service=git-upload-pack\n"+ + "0000004f6ecf0ef2c2dffb796033e5a02219af86ec6584e5 HEADsymref=HEAD:refs/heads/master\n"+ + "003f6ecf0ef2c2dffb796033e5a02219af86ec6584e5 refs/heads/master\n"+ + "0000", + ) +} + func (s *SuiteCommon) TestGitUploadPackRequest(c *C) { r := &GitUploadPackRequest{ Want: []internal.Hash{ diff --git a/common_test.go b/common_test.go index 446bc16..612afd1 100644 --- a/common_test.go +++ b/common_test.go @@ -28,9 +28,8 @@ func (s *MockGitUploadPackService) Info() (*common.GitUploadPackInfo, error) { return &common.GitUploadPackInfo{ Capabilities: common.Capabilities(values), - Refs: map[string]*common.RemoteHead{ - "refs/heads/master": &common.RemoteHead{Id: hash}, - }, + Head: "refs/heads/master", + Refs: map[string]internal.Hash{"refs/heads/master": hash}, }, nil } @@ -77,5 +77,10 @@ func (r *Remote) Ref(refName string) (internal.Hash, error) { return internal.NewHash(""), fmt.Errorf("unable to find ref %q", refName) } - return ref.Id, nil + return ref, nil +} + +// Refs returns the Hash pointing the given refName +func (r *Remote) Refs() map[string]internal.Hash { + return r.upInfo.Refs } |