diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/errors.go | 35 | ||||
-rw-r--r-- | core/hash.go | 58 | ||||
-rw-r--r-- | core/hash_test.go | 42 | ||||
-rw-r--r-- | core/memory.go | 59 | ||||
-rw-r--r-- | core/memory_test.go | 71 | ||||
-rw-r--r-- | core/object.go | 265 | ||||
-rw-r--r-- | core/object_test.go | 176 | ||||
-rw-r--r-- | core/reference.go | 230 | ||||
-rw-r--r-- | core/reference_test.go | 120 | ||||
-rw-r--r-- | core/storage.go | 83 |
10 files changed, 0 insertions, 1139 deletions
diff --git a/core/errors.go b/core/errors.go deleted file mode 100644 index 50772b6..0000000 --- a/core/errors.go +++ /dev/null @@ -1,35 +0,0 @@ -package core - -import "fmt" - -type PermanentError struct { - Err error -} - -func NewPermanentError(err error) *PermanentError { - if err == nil { - return nil - } - - return &PermanentError{Err: err} -} - -func (e *PermanentError) Error() string { - return fmt.Sprintf("permanent client error: %s", e.Err.Error()) -} - -type UnexpectedError struct { - Err error -} - -func NewUnexpectedError(err error) *UnexpectedError { - if err == nil { - return nil - } - - return &UnexpectedError{Err: err} -} - -func (e *UnexpectedError) Error() string { - return fmt.Sprintf("unexpected client error: %s", e.Err.Error()) -} diff --git a/core/hash.go b/core/hash.go deleted file mode 100644 index c50ffb2..0000000 --- a/core/hash.go +++ /dev/null @@ -1,58 +0,0 @@ -package core - -import ( - "crypto/sha1" - "encoding/hex" - "hash" - "strconv" -) - -// Hash SHA1 hased content -type Hash [20]byte - -// ZeroHash is Hash with value zero -var ZeroHash Hash - -// ComputeHash compute the hash for a given ObjectType and content -func ComputeHash(t ObjectType, content []byte) Hash { - h := NewHasher(t, int64(len(content))) - h.Write(content) - return h.Sum() -} - -// NewHash return a new Hash from a hexadecimal hash representation -func NewHash(s string) Hash { - b, _ := hex.DecodeString(s) - - var h Hash - copy(h[:], b) - - return h -} - -func (h Hash) IsZero() bool { - var empty Hash - return h == empty -} - -func (h Hash) String() string { - return hex.EncodeToString(h[:]) -} - -type Hasher struct { - hash.Hash -} - -func NewHasher(t ObjectType, size int64) Hasher { - h := Hasher{sha1.New()} - h.Write(t.Bytes()) - h.Write([]byte(" ")) - h.Write([]byte(strconv.FormatInt(size, 10))) - h.Write([]byte{0}) - return h -} - -func (h Hasher) Sum() (hash Hash) { - copy(hash[:], h.Hash.Sum(nil)) - return -} diff --git a/core/hash_test.go b/core/hash_test.go deleted file mode 100644 index 782777e..0000000 --- a/core/hash_test.go +++ /dev/null @@ -1,42 +0,0 @@ -package core - -import ( - "testing" - - . "gopkg.in/check.v1" -) - -func Test(t *testing.T) { TestingT(t) } - -type HashSuite struct{} - -var _ = Suite(&HashSuite{}) - -func (s *HashSuite) TestComputeHash(c *C) { - hash := ComputeHash(BlobObject, []byte("")) - c.Assert(hash.String(), Equals, "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391") - - hash = ComputeHash(BlobObject, []byte("Hello, World!\n")) - c.Assert(hash.String(), Equals, "8ab686eafeb1f44702738c8b0f24f2567c36da6d") -} - -func (s *HashSuite) TestNewHash(c *C) { - hash := ComputeHash(BlobObject, []byte("Hello, World!\n")) - - c.Assert(hash, Equals, NewHash(hash.String())) -} - -func (s *HashSuite) TestIsZero(c *C) { - hash := NewHash("foo") - c.Assert(hash.IsZero(), Equals, true) - - hash = NewHash("8ab686eafeb1f44702738c8b0f24f2567c36da6d") - c.Assert(hash.IsZero(), Equals, false) -} - -func (s *HashSuite) TestNewHasher(c *C) { - content := "hasher test sample" - hasher := NewHasher(BlobObject, int64(len(content))) - hasher.Write([]byte(content)) - c.Assert(hasher.Sum().String(), Equals, "dc42c3cc80028d0ec61f0a6b24cadd1c195c4dfc") -} diff --git a/core/memory.go b/core/memory.go deleted file mode 100644 index dabee3a..0000000 --- a/core/memory.go +++ /dev/null @@ -1,59 +0,0 @@ -package core - -import ( - "bytes" - "io" - "io/ioutil" -) - -// MemoryObject on memory Object implementation -type MemoryObject struct { - t ObjectType - h Hash - cont []byte - sz int64 -} - -// Hash return the object Hash, the hash is calculated on-the-fly the first -// time is called, the subsequent calls the same Hash is returned even if the -// type or the content has changed. The Hash is only generated if the size of -// the content is exactly the Object.Size -func (o *MemoryObject) Hash() Hash { - if o.h == ZeroHash && int64(len(o.cont)) == o.sz { - o.h = ComputeHash(o.t, o.cont) - } - - return o.h -} - -// Type return the ObjectType -func (o *MemoryObject) Type() ObjectType { return o.t } - -// SetType sets the ObjectType -func (o *MemoryObject) SetType(t ObjectType) { o.t = t } - -// Size return the size of the object -func (o *MemoryObject) Size() int64 { return o.sz } - -// SetSize set the object size, a content of the given size should be written -// afterwards -func (o *MemoryObject) SetSize(s int64) { o.sz = s } - -// Reader returns a ObjectReader used to read the object's content. -func (o *MemoryObject) Reader() (io.ReadCloser, error) { - return ioutil.NopCloser(bytes.NewBuffer(o.cont)), nil -} - -// Writer returns a ObjectWriter used to write the object's content. -func (o *MemoryObject) Writer() (io.WriteCloser, error) { - return o, nil -} - -func (o *MemoryObject) Write(p []byte) (n int, err error) { - o.cont = append(o.cont, p...) - return len(p), nil -} - -// Close releases any resources consumed by the object when it is acting as a -// ObjectWriter. -func (o *MemoryObject) Close() error { return nil } diff --git a/core/memory_test.go b/core/memory_test.go deleted file mode 100644 index f1c3f64..0000000 --- a/core/memory_test.go +++ /dev/null @@ -1,71 +0,0 @@ -package core - -import ( - "io/ioutil" - - . "gopkg.in/check.v1" -) - -type MemoryObjectSuite struct{} - -var _ = Suite(&MemoryObjectSuite{}) - -func (s *MemoryObjectSuite) TestHash(c *C) { - o := &MemoryObject{} - o.SetType(BlobObject) - o.SetSize(14) - - _, err := o.Write([]byte("Hello, World!\n")) - c.Assert(err, IsNil) - - c.Assert(o.Hash().String(), Equals, "8ab686eafeb1f44702738c8b0f24f2567c36da6d") - - o.SetType(CommitObject) - c.Assert(o.Hash().String(), Equals, "8ab686eafeb1f44702738c8b0f24f2567c36da6d") -} - -func (s *MemoryObjectSuite) TestHashNotFilled(c *C) { - o := &MemoryObject{} - o.SetType(BlobObject) - o.SetSize(14) - - c.Assert(o.Hash(), Equals, ZeroHash) -} - -func (s *MemoryObjectSuite) TestType(c *C) { - o := &MemoryObject{} - o.SetType(BlobObject) - c.Assert(o.Type(), Equals, BlobObject) -} - -func (s *MemoryObjectSuite) TestSize(c *C) { - o := &MemoryObject{} - o.SetSize(42) - c.Assert(o.Size(), Equals, int64(42)) -} - -func (s *MemoryObjectSuite) TestReader(c *C) { - o := &MemoryObject{cont: []byte("foo")} - - reader, err := o.Reader() - c.Assert(err, IsNil) - defer func() { c.Assert(reader.Close(), IsNil) }() - - b, err := ioutil.ReadAll(reader) - c.Assert(err, IsNil) - c.Assert(b, DeepEquals, []byte("foo")) -} - -func (s *MemoryObjectSuite) TestWriter(c *C) { - o := &MemoryObject{} - - writer, err := o.Writer() - c.Assert(err, IsNil) - defer func() { c.Assert(writer.Close(), IsNil) }() - - n, err := writer.Write([]byte("foo")) - c.Assert(err, IsNil) - c.Assert(n, Equals, 3) - - c.Assert(o.cont, DeepEquals, []byte("foo")) -} diff --git a/core/object.go b/core/object.go deleted file mode 100644 index 8125465..0000000 --- a/core/object.go +++ /dev/null @@ -1,265 +0,0 @@ -// Package core implement the core interfaces and structs used by go-git -package core - -import ( - "errors" - "io" -) - -var ( - ErrObjectNotFound = errors.New("object not found") - // ErrInvalidType is returned when an invalid object type is provided. - ErrInvalidType = errors.New("invalid object type") -) - -// Object is a generic representation of any git object -type Object interface { - Hash() Hash - Type() ObjectType - SetType(ObjectType) - Size() int64 - SetSize(int64) - Reader() (io.ReadCloser, error) - Writer() (io.WriteCloser, error) -} - -// ObjectType internal object type -// Integer values from 0 to 7 map to those exposed by git. -// AnyObject is used to represent any from 0 to 7. -type ObjectType int8 - -const ( - InvalidObject ObjectType = 0 - CommitObject ObjectType = 1 - TreeObject ObjectType = 2 - BlobObject ObjectType = 3 - TagObject ObjectType = 4 - // 5 reserved for future expansion - OFSDeltaObject ObjectType = 6 - REFDeltaObject ObjectType = 7 - - AnyObject ObjectType = -127 -) - -func (t ObjectType) String() string { - switch t { - case CommitObject: - return "commit" - case TreeObject: - return "tree" - case BlobObject: - return "blob" - case TagObject: - return "tag" - case OFSDeltaObject: - return "ofs-delta" - case REFDeltaObject: - return "ref-delta" - case AnyObject: - return "any" - default: - return "unknown" - } -} - -func (t ObjectType) Bytes() []byte { - return []byte(t.String()) -} - -// Valid returns true if t is a valid ObjectType. -func (t ObjectType) Valid() bool { - return t >= CommitObject && t <= REFDeltaObject -} - -// ParseObjectType parses a string representation of ObjectType. It returns an -// error on parse failure. -func ParseObjectType(value string) (typ ObjectType, err error) { - switch value { - case "commit": - typ = CommitObject - case "tree": - typ = TreeObject - case "blob": - typ = BlobObject - case "tag": - typ = TagObject - case "ofs-delta": - typ = OFSDeltaObject - case "ref-delta": - typ = REFDeltaObject - default: - err = ErrInvalidType - } - return -} - -// ObjectLookupIter implements ObjectIter. It iterates over a series of object -// hashes and yields their associated objects by retrieving each one from -// object storage. The retrievals are lazy and only occur when the iterator -// moves forward with a call to Next(). -// -// The ObjectLookupIter must be closed with a call to Close() when it is no -// longer needed. -type ObjectLookupIter struct { - storage ObjectStorer - series []Hash - t ObjectType - pos int -} - -// NewObjectLookupIter returns an object iterator given an object storage and -// a slice of object hashes. -func NewObjectLookupIter(storage ObjectStorer, t ObjectType, series []Hash) *ObjectLookupIter { - return &ObjectLookupIter{ - storage: storage, - series: series, - t: t, - } -} - -// Next returns the next object from the iterator. If the iterator has reached -// the end it will return io.EOF as an error. If the object can't be found in -// the object storage, it will return ErrObjectNotFound as an error. If the -// object is retreieved successfully error will be nil. -func (iter *ObjectLookupIter) Next() (Object, error) { - if iter.pos >= len(iter.series) { - return nil, io.EOF - } - - hash := iter.series[iter.pos] - obj, err := iter.storage.Object(iter.t, hash) - if err == nil { - iter.pos++ - } - - return obj, err -} - -// ForEach call the cb function for each object contained on this iter until -// an error happends 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 *ObjectLookupIter) ForEach(cb func(Object) error) error { - return ForEachIterator(iter, cb) -} - -// Close releases any resources used by the iterator. -func (iter *ObjectLookupIter) Close() { - iter.pos = len(iter.series) -} - -// ObjectSliceIter implements ObjectIter. It iterates over a series of objects -// stored in a slice and yields each one in turn when Next() is called. -// -// The ObjectSliceIter must be closed with a call to Close() when it is no -// longer needed. -type ObjectSliceIter struct { - series []Object - pos int -} - -// NewObjectSliceIter returns an object iterator for the given slice of objects. -func NewObjectSliceIter(series []Object) *ObjectSliceIter { - return &ObjectSliceIter{ - series: series, - } -} - -// Next returns the next object from the iterator. If the iterator has reached -// the end it will return io.EOF as an error. If the object is retreieved -// successfully error will be nil. -func (iter *ObjectSliceIter) Next() (Object, error) { - if len(iter.series) == 0 { - return nil, io.EOF - } - - obj := iter.series[0] - iter.series = iter.series[1:] - - return obj, nil -} - -// ForEach call the cb function for each object contained on this iter until -// an error happends 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 *ObjectSliceIter) ForEach(cb func(Object) error) error { - return ForEachIterator(iter, cb) -} - -// Close releases any resources used by the iterator. -func (iter *ObjectSliceIter) Close() { - iter.series = []Object{} -} - -// MultiObjectIter implements ObjectIter. It iterates over several ObjectIter, -// -// The MultiObjectIter must be closed with a call to Close() when it is no -// longer needed. -type MultiObjectIter struct { - iters []ObjectIter - pos int -} - -// NewMultiObjectIter returns an object iterator for the given slice of objects. -func NewMultiObjectIter(iters []ObjectIter) ObjectIter { - return &MultiObjectIter{iters: iters} -} - -// Next returns the next object from the iterator, if one iterator reach io.EOF -// is removed and the next one is used. -func (iter *MultiObjectIter) Next() (Object, error) { - if len(iter.iters) == 0 { - return nil, io.EOF - } - - obj, err := iter.iters[0].Next() - if err == io.EOF { - iter.iters[0].Close() - iter.iters = iter.iters[1:] - return iter.Next() - } - - return obj, err -} - -// ForEach call the cb function for each object contained on this iter until -// an error happends 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 *MultiObjectIter) ForEach(cb func(Object) error) error { - return ForEachIterator(iter, cb) -} - -// Close releases any resources used by the iterator. -func (iter *MultiObjectIter) Close() { - for _, i := range iter.iters { - i.Close() - } -} - -type bareIterator interface { - Next() (Object, error) - Close() -} - -// ForEachIterator is a helper function to build iterators without need to -// rewrite the same ForEach function each time. -func ForEachIterator(iter bareIterator, cb func(Object) error) error { - defer iter.Close() - for { - obj, err := iter.Next() - if err != nil { - if err == io.EOF { - return nil - } - - return err - } - - if err := cb(obj); err != nil { - if err == ErrStop { - return nil - } - - return err - } - } -} diff --git a/core/object_test.go b/core/object_test.go deleted file mode 100644 index 5ebf26a..0000000 --- a/core/object_test.go +++ /dev/null @@ -1,176 +0,0 @@ -package core - -import ( - "fmt" - - . "gopkg.in/check.v1" -) - -type ObjectSuite struct{} - -var _ = Suite(&ObjectSuite{}) - -func (s *ObjectSuite) TestObjectTypeString(c *C) { - c.Assert(CommitObject.String(), Equals, "commit") - c.Assert(TreeObject.String(), Equals, "tree") - c.Assert(BlobObject.String(), Equals, "blob") - c.Assert(TagObject.String(), Equals, "tag") - c.Assert(REFDeltaObject.String(), Equals, "ref-delta") - c.Assert(OFSDeltaObject.String(), Equals, "ofs-delta") - c.Assert(AnyObject.String(), Equals, "any") - c.Assert(ObjectType(42).String(), Equals, "unknown") -} - -func (s *ObjectSuite) TestObjectTypeBytes(c *C) { - c.Assert(CommitObject.Bytes(), DeepEquals, []byte("commit")) -} - -func (s *ObjectSuite) TestObjectTypeValid(c *C) { - c.Assert(CommitObject.Valid(), Equals, true) - c.Assert(ObjectType(42).Valid(), Equals, false) -} - -func (s *ObjectSuite) TestParseObjectType(c *C) { - for s, e := range map[string]ObjectType{ - "commit": CommitObject, - "tree": TreeObject, - "blob": BlobObject, - "tag": TagObject, - "ref-delta": REFDeltaObject, - "ofs-delta": OFSDeltaObject, - } { - t, err := ParseObjectType(s) - c.Assert(err, IsNil) - c.Assert(e, Equals, t) - } - - t, err := ParseObjectType("foo") - c.Assert(err, Equals, ErrInvalidType) - c.Assert(t, Equals, InvalidObject) -} - -func (s *ObjectSuite) TestMultiObjectIterNext(c *C) { - expected := []Object{ - &MemoryObject{}, - &MemoryObject{}, - &MemoryObject{}, - &MemoryObject{}, - &MemoryObject{}, - &MemoryObject{}, - } - - iter := NewMultiObjectIter([]ObjectIter{ - NewObjectSliceIter(expected[0:2]), - NewObjectSliceIter(expected[2:4]), - NewObjectSliceIter(expected[4:5]), - }) - - var i int - iter.ForEach(func(o Object) error { - c.Assert(o, Equals, expected[i]) - i++ - return nil - }) - - iter.Close() -} - -func (s *ObjectSuite) TestObjectLookupIter(c *C) { - h := []Hash{ - NewHash("0920f02906615b285040767a67c5cb30fe0f5e2c"), - NewHash("4921e391f1128010a2d957f8db15c5e729ccf94a"), - } - - var count int - - i := NewObjectLookupIter(&MockObjectStorage{}, CommitObject, h) - err := i.ForEach(func(o Object) error { - c.Assert(o, NotNil) - c.Assert(o.Hash().String(), Equals, h[count].String()) - count++ - return nil - }) - - c.Assert(err, IsNil) - i.Close() -} - -func (s *ObjectSuite) TestObjectSliceIter(c *C) { - h := []Hash{ - NewHash("0920f02906615b285040767a67c5cb30fe0f5e2c"), - NewHash("4921e391f1128010a2d957f8db15c5e729ccf94a"), - } - - var count int - - i := NewObjectSliceIter([]Object{ - &MemoryObject{h: h[0]}, &MemoryObject{h: h[1]}, - }) - - err := i.ForEach(func(o Object) error { - c.Assert(o, NotNil) - c.Assert(o.Hash().String(), Equals, h[count].String()) - count++ - return nil - }) - - c.Assert(count, Equals, 2) - c.Assert(err, IsNil) - c.Assert(i.series, HasLen, 0) -} - -func (s *ObjectSuite) TestObjectSliceIterStop(c *C) { - h := []Hash{ - NewHash("0920f02906615b285040767a67c5cb30fe0f5e2c"), - NewHash("4921e391f1128010a2d957f8db15c5e729ccf94a"), - } - - i := NewObjectSliceIter([]Object{ - &MemoryObject{h: h[0]}, &MemoryObject{h: h[1]}, - }) - - var count = 0 - err := i.ForEach(func(o Object) error { - c.Assert(o, NotNil) - c.Assert(o.Hash().String(), Equals, h[count].String()) - count++ - return ErrStop - }) - - c.Assert(count, Equals, 1) - c.Assert(err, IsNil) -} - -func (s *ObjectSuite) TestObjectSliceIterError(c *C) { - i := NewObjectSliceIter([]Object{ - &MemoryObject{h: NewHash("4921e391f1128010a2d957f8db15c5e729ccf94a")}, - }) - - err := i.ForEach(func(Object) error { - return fmt.Errorf("a random error") - }) - - c.Assert(err, NotNil) -} - -type MockObjectStorage struct{} - -func (o *MockObjectStorage) NewObject() Object { - return nil -} - -func (o *MockObjectStorage) SetObject(obj Object) (Hash, error) { - return ZeroHash, nil -} - -func (o *MockObjectStorage) Object(t ObjectType, h Hash) (Object, error) { - return &MemoryObject{h: h}, nil -} - -func (o *MockObjectStorage) IterObjects(t ObjectType) (ObjectIter, error) { - return nil, nil -} - -func (o *MockObjectStorage) Begin() Transaction { - return nil -} diff --git a/core/reference.go b/core/reference.go deleted file mode 100644 index ee55a6a..0000000 --- a/core/reference.go +++ /dev/null @@ -1,230 +0,0 @@ -package core - -import ( - "errors" - "fmt" - "io" - "strings" -) - -const ( - refPrefix = "refs/" - refHeadPrefix = refPrefix + "heads/" - refTagPrefix = refPrefix + "tags/" - refRemotePrefix = refPrefix + "remotes/" - refNotePrefix = refPrefix + "notes/" - symrefPrefix = "ref: " - - maxResolveRecursion = 1024 -) - -var ( - ErrMaxResolveRecursion = errors.New("max. recursion level reached") - ErrReferenceNotFound = errors.New("reference not found") -) - -// ReferenceType reference type's -type ReferenceType int8 - -const ( - InvalidReference ReferenceType = 0 - HashReference ReferenceType = 1 - SymbolicReference ReferenceType = 2 -) - -// ReferenceName reference name's -type ReferenceName string - -func (r ReferenceName) String() string { - return string(r) -} - -// Short returns the short name of a ReferenceName -func (r ReferenceName) Short() string { - parts := strings.Split(string(r), "/") - return parts[len(parts)-1] -} - -const ( - HEAD ReferenceName = "HEAD" -) - -// Reference is a representation of git reference -type Reference struct { - t ReferenceType - n ReferenceName - h Hash - target ReferenceName -} - -// NewReferenceFromStrings creates a reference from name and target as string, -// the resulting reference can be a SymbolicReference or a HashReference base -// on the target provided -func NewReferenceFromStrings(name, target string) *Reference { - n := ReferenceName(name) - - if strings.HasPrefix(target, symrefPrefix) { - target := ReferenceName(target[len(symrefPrefix):]) - return NewSymbolicReference(n, target) - } - - return NewHashReference(n, NewHash(target)) -} - -// NewSymbolicReference creates a new SymbolicReference reference -func NewSymbolicReference(n, target ReferenceName) *Reference { - return &Reference{ - t: SymbolicReference, - n: n, - target: target, - } -} - -// NewHashReference creates a new HashReference reference -func NewHashReference(n ReferenceName, h Hash) *Reference { - return &Reference{ - t: HashReference, - n: n, - h: h, - } -} - -// Type return the type of a reference -func (r *Reference) Type() ReferenceType { - return r.t -} - -// Name return the name of a reference -func (r *Reference) Name() ReferenceName { - return r.n -} - -// Hash return the hash of a hash reference -func (r *Reference) Hash() Hash { - return r.h -} - -// Target return the target of a symbolic reference -func (r *Reference) Target() ReferenceName { - return r.target -} - -// IsBranch check if a reference is a branch -func (r *Reference) IsBranch() bool { - return strings.HasPrefix(string(r.n), refHeadPrefix) -} - -// IsNote check if a reference is a note -func (r *Reference) IsNote() bool { - return strings.HasPrefix(string(r.n), refNotePrefix) -} - -// IsRemote check if a reference is a remote -func (r *Reference) IsRemote() bool { - return strings.HasPrefix(string(r.n), refRemotePrefix) -} - -// IsTag check if a reference is a tag -func (r *Reference) IsTag() bool { - return strings.HasPrefix(string(r.n), refTagPrefix) -} - -// Strings dump a reference as a [2]string -func (r *Reference) Strings() [2]string { - var o [2]string - o[0] = r.Name().String() - - switch r.Type() { - case HashReference: - o[1] = r.Hash().String() - case SymbolicReference: - o[1] = symrefPrefix + r.Target().String() - } - - return o -} - -func (r *Reference) String() string { - s := r.Strings() - return fmt.Sprintf("%s %s", s[1], s[0]) -} - -// ReferenceSliceIter implements ReferenceIter. It iterates over a series of -// references stored in a slice and yields each one in turn when Next() is -// called. -// -// The ReferenceSliceIter must be closed with a call to Close() when it is no -// longer needed. -type ReferenceSliceIter struct { - series []*Reference - pos int -} - -// NewReferenceSliceIter returns a reference iterator for the given slice of -// objects. -func NewReferenceSliceIter(series []*Reference) *ReferenceSliceIter { - return &ReferenceSliceIter{ - series: series, - } -} - -// Next returns the next reference from the iterator. If the iterator has -// reached the end it will return io.EOF as an error. -func (iter *ReferenceSliceIter) Next() (*Reference, error) { - if iter.pos >= len(iter.series) { - return nil, io.EOF - } - - obj := iter.series[iter.pos] - iter.pos++ - return obj, nil -} - -// ForEach call the cb function for each reference contained on this iter until -// an error happends 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 *ReferenceSliceIter) ForEach(cb func(*Reference) error) error { - defer iter.Close() - for _, r := range iter.series { - if err := cb(r); err != nil { - if err == ErrStop { - return nil - } - - return nil - } - } - - return nil -} - -// Close releases any resources used by the iterator. -func (iter *ReferenceSliceIter) Close() { - iter.pos = len(iter.series) -} - -func ResolveReference(s ReferenceStorer, n ReferenceName) (*Reference, error) { - r, err := s.Reference(n) - if err != nil || r == nil { - return r, err - } - return resolveReference(s, r, 0) -} - -func resolveReference(s ReferenceStorer, r *Reference, recursion int) (*Reference, error) { - if r.Type() != SymbolicReference { - return r, nil - } - - if recursion > maxResolveRecursion { - return nil, ErrMaxResolveRecursion - } - - t, err := s.Reference(r.Target()) - if err != nil { - return nil, err - } - - recursion++ - return resolveReference(s, t, recursion) -} diff --git a/core/reference_test.go b/core/reference_test.go deleted file mode 100644 index b14f24c..0000000 --- a/core/reference_test.go +++ /dev/null @@ -1,120 +0,0 @@ -package core - -import ( - "io" - - . "gopkg.in/check.v1" -) - -type ReferenceSuite struct{} - -var _ = Suite(&ReferenceSuite{}) - -const ( - ExampleReferenceName ReferenceName = "refs/heads/v4" -) - -func (s *ReferenceSuite) TestReferenceNameShort(c *C) { - c.Assert(ExampleReferenceName.Short(), Equals, "v4") -} - -func (s *ReferenceSuite) TestNewReferenceFromStrings(c *C) { - r := NewReferenceFromStrings("refs/heads/v4", "6ecf0ef2c2dffb796033e5a02219af86ec6584e5") - c.Assert(r.Type(), Equals, HashReference) - c.Assert(r.Name(), Equals, ExampleReferenceName) - c.Assert(r.Hash(), Equals, NewHash("6ecf0ef2c2dffb796033e5a02219af86ec6584e5")) - - r = NewReferenceFromStrings("HEAD", "ref: refs/heads/v4") - c.Assert(r.Type(), Equals, SymbolicReference) - c.Assert(r.Name(), Equals, HEAD) - c.Assert(r.Target(), Equals, ExampleReferenceName) -} - -func (s *ReferenceSuite) TestNewSymbolicReference(c *C) { - r := NewSymbolicReference(HEAD, ExampleReferenceName) - c.Assert(r.Type(), Equals, SymbolicReference) - c.Assert(r.Name(), Equals, HEAD) - c.Assert(r.Target(), Equals, ExampleReferenceName) -} - -func (s *ReferenceSuite) TestNewHashReference(c *C) { - r := NewHashReference(ExampleReferenceName, NewHash("6ecf0ef2c2dffb796033e5a02219af86ec6584e5")) - c.Assert(r.Type(), Equals, HashReference) - c.Assert(r.Name(), Equals, ExampleReferenceName) - c.Assert(r.Hash(), Equals, NewHash("6ecf0ef2c2dffb796033e5a02219af86ec6584e5")) -} - -func (s *ReferenceSuite) TestIsBranch(c *C) { - r := NewHashReference(ExampleReferenceName, ZeroHash) - c.Assert(r.IsBranch(), Equals, true) -} - -func (s *ReferenceSuite) TestIsNote(c *C) { - r := NewHashReference(ReferenceName("refs/notes/foo"), ZeroHash) - c.Assert(r.IsNote(), Equals, true) -} - -func (s *ReferenceSuite) TestIsRemote(c *C) { - r := NewHashReference(ReferenceName("refs/remotes/origin/master"), ZeroHash) - c.Assert(r.IsRemote(), Equals, true) -} - -func (s *ReferenceSuite) TestIsTag(c *C) { - r := NewHashReference(ReferenceName("refs/tags/v3.1."), ZeroHash) - c.Assert(r.IsTag(), Equals, true) -} - -func (s *ReferenceSuite) TestReferenceSliceIterNext(c *C) { - slice := []*Reference{ - NewReferenceFromStrings("foo", "foo"), - NewReferenceFromStrings("bar", "bar"), - } - - i := NewReferenceSliceIter(slice) - foo, err := i.Next() - c.Assert(err, IsNil) - c.Assert(foo == slice[0], Equals, true) - - bar, err := i.Next() - c.Assert(err, IsNil) - c.Assert(bar == slice[1], Equals, true) - - empty, err := i.Next() - c.Assert(err, Equals, io.EOF) - c.Assert(empty, IsNil) -} - -func (s *ReferenceSuite) TestReferenceSliceIterForEach(c *C) { - slice := []*Reference{ - NewReferenceFromStrings("foo", "foo"), - NewReferenceFromStrings("bar", "bar"), - } - - i := NewReferenceSliceIter(slice) - var count int - i.ForEach(func(r *Reference) error { - c.Assert(r == slice[count], Equals, true) - count++ - return nil - }) - - c.Assert(count, Equals, 2) -} - -func (s *ReferenceSuite) TestReferenceSliceIterForEachStop(c *C) { - slice := []*Reference{ - NewReferenceFromStrings("foo", "foo"), - NewReferenceFromStrings("bar", "bar"), - } - - i := NewReferenceSliceIter(slice) - - var count int - i.ForEach(func(r *Reference) error { - c.Assert(r == slice[count], Equals, true) - count++ - return ErrStop - }) - - c.Assert(count, Equals, 1) -} diff --git a/core/storage.go b/core/storage.go deleted file mode 100644 index 101115b..0000000 --- a/core/storage.go +++ /dev/null @@ -1,83 +0,0 @@ -package core - -import ( - "errors" - "io" -) - -var ( - //ErrStop is used to stop a ForEach function in an Iter - ErrStop = errors.New("stop iter") -) - -// ObjectStorer generic storage of objects -type ObjectStorer interface { - // NewObject returns a new Object, the real type of the object can be a - // custom implementation or the defaul one, MemoryObject - NewObject() Object - // SetObject save an object into the storage, the object shuld be create - // with the NewObject, method, and file if the type is not supported. - SetObject(Object) (Hash, error) - // Object an object by hash with the given ObjectType. Implementors - // should return (nil, ErrObjectNotFound) if an object doesn't exist with - // both the given hash and object type. - // - // Valid ObjectType values are CommitObject, BlobObject, TagObject, - // TreeObject and AnyObject. If AnyObject is given, the object must be - // looked up regardless of its type. - Object(ObjectType, Hash) (Object, error) - // IterObjects returns a custom ObjectIter over all the object on the - // storage. - // - // Valid ObjectType values are CommitObject, BlobObject, TagObject, - IterObjects(ObjectType) (ObjectIter, error) -} - -// Transactioner is a optional method for ObjectStorer, it enable transaction -// base write and read operations in the storage -type Transactioner interface { - // Begin starts a transaction. - Begin() Transaction -} - -// PackfileWriter is a optional method for ObjectStorer, it enable direct write -// of packfile to the storage -type PackfileWriter interface { - // PackfileWriter retuns a writer for writing a packfile to the Storage, - // this method is optional, if not implemented the ObjectStorer should - // return a ErrNotImplemented error. - // - // If the implementation not implements Writer the objects should be written - // using the Set method. - PackfileWriter() (io.WriteCloser, error) -} - -// ObjectIter is a generic closable interface for iterating over objects. -type ObjectIter interface { - Next() (Object, error) - ForEach(func(Object) error) error - Close() -} - -// Transaction is an in-progress storage transaction. A transaction must end -// with a call to Commit or Rollback. -type Transaction interface { - SetObject(Object) (Hash, error) - Object(ObjectType, Hash) (Object, error) - Commit() error - Rollback() error -} - -// ReferenceStorer generic storage of references -type ReferenceStorer interface { - SetReference(*Reference) error - Reference(ReferenceName) (*Reference, error) - IterReferences() (ReferenceIter, error) -} - -// ReferenceIter is a generic closable interface for iterating over references -type ReferenceIter interface { - Next() (*Reference, error) - ForEach(func(*Reference) error) error - Close() -} |