Skip to content
This repository was archived by the owner on Aug 5, 2022. It is now read-only.

Commit 93e731f

Browse files
a-hilalyMichaelMure
andcommitted
[bridge/github] improve comments and documentation
[bridge/github] improve error handling and tests Co-Authored-By: Michael Muré <[email protected]>
1 parent 4b6949f commit 93e731f

File tree

4 files changed

+69
-101
lines changed

4 files changed

+69
-101
lines changed

bridge/core/bridge.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -313,5 +313,5 @@ func (b *Bridge) ExportAll(since time.Time) (<-chan ExportResult, error) {
313313
return nil, err
314314
}
315315

316-
return exporter.ExportAll(b.repo, since), nil
316+
return exporter.ExportAll(b.repo, since)
317317
}

bridge/core/interfaces.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,5 +34,5 @@ type Importer interface {
3434

3535
type Exporter interface {
3636
Init(conf Configuration) error
37-
ExportAll(repo *cache.RepoCache, since time.Time) <-chan ExportResult
37+
ExportAll(repo *cache.RepoCache, since time.Time) (<-chan ExportResult, error)
3838
}

bridge/github/export.go

+40-37
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ type githubExporter struct {
4040

4141
// cache identifiers used to speed up exporting operations
4242
// cleared for each bug
43-
cachedIDs map[string]string
43+
cachedOperationIDs map[string]string
4444

4545
// cache labels used to speed up exporting labels events
4646
cachedLabels map[string]string
@@ -52,7 +52,7 @@ func (ge *githubExporter) Init(conf core.Configuration) error {
5252
//TODO: initialize with multiple tokens
5353
ge.identityToken = make(map[string]string)
5454
ge.identityClient = make(map[string]*githubv4.Client)
55-
ge.cachedIDs = make(map[string]string)
55+
ge.cachedOperationIDs = make(map[string]string)
5656
ge.cachedLabels = make(map[string]string)
5757
return nil
5858
}
@@ -74,7 +74,7 @@ func (ge *githubExporter) allowOrigin(origin string) bool {
7474
return false
7575
}
7676

77-
// getIdentityClient return an identity github api v4 client
77+
// getIdentityClient return a githubv4 API client configured with the access token of the given identity.
7878
// if no client were found it will initialize it from the known tokens map and cache it for next use
7979
func (ge *githubExporter) getIdentityClient(id string) (*githubv4.Client, error) {
8080
client, ok := ge.identityClient[id]
@@ -97,31 +97,29 @@ func (ge *githubExporter) getIdentityClient(id string) (*githubv4.Client, error)
9797
}
9898

9999
// ExportAll export all event made by the current user to Github
100-
func (ge *githubExporter) ExportAll(repo *cache.RepoCache, since time.Time) <-chan core.ExportResult {
100+
func (ge *githubExporter) ExportAll(repo *cache.RepoCache, since time.Time) (<-chan core.ExportResult, error) {
101101
out := make(chan core.ExportResult)
102102

103-
go func(out chan<- core.ExportResult) {
104-
defer close(out)
103+
user, err := repo.GetUserIdentity()
104+
if err != nil {
105+
return nil, err
106+
}
105107

106-
user, err := repo.GetUserIdentity()
107-
if err != nil {
108-
out <- core.NewExportError(err, "")
109-
return
110-
}
108+
ge.identityToken[user.Id()] = ge.conf[keyToken]
111109

112-
ge.identityToken[user.Id()] = ge.conf[keyToken]
110+
// get repository node id
111+
ge.repositoryID, err = getRepositoryNodeID(
112+
ge.conf[keyOwner],
113+
ge.conf[keyProject],
114+
ge.conf[keyToken],
115+
)
113116

114-
// get repository node id
115-
ge.repositoryID, err = getRepositoryNodeID(
116-
ge.conf[keyOwner],
117-
ge.conf[keyProject],
118-
ge.conf[keyToken],
119-
)
117+
if err != nil {
118+
return nil, err
119+
}
120120

121-
if err != nil {
122-
out <- core.NewExportError(err, ge.repositoryID)
123-
return
124-
}
121+
go func() {
122+
defer close(out)
125123

126124
var allIdentitiesIds []string
127125
for id := range ge.identityToken {
@@ -140,6 +138,7 @@ func (ge *githubExporter) ExportAll(repo *cache.RepoCache, since time.Time) <-ch
140138
snapshot := b.Snapshot()
141139

142140
// ignore issues created before since date
141+
// TODO: compare the Lamport time instead of using the unix time
143142
if snapshot.CreatedAt.Before(since) {
144143
out <- core.NewExportNothing(b.Id(), "bug created before the since date")
145144
continue
@@ -152,9 +151,9 @@ func (ge *githubExporter) ExportAll(repo *cache.RepoCache, since time.Time) <-ch
152151
out <- core.NewExportNothing(id, "not an actor")
153152
}
154153
}
155-
}(out)
154+
}()
156155

157-
return out
156+
return out, nil
158157
}
159158

160159
// exportBug publish bugs and related events
@@ -176,7 +175,7 @@ func (ge *githubExporter) exportBug(b *cache.BugCache, since time.Time, out chan
176175
// skip bug if origin is not allowed
177176
origin, ok := createOp.GetMetadata(keyOrigin)
178177
if ok && !ge.allowOrigin(origin) {
179-
out <- core.NewExportNothing(b.Id(), fmt.Sprintf("issue taged with origin: %s", origin))
178+
out <- core.NewExportNothing(b.Id(), fmt.Sprintf("issue tagged with origin: %s", origin))
180179
return
181180
}
182181

@@ -186,7 +185,8 @@ func (ge *githubExporter) exportBug(b *cache.BugCache, since time.Time, out chan
186185
githubURL, ok := createOp.GetMetadata(keyGithubUrl)
187186
if !ok {
188187
// if we find github ID, github URL must be found too
189-
panic("expected to find github issue URL")
188+
err := fmt.Errorf("expected to find github issue URL")
189+
out <- core.NewExportError(err, b.Id())
190190
}
191191

192192
out <- core.NewExportNothing(b.Id(), "bug already exported")
@@ -199,9 +199,6 @@ func (ge *githubExporter) exportBug(b *cache.BugCache, since time.Time, out chan
199199
client, err := ge.getIdentityClient(author.Id())
200200
if err != nil {
201201
// if bug is still not exported and we do not have the author stop the execution
202-
203-
// fmt.Println("warning: skipping issue due to missing token for bug creator")
204-
// this is not an error, don't export bug
205202
out <- core.NewExportNothing(b.Id(), fmt.Sprintf("missing author token"))
206203
return
207204
}
@@ -252,7 +249,7 @@ func (ge *githubExporter) exportBug(b *cache.BugCache, since time.Time, out chan
252249
bugCreationHash = hash.String()
253250

254251
// cache operation github id
255-
ge.cachedIDs[bugCreationHash] = bugGithubID
252+
ge.cachedOperationIDs[bugCreationHash] = bugGithubID
256253

257254
for _, op := range snapshot.Operations[1:] {
258255
// ignore SetMetadata operations
@@ -268,10 +265,10 @@ func (ge *githubExporter) exportBug(b *cache.BugCache, since time.Time, out chan
268265
return
269266
}
270267

271-
// ignore imported (or exported) operations from github
268+
// ignore operations already existing in github (due to import or export)
272269
// cache the ID of already exported or imported issues and events from Github
273270
if id, ok := op.GetMetadata(keyGithubId); ok {
274-
ge.cachedIDs[hash.String()] = id
271+
ge.cachedOperationIDs[hash.String()] = id
275272
out <- core.NewExportNothing(hash.String(), "already exported operation")
276273
continue
277274
}
@@ -299,7 +296,7 @@ func (ge *githubExporter) exportBug(b *cache.BugCache, since time.Time, out chan
299296
out <- core.NewExportComment(hash.String())
300297

301298
// cache comment id
302-
ge.cachedIDs[hash.String()] = id
299+
ge.cachedOperationIDs[hash.String()] = id
303300

304301
case *bug.EditCommentOperation:
305302

@@ -324,7 +321,7 @@ func (ge *githubExporter) exportBug(b *cache.BugCache, since time.Time, out chan
324321
} else {
325322

326323
// case comment edition operation: we need to edit the Github comment
327-
commentID, ok := ge.cachedIDs[targetHash]
324+
commentID, ok := ge.cachedOperationIDs[targetHash]
328325
if !ok {
329326
panic("unexpected error: comment id not found")
330327
}
@@ -424,7 +421,7 @@ func getRepositoryNodeID(owner, project, token string) (string, error) {
424421
}
425422

426423
if resp.StatusCode != http.StatusOK {
427-
return "", fmt.Errorf("error retrieving repository node id %v", resp.StatusCode)
424+
return "", fmt.Errorf("HTTP error %v retrieving repository node id", resp.StatusCode)
428425
}
429426

430427
aux := struct {
@@ -668,9 +665,15 @@ func updateGithubIssueStatus(gc *githubv4.Client, id string, status bug.Status)
668665
m := &updateIssueMutation{}
669666

670667
// set state
671-
state := githubv4.IssueStateClosed
672-
if status == bug.OpenStatus {
668+
var state githubv4.IssueState
669+
670+
switch status {
671+
case bug.OpenStatus:
672+
state = githubv4.IssueStateOpen
673+
case bug.ClosedStatus:
673674
state = githubv4.IssueStateOpen
675+
default:
676+
panic("unknown bug state")
674677
}
675678

676679
input := githubv4.UpdateIssueInput{

bridge/github/export_test.go

+27-62
Original file line numberDiff line numberDiff line change
@@ -29,102 +29,66 @@ type testCase struct {
2929
numOrOp int // number of original operations
3030
}
3131

32-
func testCases(repo *cache.RepoCache, identity *cache.IdentityCache) ([]*testCase, error) {
32+
func testCases(t *testing.T, repo *cache.RepoCache, identity *cache.IdentityCache) []*testCase {
3333
// simple bug
3434
simpleBug, _, err := repo.NewBug("simple bug", "new bug")
35-
if err != nil {
36-
return nil, err
37-
}
35+
require.NoError(t, err)
3836

3937
// bug with comments
4038
bugWithComments, _, err := repo.NewBug("bug with comments", "new bug")
41-
if err != nil {
42-
return nil, err
43-
}
39+
require.NoError(t, err)
4440

4541
_, err = bugWithComments.AddComment("new comment")
46-
if err != nil {
47-
return nil, err
48-
}
42+
require.NoError(t, err)
4943

5044
// bug with label changes
5145
bugLabelChange, _, err := repo.NewBug("bug label change", "new bug")
52-
if err != nil {
53-
return nil, err
54-
}
46+
require.NoError(t, err)
5547

5648
_, _, err = bugLabelChange.ChangeLabels([]string{"bug"}, nil)
57-
if err != nil {
58-
return nil, err
59-
}
49+
require.NoError(t, err)
6050

6151
_, _, err = bugLabelChange.ChangeLabels([]string{"core"}, nil)
62-
if err != nil {
63-
return nil, err
64-
}
52+
require.NoError(t, err)
6553

6654
_, _, err = bugLabelChange.ChangeLabels(nil, []string{"bug"})
67-
if err != nil {
68-
return nil, err
69-
}
55+
require.NoError(t, err)
7056

7157
// bug with comments editions
7258
bugWithCommentEditions, createOp, err := repo.NewBug("bug with comments editions", "new bug")
73-
if err != nil {
74-
return nil, err
75-
}
59+
require.NoError(t, err)
7660

7761
createOpHash, err := createOp.Hash()
78-
if err != nil {
79-
return nil, err
80-
}
62+
require.NoError(t, err)
8163

8264
_, err = bugWithCommentEditions.EditComment(createOpHash, "first comment edited")
83-
if err != nil {
84-
return nil, err
85-
}
65+
require.NoError(t, err)
8666

8767
commentOp, err := bugWithCommentEditions.AddComment("first comment")
88-
if err != nil {
89-
return nil, err
90-
}
68+
require.NoError(t, err)
9169

9270
commentOpHash, err := commentOp.Hash()
93-
if err != nil {
94-
return nil, err
95-
}
71+
require.NoError(t, err)
9672

9773
_, err = bugWithCommentEditions.EditComment(commentOpHash, "first comment edited")
98-
if err != nil {
99-
return nil, err
100-
}
74+
require.NoError(t, err)
10175

10276
// bug status changed
10377
bugStatusChanged, _, err := repo.NewBug("bug status changed", "new bug")
104-
if err != nil {
105-
return nil, err
106-
}
78+
require.NoError(t, err)
10779

10880
_, err = bugStatusChanged.Close()
109-
if err != nil {
110-
return nil, err
111-
}
81+
require.NoError(t, err)
11282

11383
_, err = bugStatusChanged.Open()
114-
if err != nil {
115-
return nil, err
116-
}
84+
require.NoError(t, err)
11785

11886
// bug title changed
11987
bugTitleEdited, _, err := repo.NewBug("bug title edited", "new bug")
120-
if err != nil {
121-
return nil, err
122-
}
88+
require.NoError(t, err)
12389

12490
_, err = bugTitleEdited.SetTitle("bug title edited again")
125-
if err != nil {
126-
return nil, err
127-
}
91+
require.NoError(t, err)
12892

12993
return []*testCase{
13094
&testCase{
@@ -157,8 +121,7 @@ func testCases(repo *cache.RepoCache, identity *cache.IdentityCache) ([]*testCas
157121
bug: bugTitleEdited,
158122
numOrOp: 2,
159123
},
160-
}, nil
161-
124+
}
162125
}
163126

164127
func TestPushPull(t *testing.T) {
@@ -188,8 +151,7 @@ func TestPushPull(t *testing.T) {
188151
defer backend.Close()
189152
interrupt.RegisterCleaner(backend.Close)
190153

191-
tests, err := testCases(backend, author)
192-
require.NoError(t, err)
154+
tests := testCases(t, backend, author)
193155

194156
// generate project name
195157
projectName := generateRepoName()
@@ -224,7 +186,10 @@ func TestPushPull(t *testing.T) {
224186
start := time.Now()
225187

226188
// export all bugs
227-
for result := range exporter.ExportAll(backend, time.Time{}) {
189+
events, err := exporter.ExportAll(backend, time.Time{})
190+
require.NoError(t, err)
191+
192+
for result := range events {
228193
require.NoError(t, result.Err)
229194
}
230195
require.NoError(t, err)
@@ -258,7 +223,7 @@ func TestPushPull(t *testing.T) {
258223
// so number of operations should double
259224
require.Len(t, tt.bug.Snapshot().Operations, tt.numOrOp*2)
260225

261-
// verify operation have correcte metadata
226+
// verify operation have correct metadata
262227
for _, op := range tt.bug.Snapshot().Operations {
263228
// Check if the originals operations (*not* SetMetadata) are tagged properly
264229
if _, ok := op.(*bug.SetMetadataOperation); !ok {
@@ -274,7 +239,7 @@ func TestPushPull(t *testing.T) {
274239
bugGithubID, ok := tt.bug.Snapshot().GetCreateMetadata(keyGithubId)
275240
require.True(t, ok)
276241

277-
// retrive bug from backendTwo
242+
// retrieve bug from backendTwo
278243
importedBug, err := backendTwo.ResolveBugCreateMetadata(keyGithubId, bugGithubID)
279244
require.NoError(t, err)
280245

0 commit comments

Comments
 (0)