feat(dir2config): defaults
This commit is contained in:
237
vendor/gopkg.in/src-d/go-git.v4/plumbing/object/object.go
generated
vendored
Normal file
237
vendor/gopkg.in/src-d/go-git.v4/plumbing/object/object.go
generated
vendored
Normal file
@ -0,0 +1,237 @@
|
||||
// Package object contains implementations of all Git objects and utility
|
||||
// functions to work with them.
|
||||
package object
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"gopkg.in/src-d/go-git.v4/plumbing"
|
||||
"gopkg.in/src-d/go-git.v4/plumbing/storer"
|
||||
)
|
||||
|
||||
// ErrUnsupportedObject trigger when a non-supported object is being decoded.
|
||||
var ErrUnsupportedObject = errors.New("unsupported object type")
|
||||
|
||||
// Object is a generic representation of any git object. It is implemented by
|
||||
// Commit, Tree, Blob, and Tag, and includes the functions that are common to
|
||||
// them.
|
||||
//
|
||||
// Object is returned when an object can be of any type. It is frequently used
|
||||
// with a type cast to acquire the specific type of object:
|
||||
//
|
||||
// func process(obj Object) {
|
||||
// switch o := obj.(type) {
|
||||
// case *Commit:
|
||||
// // o is a Commit
|
||||
// case *Tree:
|
||||
// // o is a Tree
|
||||
// case *Blob:
|
||||
// // o is a Blob
|
||||
// case *Tag:
|
||||
// // o is a Tag
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// This interface is intentionally different from plumbing.EncodedObject, which
|
||||
// is a lower level interface used by storage implementations to read and write
|
||||
// objects in its encoded form.
|
||||
type Object interface {
|
||||
ID() plumbing.Hash
|
||||
Type() plumbing.ObjectType
|
||||
Decode(plumbing.EncodedObject) error
|
||||
Encode(plumbing.EncodedObject) error
|
||||
}
|
||||
|
||||
// GetObject gets an object from an object storer and decodes it.
|
||||
func GetObject(s storer.EncodedObjectStorer, h plumbing.Hash) (Object, error) {
|
||||
o, err := s.EncodedObject(plumbing.AnyObject, h)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return DecodeObject(s, o)
|
||||
}
|
||||
|
||||
// DecodeObject decodes an encoded object into an Object and associates it to
|
||||
// the given object storer.
|
||||
func DecodeObject(s storer.EncodedObjectStorer, o plumbing.EncodedObject) (Object, error) {
|
||||
switch o.Type() {
|
||||
case plumbing.CommitObject:
|
||||
return DecodeCommit(s, o)
|
||||
case plumbing.TreeObject:
|
||||
return DecodeTree(s, o)
|
||||
case plumbing.BlobObject:
|
||||
return DecodeBlob(o)
|
||||
case plumbing.TagObject:
|
||||
return DecodeTag(s, o)
|
||||
default:
|
||||
return nil, plumbing.ErrInvalidType
|
||||
}
|
||||
}
|
||||
|
||||
// DateFormat is the format being used in the original git implementation
|
||||
const DateFormat = "Mon Jan 02 15:04:05 2006 -0700"
|
||||
|
||||
// Signature is used to identify who and when created a commit or tag.
|
||||
type Signature struct {
|
||||
// Name represents a person name. It is an arbitrary string.
|
||||
Name string
|
||||
// Email is an email, but it cannot be assumed to be well-formed.
|
||||
Email string
|
||||
// When is the timestamp of the signature.
|
||||
When time.Time
|
||||
}
|
||||
|
||||
// Decode decodes a byte slice into a signature
|
||||
func (s *Signature) Decode(b []byte) {
|
||||
open := bytes.LastIndexByte(b, '<')
|
||||
close := bytes.LastIndexByte(b, '>')
|
||||
if open == -1 || close == -1 {
|
||||
return
|
||||
}
|
||||
|
||||
if close < open {
|
||||
return
|
||||
}
|
||||
|
||||
s.Name = string(bytes.Trim(b[:open], " "))
|
||||
s.Email = string(b[open+1 : close])
|
||||
|
||||
hasTime := close+2 < len(b)
|
||||
if hasTime {
|
||||
s.decodeTimeAndTimeZone(b[close+2:])
|
||||
}
|
||||
}
|
||||
|
||||
// Encode encodes a Signature into a writer.
|
||||
func (s *Signature) Encode(w io.Writer) error {
|
||||
if _, err := fmt.Fprintf(w, "%s <%s> ", s.Name, s.Email); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.encodeTimeAndTimeZone(w); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var timeZoneLength = 5
|
||||
|
||||
func (s *Signature) decodeTimeAndTimeZone(b []byte) {
|
||||
space := bytes.IndexByte(b, ' ')
|
||||
if space == -1 {
|
||||
space = len(b)
|
||||
}
|
||||
|
||||
ts, err := strconv.ParseInt(string(b[:space]), 10, 64)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
s.When = time.Unix(ts, 0).In(time.UTC)
|
||||
var tzStart = space + 1
|
||||
if tzStart >= len(b) || tzStart+timeZoneLength > len(b) {
|
||||
return
|
||||
}
|
||||
|
||||
// Include a dummy year in this time.Parse() call to avoid a bug in Go:
|
||||
// https://github.com/golang/go/issues/19750
|
||||
//
|
||||
// Parsing the timezone with no other details causes the tl.Location() call
|
||||
// below to return time.Local instead of the parsed zone in some cases
|
||||
tl, err := time.Parse("2006 -0700", "1970 "+string(b[tzStart:tzStart+timeZoneLength]))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
s.When = s.When.In(tl.Location())
|
||||
}
|
||||
|
||||
func (s *Signature) encodeTimeAndTimeZone(w io.Writer) error {
|
||||
u := s.When.Unix()
|
||||
if u < 0 {
|
||||
u = 0
|
||||
}
|
||||
_, err := fmt.Fprintf(w, "%d %s", u, s.When.Format("-0700"))
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *Signature) String() string {
|
||||
return fmt.Sprintf("%s <%s>", s.Name, s.Email)
|
||||
}
|
||||
|
||||
// ObjectIter provides an iterator for a set of objects.
|
||||
type ObjectIter struct {
|
||||
storer.EncodedObjectIter
|
||||
s storer.EncodedObjectStorer
|
||||
}
|
||||
|
||||
// NewObjectIter takes a storer.EncodedObjectStorer and a
|
||||
// storer.EncodedObjectIter and returns an *ObjectIter that iterates over all
|
||||
// objects contained in the storer.EncodedObjectIter.
|
||||
func NewObjectIter(s storer.EncodedObjectStorer, iter storer.EncodedObjectIter) *ObjectIter {
|
||||
return &ObjectIter{iter, s}
|
||||
}
|
||||
|
||||
// Next moves the iterator to the next object and returns a pointer to it. If
|
||||
// there are no more objects, it returns io.EOF.
|
||||
func (iter *ObjectIter) Next() (Object, error) {
|
||||
for {
|
||||
obj, err := iter.EncodedObjectIter.Next()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
o, err := iter.toObject(obj)
|
||||
if err == plumbing.ErrInvalidType {
|
||||
continue
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return o, nil
|
||||
}
|
||||
}
|
||||
|
||||
// ForEach call the cb function for each object contained on this iter until
|
||||
// an error happens or the end of the iter is reached. If ErrStop is sent
|
||||
// the iteration is stop but no error is returned. The iterator is closed.
|
||||
func (iter *ObjectIter) ForEach(cb func(Object) error) error {
|
||||
return iter.EncodedObjectIter.ForEach(func(obj plumbing.EncodedObject) error {
|
||||
o, err := iter.toObject(obj)
|
||||
if err == plumbing.ErrInvalidType {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return cb(o)
|
||||
})
|
||||
}
|
||||
|
||||
func (iter *ObjectIter) toObject(obj plumbing.EncodedObject) (Object, error) {
|
||||
switch obj.Type() {
|
||||
case plumbing.BlobObject:
|
||||
blob := &Blob{}
|
||||
return blob, blob.Decode(obj)
|
||||
case plumbing.TreeObject:
|
||||
tree := &Tree{s: iter.s}
|
||||
return tree, tree.Decode(obj)
|
||||
case plumbing.CommitObject:
|
||||
commit := &Commit{}
|
||||
return commit, commit.Decode(obj)
|
||||
case plumbing.TagObject:
|
||||
tag := &Tag{}
|
||||
return tag, tag.Decode(obj)
|
||||
default:
|
||||
return nil, plumbing.ErrInvalidType
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user