123 lines
2.7 KiB
Go
123 lines
2.7 KiB
Go
package packp
|
|
|
|
import (
|
|
"errors"
|
|
"io"
|
|
|
|
"gopkg.in/src-d/go-git.v4/plumbing"
|
|
"gopkg.in/src-d/go-git.v4/plumbing/protocol/packp/capability"
|
|
"gopkg.in/src-d/go-git.v4/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
|
|
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 (r *ReferenceUpdateRequest) validate() error {
|
|
if len(r.Commands) == 0 {
|
|
return ErrEmptyCommands
|
|
}
|
|
|
|
for _, c := range r.Commands {
|
|
if err := c.validate(); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
type Action string
|
|
|
|
const (
|
|
Create Action = "create"
|
|
Update = "update"
|
|
Delete = "delete"
|
|
Invalid = "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
|
|
}
|