Skip to content
This repository was archived by the owner on Sep 11, 2020. It is now read-only.

Commit f821e13

Browse files
committed
Merge pull request #9 from mcuadros/blame-cleanup
blame code reorganization, and mutting the test
2 parents c22c181 + b543e4e commit f821e13

11 files changed

+132
-196
lines changed

blame/blame.go renamed to blame.go

+30-37
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
//
77
// This package also provides a pretty print function to output the
88
// results of a blame in a similar format to the git-blame command.
9-
package blame
9+
package git
1010

1111
import (
1212
"bytes"
@@ -16,14 +16,18 @@ import (
1616
"strings"
1717
"unicode/utf8"
1818

19-
"gopkg.in/src-d/go-git.v2"
2019
"gopkg.in/src-d/go-git.v2/core"
2120
"gopkg.in/src-d/go-git.v2/diff"
22-
"gopkg.in/src-d/go-git.v2/revlist"
2321
)
2422

25-
// Blame returns the last commit that modified each line of a file in
26-
// a repository.
23+
type Blame struct {
24+
Path string
25+
Rev core.Hash
26+
Lines []*line
27+
}
28+
29+
// Blame returns the last commit that modified each line of a file in a
30+
// repository.
2731
//
2832
// The file to blame is identified by the input arguments: repo, commit and path.
2933
// The output is a slice of commits, one for each line in the file.
@@ -66,19 +70,9 @@ import (
6670
// 1. Add memoization between revlist and assign.
6771
//
6872
// 2. It is using much more memory than needed, see the TODOs below.
69-
70-
type Blame struct {
71-
Repo string
72-
Path string
73-
Rev string
74-
Lines []*line
75-
}
76-
77-
func New(repo *git.Repository, path string, commit *git.Commit) (*Blame, error) {
78-
// init the internal blame struct
73+
func (c *Commit) Blame(path string) (*Blame, error) {
7974
b := new(blame)
80-
b.repo = repo
81-
b.fRev = commit
75+
b.fRev = c
8276
b.path = path
8377

8478
// get all the file revisions
@@ -104,9 +98,8 @@ func New(repo *git.Repository, path string, commit *git.Commit) (*Blame, error)
10498
}
10599

106100
return &Blame{
107-
Repo: repo.URL,
108101
Path: path,
109-
Rev: commit.Hash.String(),
102+
Rev: c.Hash,
110103
Lines: lines,
111104
}, nil
112105
}
@@ -123,7 +116,7 @@ func newLine(author, text string) *line {
123116
}
124117
}
125118

126-
func newLines(contents []string, commits []*git.Commit) ([]*line, error) {
119+
func newLines(contents []string, commits []*Commit) ([]*line, error) {
127120
if len(contents) != len(commits) {
128121
return nil, errors.New("contents and commits have different length")
129122
}
@@ -138,18 +131,18 @@ func newLines(contents []string, commits []*git.Commit) ([]*line, error) {
138131
// this struct is internally used by the blame function to hold its
139132
// inputs, outputs and state.
140133
type blame struct {
141-
repo *git.Repository // the repo holding the history of the file to blame
142-
path string // the path of the file to blame
143-
fRev *git.Commit // the commit of the final revision of the file to blame
144-
revs revlist.Revs // the chain of revisions affecting the the file to blame
145-
data []string // the contents of the file across all its revisions
146-
graph [][]*git.Commit // the graph of the lines in the file across all the revisions TODO: not all commits are needed, only the current rev and the prev
134+
path string // the path of the file to blame
135+
fRev *Commit // the commit of the final revision of the file to blame
136+
revs []*Commit // the chain of revisions affecting the the file to blame
137+
data []string // the contents of the file across all its revisions
138+
graph [][]*Commit // the graph of the lines in the file across all the revisions TODO: not all commits are needed, only the current rev and the prev
147139
}
148140

149141
// calculte the history of a file "path", starting from commit "from", sorted by commit date.
150142
func (b *blame) fillRevs() error {
151143
var err error
152-
b.revs, err = revlist.NewRevs(b.repo, b.fRev, b.path)
144+
145+
b.revs, err = b.fRev.References(b.path)
153146
if err != nil {
154147
return err
155148
}
@@ -158,7 +151,7 @@ func (b *blame) fillRevs() error {
158151

159152
// build graph of a file from its revision history
160153
func (b *blame) fillGraphAndData() error {
161-
b.graph = make([][]*git.Commit, len(b.revs))
154+
b.graph = make([][]*Commit, len(b.revs))
162155
b.data = make([]string, len(b.revs)) // file contents in all the revisions
163156
// for every revision of the file, starting with the first
164157
// one...
@@ -169,15 +162,15 @@ func (b *blame) fillGraphAndData() error {
169162
return nil
170163
}
171164
b.data[i] = file.Contents()
172-
nLines := git.CountLines(b.data[i])
165+
nLines := countLines(b.data[i])
173166
// create a node for each line
174-
b.graph[i] = make([]*git.Commit, nLines)
167+
b.graph[i] = make([]*Commit, nLines)
175168
// assign a commit to each node
176169
// if this is the first revision, then the node is assigned to
177170
// this first commit.
178171
if i == 0 {
179172
for j := 0; j < nLines; j++ {
180-
b.graph[i][j] = (*git.Commit)(b.revs[i])
173+
b.graph[i][j] = (*Commit)(b.revs[i])
181174
}
182175
} else {
183176
// if this is not the first commit, then assign to the old
@@ -191,11 +184,11 @@ func (b *blame) fillGraphAndData() error {
191184

192185
// sliceGraph returns a slice of commits (one per line) for a particular
193186
// revision of a file (0=first revision).
194-
func (b *blame) sliceGraph(i int) []*git.Commit {
187+
func (b *blame) sliceGraph(i int) []*Commit {
195188
fVs := b.graph[i]
196-
result := make([]*git.Commit, 0, len(fVs))
189+
result := make([]*Commit, 0, len(fVs))
197190
for _, v := range fVs {
198-
c := git.Commit(*v)
191+
c := Commit(*v)
199192
result = append(result, &c)
200193
}
201194
return result
@@ -209,7 +202,7 @@ func (b *blame) assignOrigin(c, p int) {
209202
sl := -1 // source line
210203
dl := -1 // destination line
211204
for h := range hunks {
212-
hLines := git.CountLines(hunks[h].Text)
205+
hLines := countLines(hunks[h].Text)
213206
for hl := 0; hl < hLines; hl++ {
214207
switch {
215208
case hunks[h].Type == 0:
@@ -218,7 +211,7 @@ func (b *blame) assignOrigin(c, p int) {
218211
b.graph[c][dl] = b.graph[p][sl]
219212
case hunks[h].Type == 1:
220213
dl++
221-
b.graph[c][dl] = (*git.Commit)(b.revs[c])
214+
b.graph[c][dl] = (*Commit)(b.revs[c])
222215
case hunks[h].Type == -1:
223216
sl++
224217
default:
@@ -255,7 +248,7 @@ func (b *blame) GoString() string {
255248
}
256249

257250
// utility function to pretty print the author.
258-
func prettyPrintAuthor(c *git.Commit) string {
251+
func prettyPrintAuthor(c *Commit) string {
259252
return fmt.Sprintf("%s %s", c.Author.Name, c.Author.When.Format("2006-01-02"))
260253
}
261254

blame/blame_test.go renamed to blame_test.go

+14-38
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,25 @@
1-
package blame
1+
package git
22

33
import (
4-
"bytes"
54
"os"
6-
"testing"
75

8-
"gopkg.in/src-d/go-git.v2"
96
"gopkg.in/src-d/go-git.v2/core"
107
"gopkg.in/src-d/go-git.v2/formats/packfile"
118

129
. "gopkg.in/check.v1"
1310
)
1411

15-
func Test(t *testing.T) { TestingT(t) }
16-
17-
type SuiteCommon struct {
18-
repos map[string]*git.Repository
12+
type BlameCommon struct {
13+
repos map[string]*Repository
1914
}
2015

21-
var _ = Suite(&SuiteCommon{})
22-
23-
var fixtureRepos = [...]struct {
24-
url string
25-
packfile string
26-
}{
27-
{"https://github.com/tyba/git-fixture.git", "../formats/packfile/fixtures/git-fixture.ofs-delta"},
28-
{"https://github.com/spinnaker/spinnaker.git", "../formats/packfile/fixtures/spinnaker-spinnaker.pack"},
29-
}
16+
var _ = Suite(&BlameCommon{})
3017

3118
// create the repositories of the fixtures
32-
func (s *SuiteCommon) SetUpSuite(c *C) {
33-
s.repos = make(map[string]*git.Repository, 0)
19+
func (s *BlameCommon) SetUpSuite(c *C) {
20+
s.repos = make(map[string]*Repository, 0)
3421
for _, fixRepo := range fixtureRepos {
35-
repo := git.NewPlainRepository()
22+
repo := NewPlainRepository()
3623
repo.URL = fixRepo.url
3724

3825
d, err := os.Open(fixRepo.packfile)
@@ -60,7 +47,7 @@ type blameTest struct {
6047
blames []string // the commits blamed for each line
6148
}
6249

63-
func (s *SuiteCommon) mockBlame(t blameTest, c *C) (blame *Blame) {
50+
func (s *BlameCommon) mockBlame(t blameTest, c *C) (blame *Blame) {
6451
repo, ok := s.repos[t.repo]
6552
c.Assert(ok, Equals, true)
6653

@@ -85,16 +72,15 @@ func (s *SuiteCommon) mockBlame(t blameTest, c *C) (blame *Blame) {
8572
}
8673

8774
return &Blame{
88-
Repo: t.repo,
8975
Path: t.path,
90-
Rev: t.rev,
76+
Rev: core.NewHash(t.rev),
9177
Lines: blamedLines,
9278
}
9379
}
9480

9581
// run a blame on all the suite's tests
96-
func (s *SuiteCommon) TestBlame(c *C) {
97-
for i, t := range blameTests {
82+
func (s *BlameCommon) TestBlame(c *C) {
83+
for _, t := range blameTests {
9884
expected := s.mockBlame(t, c)
9985

10086
repo, ok := s.repos[t.repo]
@@ -103,22 +89,12 @@ func (s *SuiteCommon) TestBlame(c *C) {
10389
commit, err := repo.Commit(core.NewHash(t.rev))
10490
c.Assert(err, IsNil)
10591

106-
obtained, err := New(repo, t.path, commit)
107-
c.Assert(err, IsNil, Commentf("subtest %d", i))
108-
109-
c.Assert(obtained, DeepEquals, expected, Commentf("subtest %d: %s",
110-
i, sideBySide(obtained, expected)))
92+
obtained, err := commit.Blame(t.path)
93+
c.Assert(err, IsNil)
94+
c.Assert(obtained, DeepEquals, expected)
11195
}
11296
}
11397

114-
func sideBySide(output, expected *Blame) string {
115-
var buf bytes.Buffer
116-
buf.WriteString(output.Repo)
117-
buf.WriteString(" ")
118-
buf.WriteString(expected.Repo)
119-
return buf.String()
120-
}
121-
12298
// utility function to avoid writing so many repeated commits
12399
func repeat(s string, n int) []string {
124100
if n < 0 {

clients/ssh/git_upload_pack_test.go

-16
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ const (
2525
)
2626

2727
func (s *SuiteRemote) TestConnect(c *C) {
28-
fmt.Println("TestConnect")
2928
r := NewGitUploadPackService()
3029
c.Assert(r.Connect(fixRepo), Equals, ErrAuthRequired)
3130
}
@@ -59,7 +58,6 @@ func (c *sshAgentConn) close() error {
5958
}
6059

6160
func (s *SuiteRemote) TestConnectWithPublicKeysCallback(c *C) {
62-
fmt.Println("TestConnectWithPublicKeysCallback")
6361
agent, err := newSSHAgentConn()
6462
c.Assert(err, IsNil)
6563
defer func() { c.Assert(agent.close(), IsNil) }()
@@ -72,19 +70,16 @@ func (s *SuiteRemote) TestConnectWithPublicKeysCallback(c *C) {
7270
}
7371

7472
func (s *SuiteRemote) TestConnectBadVcs(c *C) {
75-
fmt.Println("TestConnectBadVcs")
7673
r := NewGitUploadPackService()
7774
c.Assert(r.ConnectWithAuth(fixRepoBadVcs, nil), ErrorMatches, fmt.Sprintf(".*%s.*", fixRepoBadVcs))
7875
}
7976

8077
func (s *SuiteRemote) TestConnectNonGit(c *C) {
81-
fmt.Println("TestConnectNonGit")
8278
r := NewGitUploadPackService()
8379
c.Assert(r.ConnectWithAuth(fixRepoNonGit, nil), Equals, ErrUnsupportedVCS)
8480
}
8581

8682
func (s *SuiteRemote) TestConnectNonGithub(c *C) {
87-
fmt.Println("TestConnectNonGit")
8883
r := NewGitUploadPackService()
8984
c.Assert(r.ConnectWithAuth(fixGitRepoNonGithub, nil), Equals, ErrUnsupportedRepo)
9085
}
@@ -97,14 +92,12 @@ func (*mockAuth) Name() string { return "" }
9792
func (*mockAuth) String() string { return "" }
9893

9994
func (s *SuiteRemote) TestConnectWithAuthWrongType(c *C) {
100-
fmt.Println("TestConnectWithAuthWrongType")
10195
r := NewGitUploadPackService()
10296
c.Assert(r.ConnectWithAuth(fixRepo, &mockAuth{}), Equals, ErrInvalidAuthMethod)
10397
c.Assert(r.connected, Equals, false)
10498
}
10599

106100
func (s *SuiteRemote) TestAlreadyConnected(c *C) {
107-
fmt.Println("TestAlreadyConnected")
108101
agent, err := newSSHAgentConn()
109102
c.Assert(err, IsNil)
110103
defer func() { c.Assert(agent.close(), IsNil) }()
@@ -117,7 +110,6 @@ func (s *SuiteRemote) TestAlreadyConnected(c *C) {
117110
}
118111

119112
func (s *SuiteRemote) TestDisconnect(c *C) {
120-
fmt.Println("TestDisconnect")
121113
agent, err := newSSHAgentConn()
122114
c.Assert(err, IsNil)
123115
defer func() { c.Assert(agent.close(), IsNil) }()
@@ -129,13 +121,11 @@ func (s *SuiteRemote) TestDisconnect(c *C) {
129121
}
130122

131123
func (s *SuiteRemote) TestDisconnectedWhenNonConnected(c *C) {
132-
fmt.Println("TestDisconnectedWhenNonConnected")
133124
r := NewGitUploadPackService()
134125
c.Assert(r.Disconnect(), Equals, ErrNotConnected)
135126
}
136127

137128
func (s *SuiteRemote) TestAlreadyDisconnected(c *C) {
138-
fmt.Println("TestAlreadyDisconnected")
139129
agent, err := newSSHAgentConn()
140130
c.Assert(err, IsNil)
141131
defer func() { c.Assert(agent.close(), IsNil) }()
@@ -148,7 +138,6 @@ func (s *SuiteRemote) TestAlreadyDisconnected(c *C) {
148138
}
149139

150140
func (s *SuiteRemote) TestServeralConnections(c *C) {
151-
fmt.Println("TestServeralConnections")
152141
agent, err := newSSHAgentConn()
153142
c.Assert(err, IsNil)
154143
defer func() { c.Assert(agent.close(), IsNil) }()
@@ -169,14 +158,12 @@ func (s *SuiteRemote) TestServeralConnections(c *C) {
169158
}
170159

171160
func (s *SuiteRemote) TestInfoNotConnected(c *C) {
172-
fmt.Println("TestInfoNotConnected")
173161
r := NewGitUploadPackService()
174162
_, err := r.Info()
175163
c.Assert(err, Equals, ErrNotConnected)
176164
}
177165

178166
func (s *SuiteRemote) TestDefaultBranch(c *C) {
179-
fmt.Println("TestDefaultBranch")
180167
agent, err := newSSHAgentConn()
181168
c.Assert(err, IsNil)
182169
defer func() { c.Assert(agent.close(), IsNil) }()
@@ -191,7 +178,6 @@ func (s *SuiteRemote) TestDefaultBranch(c *C) {
191178
}
192179

193180
func (s *SuiteRemote) TestCapabilities(c *C) {
194-
fmt.Println("TestCapabilities")
195181
agent, err := newSSHAgentConn()
196182
c.Assert(err, IsNil)
197183
defer func() { c.Assert(agent.close(), IsNil) }()
@@ -206,7 +192,6 @@ func (s *SuiteRemote) TestCapabilities(c *C) {
206192
}
207193

208194
func (s *SuiteRemote) TestFetchNotConnected(c *C) {
209-
fmt.Println("TestFetchNotConnected")
210195
r := NewGitUploadPackService()
211196
pr := &common.GitUploadPackRequest{}
212197
pr.Want(core.NewHash("6ecf0ef2c2dffb796033e5a02219af86ec6584e5"))
@@ -215,7 +200,6 @@ func (s *SuiteRemote) TestFetchNotConnected(c *C) {
215200
}
216201

217202
func (s *SuiteRemote) TestFetch(c *C) {
218-
fmt.Println("TestFetch")
219203
agent, err := newSSHAgentConn()
220204
c.Assert(err, IsNil)
221205
defer func() { c.Assert(agent.close(), IsNil) }()

0 commit comments

Comments
 (0)