-
Notifications
You must be signed in to change notification settings - Fork 1
/
organization_syncer.go
110 lines (89 loc) · 2.54 KB
/
organization_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
package accountsync
import (
"log"
"github.com/google/go-github/github"
)
type OrganizationSyncer struct {
db *DB
cfg *Config
}
type orgSyncContext struct {
user *User
client *github.Client
curOrgs map[string]*Organization
ghOrgs map[string]*github.Organization
}
func NewOrganizationSyncer(db *DB, cfg *Config) *OrganizationSyncer {
return &OrganizationSyncer{db: db, cfg: cfg}
}
func (osync *OrganizationSyncer) Sync(user *User, client *github.Client) error {
ctx := &orgSyncContext{
user: user,
client: client,
curOrgs: map[string]*Organization{},
ghOrgs: map[string]*github.Organization{},
}
err := user.HydrateOrganizations(osync.db)
if err != nil {
return err
}
for _, org := range user.Organizations {
ctx.curOrgs[org.Login.String] = org
}
ghOrgs, err := osync.getGithubOrgs(ctx)
if err != nil {
return err
}
for _, org := range ghOrgs {
ctx.ghOrgs[*org.Login] = org
}
for _, org := range user.Organizations {
log.Printf("sync=organizations login=%s org=%s", user.Login.String, org.Login.String)
// TODO: create or update org
// TODO: create new memberships
// TODO: remove outdated memberships
}
return nil
}
func (osync *OrganizationSyncer) getCurrentlySyncedOrganizations(ctx *orgSyncContext) ([]*Organization, error) {
orgs := []*Organization{}
err := osync.db.Select(&orgs, `
SELECT *
FROM organizations
WHERE id IN (
SELECT organization_id
FROM memberships
WHERE user_id = $1
)`, ctx.user.ID)
return orgs, err
}
func (osync *OrganizationSyncer) getGithubOrgs(ctx *orgSyncContext) ([]*github.Organization, error) {
allOrgs := []*github.Organization{}
listOpts := &github.ListOptions{Page: 1, PerPage: 100}
for {
ghOrgs, resp, err := ctx.client.Organizations.List("", listOpts)
if err != nil {
return allOrgs, err
}
for _, org := range ghOrgs {
log.Printf("msg=\"fetching full org\" sync=organizations login=%v page=%v org=%v",
ctx.user.Login.String, listOpts.Page, *org.Login)
fullOrg, _, err := ctx.client.Organizations.Get(*org.Login)
if err != nil {
return allOrgs, err
}
if *fullOrg.PublicRepos > osync.cfg.OrganizationsRepositoriesLimit {
log.Printf("msg=\"skipping org\" sync=organizations login=%v page=%v org=%v public_repos=%v public_repos_limit=%v",
ctx.user.Login.String, listOpts.Page, *fullOrg.Login, *fullOrg.PublicRepos,
osync.cfg.OrganizationsRepositoriesLimit)
continue
}
allOrgs = append(allOrgs, fullOrg)
}
if resp.NextPage == 0 {
break
}
listOpts.Page = resp.NextPage
}
return allOrgs, nil
}