aboutsummaryrefslogtreecommitdiffstats
path: root/plumbing/protocol/packp/uppackreq.go
diff options
context:
space:
mode:
authorMáximo Cuadros <mcuadros@gmail.com>2016-12-01 09:59:19 +0100
committerGitHub <noreply@github.com>2016-12-01 09:59:19 +0100
commitc15bf1dff332873644290db0e186b8f5ad9b8fb2 (patch)
tree1dd79212333823b70f2792ad116864ea127e4a1c /plumbing/protocol/packp/uppackreq.go
parent7de79aef5d4aa3100382d4df3e99525f9949e8d1 (diff)
downloadgo-git-c15bf1dff332873644290db0e186b8f5ad9b8fb2.tar.gz
capabilities: full integration (#151)
* format/pktline: fix readPayloadLen err handling * protocol/pakp: UploadReq validation and creation of capabilities * protocol/pakp: AdvRef tests * protocol/pakp: capability.List.Delete * protocol: filter unsupported capabilities * remote capability negociation * transport: UploadRequest validation * requested changes
Diffstat (limited to 'plumbing/protocol/packp/uppackreq.go')
-rw-r--r--plumbing/protocol/packp/uppackreq.go84
1 files changed, 84 insertions, 0 deletions
diff --git a/plumbing/protocol/packp/uppackreq.go b/plumbing/protocol/packp/uppackreq.go
new file mode 100644
index 0000000..2b1cb84
--- /dev/null
+++ b/plumbing/protocol/packp/uppackreq.go
@@ -0,0 +1,84 @@
+package packp
+
+import (
+ "fmt"
+ "io"
+
+ "gopkg.in/src-d/go-git.v4/plumbing"
+ "gopkg.in/src-d/go-git.v4/plumbing/format/pktline"
+ "gopkg.in/src-d/go-git.v4/plumbing/protocol/packp/capability"
+)
+
+// UploadPackRequest represents a upload-pack request.
+// Zero-value is not safe, use NewUploadPackRequest instead.
+type UploadPackRequest struct {
+ *UploadRequest
+ *UploadHaves
+}
+
+// NewUploadPackRequest creates a new UploadPackRequest and returns a pointer.
+func NewUploadPackRequest() *UploadPackRequest {
+ return &UploadPackRequest{
+ UploadHaves: &UploadHaves{},
+ UploadRequest: NewUploadRequest(),
+ }
+}
+
+// NewUploadPackRequestFromCapabilities creates a new UploadPackRequest and
+// returns a pointer. The request capabilities are filled with the most optiomal
+// ones, based on the adv value (advertaised capabilities), the UploadPackRequest
+// it has no wants, haves or shallows and an infinite depth
+func NewUploadPackRequestFromCapabilities(adv *capability.List) *UploadPackRequest {
+ return &UploadPackRequest{
+ UploadHaves: &UploadHaves{},
+ UploadRequest: NewUploadRequestFromCapabilities(adv),
+ }
+}
+
+// IsEmpty a request if empty if Haves are contained in the Wants, or if Wants
+// length is zero
+func (r *UploadPackRequest) IsEmpty() bool {
+ return isSubset(r.Wants, r.Haves)
+}
+
+func isSubset(needle []plumbing.Hash, haystack []plumbing.Hash) bool {
+ for _, h := range needle {
+ found := false
+ for _, oh := range haystack {
+ if h == oh {
+ found = true
+ break
+ }
+ }
+
+ if !found {
+ return false
+ }
+ }
+
+ return true
+}
+
+// UploadHaves is a message to signal the references that a client has in a
+// upload-pack. Do not use this directly. Use UploadPackRequest request instead.
+type UploadHaves struct {
+ Haves []plumbing.Hash
+}
+
+// Encode encodes the UploadHaves into the Writer.
+func (u *UploadHaves) Encode(w io.Writer) error {
+ e := pktline.NewEncoder(w)
+ for _, have := range u.Haves {
+ if err := e.Encodef("have %s\n", have); err != nil {
+ return fmt.Errorf("sending haves for %q: %s", have, err)
+ }
+ }
+
+ if len(u.Haves) != 0 {
+ if err := e.Flush(); err != nil {
+ return fmt.Errorf("sending flush-pkt after haves: %s", err)
+ }
+ }
+
+ return nil
+}