-
Notifications
You must be signed in to change notification settings - Fork 18
/
syncer.go
109 lines (84 loc) · 2.11 KB
/
syncer.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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
package rolodex
import (
"errors"
"os"
"code.cloudfoundry.org/lager"
"cred-alert/metrics"
)
type syncer struct {
repoURL string
repoPath string
gitClient GitSyncClient
teamRepo TeamRepository
logger lager.Logger
successCounter metrics.Counter
failureCounter metrics.Counter
fetchTimer metrics.Timer
}
type Syncer interface {
Sync()
}
//go:generate counterfeiter . GitSyncClient
type GitSyncClient interface {
Fetch(string) (map[string][]string, error)
Clone(string, string) error
HardReset(string, string) error
}
func NewSyncer(logger lager.Logger, emitter metrics.Emitter, repoURL, repoPath string, gitClient GitSyncClient, teamRepo TeamRepository) Syncer {
syncLogger := logger.Session("syncer", lager.Data{
"upstream": repoURL,
"local": repoPath,
})
return &syncer{
repoURL: repoURL,
repoPath: repoPath,
gitClient: gitClient,
teamRepo: teamRepo,
logger: syncLogger,
successCounter: emitter.Counter("rolodex.syncer.fetch.success"),
failureCounter: emitter.Counter("rolodex.syncer.fetch.failure"),
fetchTimer: emitter.Timer("rolodex.syncer.fetch.time"),
}
}
const remoteMaster = "refs/remotes/origin/master"
var errMissingMaster = errors.New("no remote master branch found")
func (s *syncer) Sync() {
if _, err := os.Stat(s.repoPath); os.IsNotExist(err) {
err := s.gitClient.Clone(s.repoURL, s.repoPath)
if err != nil {
s.logger.Error("cloning", err)
return
}
s.teamRepo.Reload()
return
}
var fetchErr error
s.fetchTimer.Time(s.logger, func() {
heads, err := s.gitClient.Fetch(s.repoPath)
if err != nil {
s.logger.Error("fetching", err)
fetchErr = err
return
}
if len(heads) == 0 {
return
}
upstream, found := heads[remoteMaster]
if !found {
s.logger.Error("failed-to-find-updated-master", errMissingMaster)
fetchErr = errMissingMaster
return
}
if err = s.gitClient.HardReset(s.repoPath, upstream[1]); err != nil {
s.logger.Error("reseting", err)
fetchErr = err
return
}
})
if fetchErr != nil {
s.failureCounter.Inc(s.logger)
return
}
s.successCounter.Inc(s.logger)
s.teamRepo.Reload()
}