forked from src-d/borges
/
linejobiter.go
77 lines (65 loc) · 1.62 KB
/
linejobiter.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
package borges
import (
"bufio"
"fmt"
"io"
"net/url"
"os"
"path"
"path/filepath"
"github.com/src-d/borges/storage"
)
type lineJobIter struct {
storer storage.RepoStore
*bufio.Scanner
r io.ReadCloser
}
// NewLineJobIter returns a JobIter that returns jobs generated from a reader
// with a list of repository URLs, one per line.
func NewLineJobIter(r io.ReadCloser, storer storage.RepoStore) JobIter {
return &lineJobIter{
storer: storer,
Scanner: bufio.NewScanner(r),
r: r,
}
}
func (i *lineJobIter) Next() (*Job, error) {
if !i.Scan() {
if err := i.Err(); err != nil {
return nil, err
}
return nil, io.EOF
}
line := string(i.Bytes())
// check if the line is an absolute path to a directory.
// If the path is a directory we can look for the .git directory to try
// to guess if it's a git repo or a bare repo.
// If .git does not exist it will be treated as a bare repo (even if it's
// not).
if path.IsAbs(line) {
dotGit := filepath.Join(line, ".git")
if _, err := os.Stat(dotGit); os.IsNotExist(err) {
line = fmt.Sprintf("file://%s", line)
} else if err != nil {
return nil, fmt.Errorf("expecting remote or local repository, instead %q was found", line)
} else {
line = fmt.Sprintf("file://%s", dotGit)
}
}
u, err := url.Parse(line)
if err != nil {
return nil, err
}
if !u.IsAbs() {
return nil, fmt.Errorf("expected absolute URL: %s", line)
}
ID, err := RepositoryID([]string{line}, nil, i.storer)
if err != nil {
return nil, err
}
return &Job{RepositoryID: ID}, nil
}
// Close closes the underlying reader.
func (i *lineJobIter) Close() error {
return i.r.Close()
}