/
updreq.go
128 lines (105 loc) · 2.78 KB
/
updreq.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package packp
import (
"errors"
"io"
"github.com/go-git/go-git/v5/plumbing"
"github.com/go-git/go-git/v5/plumbing/protocol/packp/capability"
"github.com/go-git/go-git/v5/plumbing/protocol/packp/sideband"
)
var (
ErrEmptyCommands = errors.New("commands cannot be empty")
ErrMalformedCommand = errors.New("malformed command")
)
// ReferenceUpdateRequest values represent reference upload requests.
// Values from this type are not zero-value safe, use the New function instead.
type ReferenceUpdateRequest struct {
Capabilities *capability.List
Commands []*Command
Options []*Option
Shallow *plumbing.Hash
// Packfile contains an optional packfile reader.
Packfile io.ReadCloser
// Progress receives sideband progress messages from the server
Progress sideband.Progress
}
// New returns a pointer to a new ReferenceUpdateRequest value.
func NewReferenceUpdateRequest() *ReferenceUpdateRequest {
return &ReferenceUpdateRequest{
// TODO: Add support for push-cert
Capabilities: capability.NewList(),
Commands: nil,
}
}
// NewReferenceUpdateRequestFromCapabilities returns a pointer to a new
// ReferenceUpdateRequest value, the request capabilities are filled with the
// most optimal ones, based on the adv value (advertised capabilities), the
// ReferenceUpdateRequest contains no commands
//
// It does set the following capabilities:
// - agent
// - report-status
// - ofs-delta
// - ref-delta
// - delete-refs
// It leaves up to the user to add the following capabilities later:
// - atomic
// - ofs-delta
// - side-band
// - side-band-64k
// - quiet
// - push-cert
func NewReferenceUpdateRequestFromCapabilities(adv *capability.List) *ReferenceUpdateRequest {
r := NewReferenceUpdateRequest()
if adv.Supports(capability.Agent) {
r.Capabilities.Set(capability.Agent, capability.DefaultAgent())
}
if adv.Supports(capability.ReportStatus) {
r.Capabilities.Set(capability.ReportStatus)
}
return r
}
func (req *ReferenceUpdateRequest) validate() error {
if len(req.Commands) == 0 {
return ErrEmptyCommands
}
for _, c := range req.Commands {
if err := c.validate(); err != nil {
return err
}
}
return nil
}
type Action string
const (
Create Action = "create"
Update Action = "update"
Delete Action = "delete"
Invalid Action = "invalid"
)
type Command struct {
Name plumbing.ReferenceName
Old plumbing.Hash
New plumbing.Hash
}
func (c *Command) Action() Action {
if c.Old == plumbing.ZeroHash && c.New == plumbing.ZeroHash {
return Invalid
}
if c.Old == plumbing.ZeroHash {
return Create
}
if c.New == plumbing.ZeroHash {
return Delete
}
return Update
}
func (c *Command) validate() error {
if c.Action() == Invalid {
return ErrMalformedCommand
}
return nil
}
type Option struct {
Key string
Value string
}