Skip to content

Commit dcee702

Browse files
committed
Add env var to skip go-git errors
Signed-off-by: Javi Fontan <[email protected]>
1 parent 0bd1c13 commit dcee702

File tree

4 files changed

+162
-49
lines changed

4 files changed

+162
-49
lines changed

cmd/gitbase/server.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@ import (
2121
// not be empty.
2222
var enableUnstableSquash = os.Getenv("UNSTABLE_SQUASH_ENABLE") != ""
2323

24+
// By default when gitbase encounters and error in a repository it stops
25+
// the query. With this parameter it won't complain and just skip those
26+
// rows or repositories.
27+
var skipGitErrors = os.Getenv("GITBASE_SKIP_GIT_ERRORS") != ""
28+
2429
type cmdServer struct {
2530
Verbose bool `short:"v" description:"Activates the verbose mode"`
2631

@@ -84,7 +89,9 @@ func (c *cmdServer) Execute(args []string) error {
8489
Auth: auth,
8590
},
8691
c.engine,
87-
gitbase.NewSessionBuilder(c.pool),
92+
gitbase.NewSessionBuilder(c.pool,
93+
gitbase.WithSkipGitErrors(skipGitErrors),
94+
),
8895
)
8996
if err != nil {
9097
return err

repository_pool.go

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -242,13 +242,9 @@ type RepositoryIter struct {
242242
// when there are no more Repositories to retrieve.
243243
func (i *RepositoryIter) Next() (*Repository, error) {
244244
r, err := i.pool.GetPos(i.pos)
245-
if err != nil {
246-
return nil, err
247-
}
248-
249245
i.pos++
250246

251-
return r, nil
247+
return r, err
252248
}
253249

254250
// Close finished iterator. It's no-op.
@@ -330,6 +326,7 @@ func NewRowRepoIter(
330326
go func() {
331327
repoIter.wg.Wait()
332328
close(repoIter.rows)
329+
closeIter(&repoIter)
333330
}()
334331

335332
return &repoIter, nil
@@ -387,9 +384,11 @@ func (i *rowRepoIter) fillRepoChannel() {
387384
return
388385

389386
default:
390-
closeIter(i)
391-
i.setError(err)
392-
return
387+
if !i.session.SkipGitErrors {
388+
closeIter(i)
389+
i.setError(err)
390+
return
391+
}
393392
}
394393
}
395394
}
@@ -439,10 +438,14 @@ func (i *rowRepoIter) rowReader(num int) {
439438
break loop
440439

441440
default:
442-
iter.Close()
443-
i.setError(err)
444-
closeIter(i)
445-
return
441+
if !i.session.SkipGitErrors {
442+
iter.Close()
443+
i.setError(err)
444+
closeIter(i)
445+
return
446+
} else {
447+
break loop
448+
}
446449
}
447450
}
448451
}

repository_pool_test.go

Lines changed: 130 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -266,83 +266,177 @@ func TestRepositoryPoolAddDir(t *testing.T) {
266266
require.ElementsMatch(arrayExpected, arrayID)
267267
}
268268

269+
func TestRepositoryPoolSiva(t *testing.T) {
270+
require := require.New(t)
271+
272+
expectedRepos := 3
273+
274+
pool := NewRepositoryPool()
275+
path := filepath.Join(
276+
os.Getenv("GOPATH"),
277+
"src", "github.com", "src-d", "gitbase",
278+
"_testdata",
279+
)
280+
281+
require.NoError(pool.AddSivaDir(path))
282+
require.Equal(expectedRepos, len(pool.repositories))
283+
284+
expected := []int{606, 452, 75}
285+
result := make([]int, expectedRepos)
286+
287+
for i := 0; i < expectedRepos; i++ {
288+
repo, err := pool.GetPos(i)
289+
require.NoError(err)
290+
291+
iter, err := repo.Repo.CommitObjects()
292+
require.NoError(err)
293+
294+
require.NoError(iter.ForEach(func(c *object.Commit) error {
295+
result[i]++
296+
return nil
297+
}))
298+
}
299+
300+
require.Equal(expected, result)
301+
}
302+
269303
var errIter = fmt.Errorf("Error iter")
270304

271-
type testErrorIter struct{}
305+
type newIteratorFunc func(*Repository) (RowRepoIter, error)
306+
type nextFunc func() (sql.Row, error)
307+
308+
type testErrorIter struct {
309+
newIterator newIteratorFunc
310+
next nextFunc
311+
}
272312

273313
func (d *testErrorIter) NewIterator(
274314
repo *Repository,
275315
) (RowRepoIter, error) {
316+
if d.newIterator != nil {
317+
return d.newIterator(repo)
318+
}
319+
276320
return nil, errIter
277-
// return &testErrorIter{}, nil
278321
}
279322

280323
func (d *testErrorIter) Next() (sql.Row, error) {
324+
if d.next != nil {
325+
return d.next()
326+
}
327+
281328
return nil, io.EOF
282329
}
283330

284331
func (d *testErrorIter) Close() error {
285332
return nil
286333
}
287334

288-
func TestRepositoryErrorIter(t *testing.T) {
335+
func testCaseRepositoryErrorIter(
336+
t *testing.T,
337+
pool *RepositoryPool,
338+
iter RowRepoIter,
339+
retError error,
340+
skipGitErrors bool,
341+
) {
289342
require := require.New(t)
290343

291-
path := fixtures.Basic().ByTag("worktree").One().Worktree().Root()
292-
pool := NewRepositoryPool()
293-
pool.Add("one", path, gitRepo)
294-
295344
timeout, cancel := context.WithTimeout(context.Background(), 5*time.Second)
345+
ctx := sql.NewContext(timeout,
346+
sql.WithSession(NewSession(pool, WithSkipGitErrors(skipGitErrors))),
347+
)
296348

297-
ctx := sql.NewContext(timeout, sql.WithSession(NewSession(pool)))
298-
eIter := &testErrorIter{}
299-
300-
iter, err := NewRowRepoIter(ctx, eIter)
301-
repoIter := iter.(*rowRepoIter)
349+
r, err := NewRowRepoIter(ctx, iter)
302350
require.NoError(err)
303351

352+
repoIter, ok := r.(*rowRepoIter)
353+
require.True(ok)
354+
304355
go func() {
305-
repoIter.Next()
356+
for {
357+
_, err := repoIter.Next()
358+
if err != nil {
359+
break
360+
}
361+
}
306362
}()
307363

308364
select {
309365
case <-repoIter.done:
310-
require.Equal(errIter, repoIter.err)
366+
require.Equal(retError, repoIter.err)
311367
}
312368

313369
cancel()
314370
}
315371

316-
func TestRepositoryPoolSiva(t *testing.T) {
317-
require := require.New(t)
372+
func TestRepositoryErrorIter(t *testing.T) {
373+
path := fixtures.Basic().ByTag("worktree").One().Worktree().Root()
374+
pool := NewRepositoryPool()
375+
pool.Add("one", path, gitRepo)
318376

319-
expectedRepos := 3
377+
iter := &testErrorIter{}
378+
testCaseRepositoryErrorIter(t, pool, iter, errIter, false)
379+
}
320380

381+
func TestRepositoryErrorBadRepository(t *testing.T) {
321382
pool := NewRepositoryPool()
322-
path := filepath.Join(
323-
os.Getenv("GOPATH"),
324-
"src", "github.com", "src-d", "gitbase",
325-
"_testdata",
326-
)
383+
pool.Add("one", "badpath", gitRepo)
327384

328-
require.NoError(pool.AddSivaDir(path))
329-
require.Equal(expectedRepos, len(pool.repositories))
385+
iter := &testErrorIter{}
330386

331-
expected := []int{606, 452, 75}
332-
result := make([]int, expectedRepos)
387+
newIterator := func(*Repository) (RowRepoIter, error) {
388+
return iter, nil
389+
}
333390

334-
for i := 0; i < expectedRepos; i++ {
335-
repo, err := pool.GetPos(i)
336-
require.NoError(err)
391+
count := 0
392+
next := func() (sql.Row, error) {
393+
if count >= 10 {
394+
return nil, io.EOF
395+
}
337396

338-
iter, err := repo.Repo.CommitObjects()
339-
require.NoError(err)
397+
count++
340398

341-
require.NoError(iter.ForEach(func(c *object.Commit) error {
342-
result[i]++
343-
return nil
344-
}))
399+
return sql.NewRow("test"), nil
345400
}
346401

347-
require.Equal(expected, result)
402+
iter.newIterator = newIterator
403+
iter.next = next
404+
405+
testCaseRepositoryErrorIter(t, pool, iter, git.ErrRepositoryNotExists, false)
406+
testCaseRepositoryErrorIter(t, pool, iter, io.EOF, true)
407+
}
408+
409+
func TestRepositoryErrorBadRow(t *testing.T) {
410+
path := fixtures.Basic().ByTag("worktree").One().Worktree().Root()
411+
pool := NewRepositoryPool()
412+
pool.Add("one", path, gitRepo)
413+
414+
iter := &testErrorIter{}
415+
416+
newIterator := func(*Repository) (RowRepoIter, error) {
417+
return iter, nil
418+
}
419+
420+
errRow := fmt.Errorf("bad row")
421+
422+
count := 0
423+
next := func() (sql.Row, error) {
424+
if count == 5 {
425+
return nil, errRow
426+
}
427+
428+
if count >= 10 {
429+
return nil, io.EOF
430+
}
431+
432+
count++
433+
434+
return sql.NewRow("test"), nil
435+
}
436+
437+
iter.newIterator = newIterator
438+
iter.next = next
439+
440+
testCaseRepositoryErrorIter(t, pool, iter, errRow, false)
441+
testCaseRepositoryErrorIter(t, pool, iter, io.EOF, true)
348442
}

session.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ type Session struct {
2121
bblfshMu sync.Mutex
2222
bblfshEndpoint string
2323
bblfshClient *bblfsh.Client
24+
25+
SkipGitErrors bool
2426
}
2527

2628
const (
@@ -38,6 +40,13 @@ func WithBblfshEndpoint(endpoint string) SessionOption {
3840
}
3941
}
4042

43+
// WithSkipGitErrors changes the behavior with go-git error.
44+
func WithSkipGitErrors(enabled bool) SessionOption {
45+
return func(s *Session) {
46+
s.SkipGitErrors = enabled
47+
}
48+
}
49+
4150
// NewSession creates a new Session. It requires a repository pool and any
4251
// number of session options can be passed to configure the session.
4352
func NewSession(pool *RepositoryPool, opts ...SessionOption) *Session {

0 commit comments

Comments
 (0)