Skip to content

Commit d53af9b

Browse files
authored
Merge pull request #2 from git-lfs/ttaylorr/untyped-obj-open
object_db.go: introduce untyped Open()
2 parents 50b4f7e + e99ee2a commit d53af9b

File tree

2 files changed

+73
-10
lines changed

2 files changed

+73
-10
lines changed

object_db.go

Lines changed: 47 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -66,12 +66,44 @@ func (o *ObjectDatabase) Close() error {
6666
return nil
6767
}
6868

69+
// Object returns an Object (of unknown implementation) satisfying the type
70+
// associated with the object named "sha".
71+
//
72+
// If the object could not be opened, is of unknown type, or could not be
73+
// decoded, than an appropriate error is returned instead.
74+
func (o *ObjectDatabase) Object(sha []byte) (Object, error) {
75+
r, err := o.open(sha)
76+
if err != nil {
77+
return nil, err
78+
}
79+
80+
typ, _, err := r.Header()
81+
if err != nil {
82+
return nil, err
83+
}
84+
85+
var into Object
86+
switch typ {
87+
case BlobObjectType:
88+
into = new(Blob)
89+
case TreeObjectType:
90+
into = new(Tree)
91+
case CommitObjectType:
92+
into = new(Commit)
93+
case TagObjectType:
94+
into = new(Tag)
95+
default:
96+
return nil, fmt.Errorf("gitobj: unknown object type: %s", typ)
97+
}
98+
return into, o.decode(r, into)
99+
}
100+
69101
// Blob returns a *Blob as identified by the SHA given, or an error if one was
70102
// encountered.
71103
func (o *ObjectDatabase) Blob(sha []byte) (*Blob, error) {
72104
var b Blob
73105

74-
if err := o.decode(sha, &b); err != nil {
106+
if err := o.openDecode(sha, &b); err != nil {
75107
return nil, err
76108
}
77109
return &b, nil
@@ -81,7 +113,7 @@ func (o *ObjectDatabase) Blob(sha []byte) (*Blob, error) {
81113
// encountered.
82114
func (o *ObjectDatabase) Tree(sha []byte) (*Tree, error) {
83115
var t Tree
84-
if err := o.decode(sha, &t); err != nil {
116+
if err := o.openDecode(sha, &t); err != nil {
85117
return nil, err
86118
}
87119
return &t, nil
@@ -92,7 +124,7 @@ func (o *ObjectDatabase) Tree(sha []byte) (*Tree, error) {
92124
func (o *ObjectDatabase) Commit(sha []byte) (*Commit, error) {
93125
var c Commit
94126

95-
if err := o.decode(sha, &c); err != nil {
127+
if err := o.openDecode(sha, &c); err != nil {
96128
return nil, err
97129
}
98130
return &c, nil
@@ -103,7 +135,7 @@ func (o *ObjectDatabase) Commit(sha []byte) (*Commit, error) {
103135
func (o *ObjectDatabase) Tag(sha []byte) (*Tag, error) {
104136
var t Tag
105137

106-
if err := o.decode(sha, &t); err != nil {
138+
if err := o.openDecode(sha, &t); err != nil {
107139
return nil, err
108140
}
109141
return &t, nil
@@ -272,6 +304,16 @@ func (o *ObjectDatabase) open(sha []byte) (*ObjectReader, error) {
272304
return NewObjectReadCloser(f)
273305
}
274306

307+
// openDecode calls decode (see: below) on the object named "sha" after openin
308+
// it.
309+
func (o *ObjectDatabase) openDecode(sha []byte, into Object) error {
310+
r, err := o.open(sha)
311+
if err != nil {
312+
return err
313+
}
314+
return o.decode(r, into)
315+
}
316+
275317
// decode decodes an object given by the sha "sha []byte" into the given object
276318
// "into", or returns an error if one was encountered.
277319
//
@@ -280,12 +322,7 @@ func (o *ObjectDatabase) open(sha []byte) (*ObjectReader, error) {
280322
// BlobObjectType. Blob's don't exhaust the buffer completely (they instead
281323
// maintain a handle on the blob's contents via an io.LimitedReader) and
282324
// therefore cannot be closed until signaled explicitly by gitobj.Blob.Close().
283-
func (o *ObjectDatabase) decode(sha []byte, into Object) error {
284-
r, err := o.open(sha)
285-
if err != nil {
286-
return err
287-
}
288-
325+
func (o *ObjectDatabase) decode(r *ObjectReader, into Object) error {
289326
typ, size, err := r.Header()
290327
if err != nil {
291328
return err

object_db_test.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,32 @@ import (
1515
"github.com/stretchr/testify/require"
1616
)
1717

18+
func TestDecodeObject(t *testing.T) {
19+
sha := "af5626b4a114abcb82d63db7c8082c3c4756e51b"
20+
contents := "Hello, world!\n"
21+
22+
var buf bytes.Buffer
23+
24+
zw := zlib.NewWriter(&buf)
25+
fmt.Fprintf(zw, "blob 14\x00%s", contents)
26+
zw.Close()
27+
28+
odb := &ObjectDatabase{s: newMemoryStorer(map[string]io.ReadWriter{
29+
sha: &buf,
30+
})}
31+
32+
shaHex, _ := hex.DecodeString(sha)
33+
obj, err := odb.Object(shaHex)
34+
blob, ok := obj.(*Blob)
35+
36+
require.NoError(t, err)
37+
require.True(t, ok)
38+
39+
got, err := ioutil.ReadAll(blob.Contents)
40+
assert.Nil(t, err)
41+
assert.Equal(t, contents, string(got))
42+
}
43+
1844
func TestDecodeBlob(t *testing.T) {
1945
sha := "af5626b4a114abcb82d63db7c8082c3c4756e51b"
2046
contents := "Hello, world!\n"

0 commit comments

Comments
 (0)