Skip to content

Commit cf4f34d

Browse files
author
Juanjo Alvarez
committed
Blame: Use a generator to return results
Signed-off-by: Juanjo Alvarez <[email protected]>
1 parent beb11aa commit cf4f34d

File tree

2 files changed

+72
-26
lines changed

2 files changed

+72
-26
lines changed

internal/function/blame.go

Lines changed: 60 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,68 @@ package function
33
import (
44
"fmt"
55
"github.com/src-d/gitbase"
6-
"gopkg.in/src-d/go-git.v4"
76
"github.com/src-d/go-mysql-server/sql"
7+
"gopkg.in/src-d/go-git.v4"
88

99
"gopkg.in/src-d/go-git.v4/plumbing"
1010
"gopkg.in/src-d/go-git.v4/plumbing/object"
1111
)
1212

13+
type BlameGenerator struct {
14+
commit *object.Commit
15+
fIter *object.FileIter
16+
curLine int
17+
curFile *object.File
18+
lines []*git.Line
19+
}
20+
21+
func NewBlameGenerator(c *object.Commit, f *object.FileIter) (*BlameGenerator, error) {
22+
return &BlameGenerator{commit: c, fIter: f, curLine: -1}, nil
23+
}
24+
25+
func (g *BlameGenerator) loadNewFile() error {
26+
var err error
27+
g.curFile, err = g.fIter.Next()
28+
if err != nil {
29+
return err
30+
}
31+
32+
result, err := git.Blame(g.commit, g.curFile.Name)
33+
if err != nil {
34+
return err
35+
}
36+
g.lines = result.Lines
37+
g.curLine = 0
38+
return nil
39+
}
40+
41+
func (g *BlameGenerator) Next() (interface{}, error) {
42+
if g.curLine == -1 || g.curLine >= len(g.lines) {
43+
err := g.loadNewFile()
44+
if err != nil {
45+
return nil, err
46+
}
47+
}
48+
49+
l := g.lines[g.curLine]
50+
b := BlameLine{
51+
Commit: g.commit.Hash.String(),
52+
File: g.curFile.Name,
53+
LineNum: g.curLine,
54+
Author: l.Author,
55+
Text: l.Text,
56+
}
57+
g.curLine++
58+
return b, nil
59+
}
60+
61+
func (g *BlameGenerator) Close() error {
62+
g.fIter.Close()
63+
return nil
64+
}
65+
66+
var _ sql.Generator = (*BlameGenerator)(nil)
67+
1368
type (
1469
// Blame implements git-blame function as UDF
1570
Blame struct {
@@ -83,27 +138,13 @@ func (b *Blame) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) {
83138
if err != nil {
84139
return nil, err
85140
}
86-
defer fIter.Close()
87141

88-
var lines []BlameLine
89-
for f, err := fIter.Next(); err == nil; f, err = fIter.Next() {
90-
result, err := git.Blame(commit, f.Name)
91-
if err != nil {
92-
return nil, err
93-
}
94-
95-
for i, l := range result.Lines {
96-
lines = append(lines, BlameLine{
97-
Commit: commit.Hash.String(),
98-
File: f.Name,
99-
LineNum: i,
100-
Author: l.Author,
101-
Text: l.Text,
102-
})
103-
}
142+
bg, err := NewBlameGenerator(commit, fIter)
143+
if err != nil {
144+
return nil, err
104145
}
105146

106-
return lines, nil
147+
return bg, nil
107148
}
108149

109150
func (b *Blame) resolveCommit(ctx *sql.Context, repo *gitbase.Repository, row sql.Row) (*object.Commit, error) {

internal/function/blame_test.go

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -59,26 +59,31 @@ func TestBlameEval(t *testing.T) {
5959
"CHANGELOG",
6060
0,
6161
62-
"Creating changelog",
62+
"Initial changelog",
6363
},
6464
},
6565
}
6666

6767
for _, tc := range testCases {
6868
t.Run(tc.name, func(t *testing.T) {
6969
blame := NewBlame(tc.repo, tc.commit)
70-
results, err := blame.Eval(ctx, tc.row)
70+
blameGen, err := blame.Eval(ctx, tc.row)
7171
require.NoError(t, err)
72+
bg := blameGen.(*BlameGenerator)
73+
defer bg.Close()
74+
7275
lineCount := 0
73-
for i, r := range results.([]BlameLine) {
74-
if r.File != tc.expected.File {
76+
for i, err := bg.Next(); err == nil; i, err = bg.Next() {
77+
i := i.(BlameLine)
78+
if i.File != tc.expected.File {
7579
continue
7680
}
77-
lineCount++
78-
if i != tc.testedLine {
81+
if lineCount != tc.testedLine {
82+
lineCount++
7983
continue
8084
}
81-
require.EqualValues(t, tc.expected, r)
85+
lineCount++
86+
require.EqualValues(t, tc.expected, i)
8287
}
8388
require.Equal(t, tc.lineCount, lineCount)
8489
})

0 commit comments

Comments
 (0)