forked from pivotal-cf/cred-alert
/
syncer.go
134 lines (99 loc) · 2.61 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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
package teamstr
import (
"log"
"sort"
"context"
"github.com/deckarep/golang-set"
"github.com/google/go-github/github"
)
//go:generate counterfeiter . OrgRepo
type OrgRepo interface {
AddTeamRepo(ctx context.Context , team int, owner string, repo string, opt *github.OrganizationAddTeamRepoOptions) (*github.Response, error)
ListTeamRepos(ctx context.Context, team int, opt *github.ListOptions) ([]*github.Repository, *github.Response, error)
}
//go:generate counterfeiter . RepoRepo
type RepoRepo interface {
ListByOrg(ctx context.Context, org string, opt *github.RepositoryListByOrgOptions) ([]*github.Repository, *github.Response, error)
}
type Syncer struct {
orgRepo OrgRepo
repoRepo RepoRepo
}
func NewSyncer(orgRepo OrgRepo, repoRepo RepoRepo) *Syncer {
return &Syncer{
orgRepo: orgRepo,
repoRepo: repoRepo,
}
}
func (s *Syncer) Swim(orgName string, teamID int) error {
orgRepos, err := s.orgRepos(orgName)
if err != nil {
return err
}
teamRepos, err := s.teamRepos(teamID)
if err != nil {
return err
}
reposToAdd := orgRepos.Difference(teamRepos).ToSlice()
return s.sync(orgName, teamID, reposToAdd)
}
func (s *Syncer) orgRepos(orgName string) (mapset.Set, error) {
opts := &github.RepositoryListByOrgOptions{
ListOptions: github.ListOptions{PerPage: 30},
}
var repos []*github.Repository
for {
rs, resp, err := s.repoRepo.ListByOrg(context.TODO(), orgName, opts)
if err != nil {
return nil, err
}
repos = append(repos, rs...)
if resp.NextPage == 0 {
break
}
opts.ListOptions.Page = resp.NextPage
}
repoSet := mapset.NewSet()
for _, repo := range repos {
repoSet.Add(*repo.Name)
}
return repoSet, nil
}
func (s *Syncer) teamRepos(teamID int) (mapset.Set, error) {
opts := &github.ListOptions{PerPage: 30}
var repos []*github.Repository
for {
rs, resp, err := s.orgRepo.ListTeamRepos(context.TODO(), teamID, opts)
if err != nil {
return nil, err
}
repos = append(repos, rs...)
if resp.NextPage == 0 {
break
}
opts.Page = resp.NextPage
}
repoSet := mapset.NewSet()
for _, repo := range repos {
repoSet.Add(*repo.Name)
}
return repoSet, nil
}
func (s *Syncer) sync(orgName string, teamID int, reposToAdd []interface{}) error {
strRepos := []string{}
for _, repo := range reposToAdd {
repoName := repo.(string)
strRepos = append(strRepos, repoName)
}
sort.Strings(strRepos)
for _, repo := range strRepos {
log.Println("Adding repo: ", repo)
_, err := s.orgRepo.AddTeamRepo(context.TODO(), teamID, orgName, repo, &github.OrganizationAddTeamRepoOptions{
Permission: "pull",
})
if err != nil {
return err
}
}
return nil
}