Skip to content

Commit 40097be

Browse files
authored
blob: get blob and check image by index (#55)
1 parent c80dc60 commit 40097be

File tree

5 files changed

+109
-6
lines changed

5 files changed

+109
-6
lines changed

commit.go

+11-3
Original file line numberDiff line numberDiff line change
@@ -138,9 +138,7 @@ func (w *limitWriter) Write(p []byte) (int, error) {
138138
return len(p), err
139139
}
140140

141-
// IsImageFile returns true if the commit is an image blob.
142-
func (c *Commit) IsImageFile(subpath string) (bool, error) {
143-
blob, err := c.Blob(subpath)
141+
func (c *Commit) isImageFile(blob *Blob, err error) (bool, error) {
144142
if err != nil {
145143
if err == ErrNotBlob {
146144
return false, nil
@@ -162,3 +160,13 @@ func (c *Commit) IsImageFile(subpath string) (bool, error) {
162160

163161
return strings.Contains(http.DetectContentType(buf.Bytes()), "image/"), nil
164162
}
163+
164+
// IsImageFile returns true if the blob of the commit is an image by subpath.
165+
func (c *Commit) IsImageFile(subpath string) (bool, error) {
166+
return c.isImageFile(c.Blob(subpath))
167+
}
168+
169+
// IsImageFileByIndex returns true if the blob of the commit is an image by index.
170+
func (c *Commit) IsImageFileByIndex(index string) (bool, error) {
171+
return c.isImageFile(c.BlobByIndex(index))
172+
}

commit_test.go

+47
Original file line numberDiff line numberDiff line change
@@ -579,3 +579,50 @@ func TestCommit_IsImageFile(t *testing.T) {
579579
})
580580
}
581581
}
582+
583+
func TestCommit_IsImageFileByIndex(t *testing.T) {
584+
t.Run("not a blob", func(t *testing.T) {
585+
c, err := testrepo.CatFileCommit("4e59b72440188e7c2578299fc28ea425fbe9aece")
586+
if err != nil {
587+
t.Fatal(err)
588+
}
589+
590+
isImage, err := c.IsImageFileByIndex("fcf7087e732bfe3c25328248a9bf8c3ccd85bed4") // "gogs"
591+
if err != nil {
592+
t.Fatal(err)
593+
}
594+
assert.False(t, isImage)
595+
})
596+
597+
tests := []struct {
598+
id string
599+
index string
600+
expVal bool
601+
}{
602+
{
603+
id: "4eaa8d4b05e731e950e2eaf9e8b92f522303ab41",
604+
index: "adfd6da3c0a3fb038393144becbf37f14f780087", // "README.txt"
605+
expVal: false,
606+
},
607+
{
608+
id: "4eaa8d4b05e731e950e2eaf9e8b92f522303ab41",
609+
index: "2ce918888b0fdd4736767360fc5e3e83daf47fce", // "img/sourcegraph.png"
610+
expVal: true,
611+
},
612+
}
613+
for _, test := range tests {
614+
t.Run("", func(t *testing.T) {
615+
c, err := testrepo.CatFileCommit(test.id)
616+
if err != nil {
617+
t.Fatal(err)
618+
}
619+
620+
isImage, err := c.IsImageFileByIndex(test.index)
621+
if err != nil {
622+
t.Fatal(err)
623+
}
624+
625+
assert.Equal(t, test.expVal, isImage)
626+
})
627+
}
628+
}

repo_commit.go

+23
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,29 @@ func (r *Repository) CatFileCommit(rev string, opts ...CatFileCommitOptions) (*C
108108
return c, nil
109109
}
110110

111+
// CatFileTypeOptions contains optional arguments for showing the object type.
112+
// Docs: https://git-scm.com/docs/git-cat-file#Documentation/git-cat-file.txt--t
113+
type CatFileTypeOptions struct {
114+
// The timeout duration before giving up for each shell command execution.
115+
// The default timeout duration will be used when not supplied.
116+
Timeout time.Duration
117+
}
118+
119+
// CatFileType returns the object type of given revision of the repository.
120+
func (r *Repository) CatFileType(rev string, opts ...CatFileTypeOptions) (ObjectType, error) {
121+
var opt CatFileTypeOptions
122+
if len(opts) > 0 {
123+
opt = opts[0]
124+
}
125+
126+
typ, err := NewCommand("cat-file", "-t", rev).RunInDirWithTimeout(opt.Timeout, r.path)
127+
if err != nil {
128+
return "", err
129+
}
130+
typ = bytes.TrimSpace(typ)
131+
return ObjectType(typ), nil
132+
}
133+
111134
// BranchCommit returns the latest commit of given branch of the repository.
112135
// The branch must be given in short name e.g. "master".
113136
func (r *Repository) BranchCommit(branch string, opts ...CatFileCommitOptions) (*Commit, error) {

repo_tag.go

+2-3
Original file line numberDiff line numberDiff line change
@@ -62,14 +62,13 @@ func (r *Repository) getTag(timeout time.Duration, id *SHA1) (*Tag, error) {
6262
}
6363

6464
// Check tag type
65-
typ, err := NewCommand("cat-file", "-t", id.String()).RunInDirWithTimeout(timeout, r.path)
65+
typ, err := r.CatFileType(id.String(), CatFileTypeOptions{Timeout: timeout})
6666
if err != nil {
6767
return nil, err
6868
}
69-
typ = bytes.TrimSpace(typ)
7069

7170
var tag *Tag
72-
switch ObjectType(typ) {
71+
switch typ {
7372
case ObjectCommit: // Tag is a commit
7473
tag = &Tag{
7574
typ: ObjectCommit,

tree_blob.go

+26
Original file line numberDiff line numberDiff line change
@@ -59,3 +59,29 @@ func (t *Tree) Blob(subpath string, opts ...LsTreeOptions) (*Blob, error) {
5959

6060
return nil, ErrNotBlob
6161
}
62+
63+
// BlobByIndex returns blob object by given index.
64+
func (t *Tree) BlobByIndex(index string) (*Blob, error) {
65+
typ, err := t.repo.CatFileType(index)
66+
if err != nil {
67+
return nil, err
68+
}
69+
70+
if typ != ObjectBlob {
71+
return nil, ErrNotBlob
72+
}
73+
74+
id, err := t.repo.RevParse(index)
75+
if err != nil {
76+
return nil, err
77+
}
78+
79+
return &Blob{
80+
TreeEntry: &TreeEntry{
81+
mode: EntryBlob,
82+
typ: ObjectBlob,
83+
id: MustIDFromString(id),
84+
parent: t,
85+
},
86+
}, nil
87+
}

0 commit comments

Comments
 (0)