• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

moosetechnology / GitProjectHealth / 10870371582

15 Sep 2024 10:48AM UTC coverage: 35.962% (+2.3%) from 33.667%
10870371582

Pull #55

github

web-flow
Merge a5fe468b1 into 48c9c9c78
Pull Request #55: Agg generic importer and improve github importer

337 of 497 new or added lines in 8 files covered. (67.81%)

5 existing lines in 4 files now uncovered.

3060 of 8509 relevant lines covered (35.96%)

0.36 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

71.8
/src/GitLabProjectHealth-Model-Importer/GLPHModelImporter.class.st
1
Class {
2
        #name : 'GLPHModelImporter',
3
        #superclass : 'GLHModelImporter',
4
        #category : 'GitLabProjectHealth-Model-Importer',
5
        #package : 'GitLabProjectHealth-Model-Importer'
6
}
7

8
{ #category : 'as yet unclassified' }
9
GLPHModelImporter >> blockForDiffRangeEquality [
1✔
10

1✔
11
        ^ [ :existing :new |
1✔
12
          existing diff mooseID = new diff mooseID and: [
1✔
13
                  existing originalLineRange = new originalLineRange and: [
1✔
14
                          existing newLineRange = new newLineRange ] ] ]
1✔
15
]
1✔
16

17
{ #category : 'commit' }
UNCOV
18
GLPHModelImporter >> commitsOfProject: aGLHProject forRefName: refName until: toDate [
×
19

×
20
        | newlyFoundCommit page |
×
21
        page := 0.
×
22
        newlyFoundCommit := { true }.
×
23
        [ newlyFoundCommit isNotEmpty ] whileTrue: [
×
24
                | results parsedResults existingCommits |
×
25
                page := page + 1.
×
26
                ('import commit page ' , page printString) recordInfo.
×
27
                results := self glhApi
×
28
                                   commitsOfProject: aGLHProject id
×
29
                                   forRefName: refName
×
30
                                   since: nil
×
31
                                   until: nil
×
32
                                   path: nil
×
33
                                   author: nil
×
34
                                   all: nil
×
35
                                   with_stats: nil
×
36
                                   firstParent: nil
×
37
                                   order: nil
×
38
                                   trailers: nil
×
39
                                   perPage: 100
×
40
                                   page: page.
×
41
                parsedResults := self parseCommitsResult: results.
×
42
                existingCommits := aGLHProject mooseModel allWithType: GLHCommit.
×
43

×
44
                newlyFoundCommit := parsedResults reject: [ :commitParsed |
×
45
                                            (toDate isNil or: [
×
46
                                                     commitParsed committed_date
×
47
                                                     < toDate asDateAndTime ]) or: [
×
48
                                                    existingCommits anySatisfy: [ :existingCommit |
×
49
                                                            existingCommit id = commitParsed id ] ] ].
×
50
                self glhModel addAll: newlyFoundCommit unless: self blockOnIdEquality.
×
51
                aGLHProject repository commits addAll: newlyFoundCommit unless: self blockOnIdEquality  ].
×
52
        self withCommitDiffs ifTrue: [
×
53
                aGLHProject repository commits do: [ :commit |
×
54
                        self importDiffOfCommit: commit ] ]
×
55
]
×
56

57
{ #category : 'private - api' }
58
GLPHModelImporter >> completeImportProject: aGLHProject [
1✔
59
        |completedProject|
1✔
60
        completedProject := super completeImportProject: aGLHProject.
1✔
61

1✔
62
        "for this initial import, with only look at some but not all MR"
1✔
63
        withInitialMergeRequest ifTrue: [ self
1✔
64
                importMergeRequests: completedProject
1✔
65
                since: DateAndTime today
1✔
66
                until: DateAndTime now. ].
1✔
67

1✔
68
        ^ completedProject
1✔
69
]
1✔
70

71
{ #category : 'private - configure reader' }
72
GLPHModelImporter >> configureReaderForMergeRequest: reader [
1✔
73
        "declare quil y a un array a mapper"
1✔
74

1✔
75
        reader for: #ArrayOfMergeRequest customDo: [ :customMappting |
1✔
76
                customMappting listOfElementSchema: GLPHEMergeRequest ].
1✔
77

1✔
78
        "declare la liste des properties"
1✔
79
        reader for: GLPHEMergeRequest do: [ :mapping |
1✔
80
                mapping mapInstVars:
1✔
81
                        #( blocking_discussions_resolved changes_count description
1✔
82
                           detailed_merge_status discussion_locked downvotes draft first_deployed_to_production_at
1✔
83
                           force_remove_source_branch has_conflicts id iid labels latest_build_finished_at
1✔
84
                           latest_build_started_at merge_commit_sha merge_status
1✔
85
                           merge_when_pipeline_succeeds merged_at milestone project_id
1✔
86
                           reference references_full references_relative
1✔
87
                           references_short sha should_remove_source_branch
1✔
88
                           source_branch source_project_id squash squash_commit_sha
1✔
89
                           squash_on_merge state subscribed target_branch target_project_id
1✔
90
                           task_completion_status_completed_count
1✔
91
                           task_completion_status_count time_stats_human_time_estimate
1✔
92
                           time_stats_human_total_time_spent
1✔
93
                           time_stats_time_estimate time_stats_total_time_spent
1✔
94
                           title updated_at upvotes user_notes_count web_url work_in_progress ).
1✔
95
                (mapping mapInstVar: #created_at) valueSchema: DateAndTime.
1✔
96
                (mapping mapInstVar: #updated_at) valueSchema: DateAndTime.
1✔
97
                (mapping mapInstVar: #merged_at) valueSchema: DateAndTime.
1✔
98
                (mapping mapInstVar: #closed_at) valueSchema: DateAndTime.
1✔
99
                "(mapping mapInstVar: #assignee) valueSchema: GLHUser."
1✔
100
                mapping
1✔
101
                        mapProperty: #author
1✔
102
                        getter: [  ]
1✔
103
                        setter: [ :object :value |
1✔
104
                        object cacheAt: #authorID put: (value at: #id) ].
1✔
105
                mapping
1✔
106
                        mapProperty: #merge_user
1✔
107
                        getter: [  ]
1✔
108
                        setter: [ :object :value | 
1✔
109
                                value ifNotNil: [
1✔
110
                                        object cacheAt: #mergeUserID put: (value at: #id) ] ] ].
1✔
111

1✔
112
        "(mapping mapInstVar: #closed_by) valueSchema: GLHUser.
1✔
113
        (mapping mapInstVar: #mergeCommit) valueSchema: GLHCommit."
1✔
114
        "indique ce que doit faire le reader lorsqu'il parse une DateAndTime object"
1✔
115
        reader for: DateAndTime customDo: [ :mapping |
1✔
116
                mapping decoder: [ :string |
1✔
117
                        string ifNil: [ nil ] ifNotNil: [ DateAndTime fromString: string ] ] ]
1✔
118
]
1✔
119

120
{ #category : 'import' }
121
GLPHModelImporter >> importCommitsOfBranch: aGLHBranch [
×
122

×
123
        | commits |
×
124
        "        result := self glhApi
×
125
                          commitsOfProject: aGLHBranch repository project id
×
126
                          forRefName: aGLHBranch name."
×
127
        commits := self
×
128
                           importCommitsOfBranch: aGLHBranch
×
129
                           forRefName: aGLHBranch name
×
130
                           since: withCommitsSince.
×
131

×
132
        self chainsCommitsFrom: commits.
×
133

×
134
        commits do: [ :aCommit |
×
135
                aCommit repository: aGLHBranch repository.
×
136
                self completeImportedCommit: aCommit. 
×
137
                 ]
×
138
]
×
139

140
{ #category : 'import' }
141
GLPHModelImporter >> importCommitsOfMergeResquest: aGLPHEMergeRequest [
1✔
142

1✔
143
        | foundCommits |
1✔
144
        foundCommits := OrderedCollection new.
1✔
145

1✔
146
        ('Import commit sha of MR:  ' , aGLPHEMergeRequest iid printString)
1✔
147
                recordInfo.
1✔
148
        "the founds commits are added to the model during their respective import"
1✔
149
        aGLPHEMergeRequest mergeRequestCommit: ((self
1✔
150
                          importCommitOfProject: aGLPHEMergeRequest project
1✔
151
                          withId: aGLPHEMergeRequest sha) ifNotNil: [ :commit |
1✔
152
                         foundCommits add: commit ]).
1✔
153

1✔
154
        ('Import commit merge_commit_sha of MR:  '
1✔
155
         , aGLPHEMergeRequest iid printString) recordInfo.
1✔
156
        aGLPHEMergeRequest mergedCommit: ((self
1✔
157
                          importCommitOfProject: aGLPHEMergeRequest project
1✔
158
                          withId: aGLPHEMergeRequest merge_commit_sha) ifNotNil: [ :commit |
1✔
159
                         foundCommits add: commit ]).
1✔
160

1✔
161
        ('Import commit squash_commit_sha of MR:  '
1✔
162
         , aGLPHEMergeRequest iid printString) recordInfo.
1✔
163
        aGLPHEMergeRequest squashCommit: ((self
1✔
164
                          importCommitOfProject: aGLPHEMergeRequest project
1✔
165
                          withId: aGLPHEMergeRequest squash_commit_sha) ifNotNil: [ :commit |
1✔
166
                         foundCommits add: commit ]).
1✔
167

1✔
168

1✔
169
        self chainsCommitsFrom: foundCommits.
1✔
170
        ^ foundCommits
1✔
171
]
1✔
172

173
{ #category : 'api' }
174
GLPHModelImporter >> importDiffOfCommit: aCommit [
1✔
175

1✔
176
        super importDiffOfCommit: aCommit.
1✔
177
        
1✔
178
        "changes are added into the model during the import"
1✔
179
        aCommit diffs do: [ :diff | self importDiffRangesForDiff: diff ].
1✔
180

1✔
181
        ^ aCommit diffs
1✔
182
]
1✔
183

184
{ #category : 'as yet unclassified' }
185
GLPHModelImporter >> importDiffOfMergeRequest: aMergeRequest [
1✔
186

1✔
187
        | result diffsResult |
1✔
188
        aMergeRequest diffs ifNotEmpty: [
1✔
189
                'Diff of already importer: '
1✔
190
                , aMergeRequest iid printString recordInfo.
1✔
191
                ^ aMergeRequest diffs ].
1✔
192
        ('Import diff commits of MR ' , aMergeRequest iid printString)
1✔
193
                recordInfo.
1✔
194
        result := self glhApi
1✔
195
                          diffsMergeRequestOfProject: aMergeRequest project_id
1✔
196
                          withId: aMergeRequest iid.
1✔
197

1✔
198
        diffsResult := self parseDiffResult: result.
1✔
199

1✔
200

1✔
201
        aMergeRequest diffs
1✔
202
                addAll: diffsResult
1✔
203
                unless: self blockForDiffEquality.
1✔
204
        self glhModel
1✔
205
                addAll: aMergeRequest diffs
1✔
206
                unless: self blockForDiffEquality.
1✔
207

1✔
208
        aMergeRequest diffs do: [ :diff | self importDiffRangesForDiff: diff ].
1✔
209

1✔
210
        ^ aMergeRequest diffs
1✔
211
]
1✔
212

213
{ #category : 'import' }
214
GLPHModelImporter >> importDiffRangesForDiff: aGLHDiff [
1✔
215

1✔
216
        | diffRanges |
1✔
217
        aGLHDiff diffRanges ifNotEmpty: [
1✔
218
                ('Diffs already imported for ' , aGLHDiff printString) recordInfo.
1✔
219
                ^ aGLHDiff diffRanges ].
1✔
220

1✔
221
        ('Import changes of diff ' , aGLHDiff printString) recordInfo.
1✔
222
        "the import of 'diffRanges' entites is technically done inside the parseDiffString"
1✔
223

1✔
224
        diffRanges := self glhModel
1✔
225
                              addAll: (self parseDiffString: aGLHDiff)
1✔
226
                              unless: self blockForDiffRangeEquality.
1✔
227
        ^ aGLHDiff diffRanges
1✔
228
                  addAll: diffRanges
1✔
229
                  unless: self blockForDiffRangeEquality
1✔
230
]
1✔
231

232
{ #category : 'import - merge request' }
233
GLPHModelImporter >> importMergeRequests: aGLHProject [
1✔
234

1✔
235
        | results parsedResults |
1✔
236
        ('Import merge request of Project: ' , aGLHProject id printString)
1✔
237
                recordInfo.
1✔
238

1✔
239
        results := self glhApi mergeRequestOfProject: aGLHProject id.
1✔
240
        parsedResults := self parseMergeRequestResult: results.
1✔
241

1✔
242
        aGLHProject mergeRequests
1✔
243
                addAll: parsedResults
1✔
244
                unless: self blockOnIdEquality.
1✔
245

1✔
246
        self glhModel
1✔
247
                addAll: aGLHProject mergeRequests
1✔
248
                unless: self blockOnIdEquality.
1✔
249

1✔
250

1✔
251
        "gets it related commits"
1✔
252
        aGLHProject mergeRequests do: [ :mr |
1✔
253
                self importCommitsOfMergeResquest: mr ].
1✔
254

1✔
255

1✔
256
        self withCommitDiffs ifTrue: [
1✔
257
                aGLHProject mergeRequests do: [ :mr |
1✔
258
                        self importDiffOfMergeRequest: mr ] ]
1✔
259
]
1✔
260

261
{ #category : 'import - merge request' }
262
GLPHModelImporter >> importMergeRequests: aGLHProject since: fromDate until: toDate [
×
263

×
264
        | newlyFoundMR page foundMR |
×
265
        ('import MR of Project ' , aGLHProject name) recordInfo.
×
266

×
267
        page := 0.
×
268
        foundMR := OrderedCollection new.
×
269
        newlyFoundMR := { true }.
×
270
        [ newlyFoundMR isNotEmpty ] whileTrue: [
×
271
                | results |
×
272
                page := page + 1.
×
273
                ('import MR page ' , page printString) recordInfo.
×
274
                results := self glhApi
×
275
                                   mergeRequestsOfProject: aGLHProject id
×
276
                                   createdAfter:
×
277
                                   (fromDate ifNotNil: [ fromDate asDateAndTime asString ])
×
278
                                   createdBefore:
×
279
                                   (toDate ifNotNil: [ toDate asDateAndTime asString ])
×
280
                                   authorId: nil
×
281
                                   authorUsername: nil
×
282
                                   scope: 'all'
×
283
                                   orderBy: 'created_at'
×
284
                                   page: page.
×
285

×
286

×
287
                newlyFoundMR := aGLHProject mergeRequests
×
288
                                        addAll: (self parseMergeRequestResult: results)
×
289
                                        unless: self blockOnIdEquality.
×
290
                foundMR addAll: newlyFoundMR ].
×
291

×
292

×
293
        "gets it related commits"
×
294
        aGLHProject mergeRequests do: [ :mr |
×
295
                self importCommitsOfMergeResquest: mr ].
×
296

×
297
        self withCommitDiffs ifTrue: [
×
298
                aGLHProject mergeRequests do: [ :mr |
×
299
                        self importDiffOfMergeRequest: mr ] ].
×
300
        
×
301
        self glhModel addAll: foundMR unless: (self blockEqualityOn: #iid).
×
302

×
303
        ^ foundMR
×
304
]
×
305

306
{ #category : 'import - merge request' }
307
GLPHModelImporter >> importMergeResquestApprovals: aGLPHEMergeRequest [
×
308

×
309
        | results parsedResult |
×
310
        (String streamContents: [ :str |
×
311
                 str << 'Check approvals of '.
×
312
                 aGLPHEMergeRequest printOn: str ]) recordInfo.
×
313
        results := self glhApi
×
314
                           approvalsOfMergeQuest: aGLPHEMergeRequest iid
×
315
                           ofProject: aGLPHEMergeRequest project id.
×
316

×
317
        parsedResult := generalReader
×
318
                                on: results readStream;
×
319
                                next.
×
320

×
321
        (parsedResult at: #approved_by) do: [ :approvedUser |
×
322
                aGLPHEMergeRequest addApproved_by:
×
323
                        (self importUser: ((approvedUser at: #user) at: #id)) ].
×
324
        aGLPHEMergeRequest approved: (parsedResult at: #approved).
×
325
        ^ aGLPHEMergeRequest
×
326
]
×
327

328
{ #category : 'import - merge request' }
329
GLPHModelImporter >> importMergeResquestAuthor: aGLPHEMergeRequest [
1✔
330

1✔
331
        | authorID |
1✔
332
        aGLPHEMergeRequest author ifNotNil: [ ^ aGLPHEMergeRequest author ].
1✔
333
        authorID := aGLPHEMergeRequest cacheAt: #authorID ifAbsent: [
1✔
334
                            (generalReader
1✔
335
                                     on: (self glhApi
1✔
336
                                                      mergeRequestOfProject:
1✔
337
                                                              aGLPHEMergeRequest project_id
1✔
338
                                                      withId: aGLPHEMergeRequest iid) readStream;
1✔
339
                                     next) at: #author at: #id ].
1✔
340
        aGLPHEMergeRequest author: (self importUser: authorID)
1✔
341
]
1✔
342

343
{ #category : 'import - merge request' }
344
GLPHModelImporter >> importMergeResquestMerger: aGLPHEMergeRequest [
1✔
345

1✔
346
        | authorID |
1✔
347
        aGLPHEMergeRequest merge_user ifNotNil: [
1✔
348
                ^ aGLPHEMergeRequest merge_user ].
1✔
349
        authorID := aGLPHEMergeRequest cacheAt: #mergeUserID ifAbsent: [
1✔
350
                            (generalReader
1✔
351
                                     on: (self glhApi
1✔
352
                                                      mergeRequestOfProject:
1✔
353
                                                              aGLPHEMergeRequest project_id
1✔
354
                                                      withId: aGLPHEMergeRequest iid) readStream;
1✔
355
                                     next)
1✔
356
                                    at: #merge_user
1✔
357
                                    ifPresent: [ :mergeUser |
1✔
358
                                    mergeUser ifNotNil: [ :mruser | mruser at: #id ] ] ].
1✔
359
        aGLPHEMergeRequest merge_user: (self importUser: authorID)
1✔
360
]
1✔
361

362
{ #category : 'as yet unclassified' }
363
GLPHModelImporter >> importProject: aProjectID [
1✔
364

1✔
365
        | result projectResult |
1✔
366
        ('Import project with id:  ' , aProjectID printString) recordInfo.
1✔
367

1✔
368
        result := self glhApi project: aProjectID.
1✔
369
        projectResult := self parseProjectResult: result.
1✔
370

1✔
371
        ^ self completeImportProject: projectResult
1✔
372
]
1✔
373

374
{ #category : 'private - api' }
375
GLPHModelImporter >> importRepository: aGLHRepository [
1✔
376

1✔
377
        super importRepository: aGLHRepository.
1✔
378

1✔
379
        withInitialCommits ifTrue: [
1✔
380
                aGLHRepository branches do: [ :branch |
1✔
381
                        self importCommitsOfBranch: branch ] ]
1✔
382
]
1✔
383

384
{ #category : 'initialization' }
385
GLPHModelImporter >> initReader [
1✔
386

1✔
387
        super initReader.
1✔
388
        self configureReaderForMergeRequest: generalReader
1✔
389
]
1✔
390

391
{ #category : 'initialization' }
392
GLPHModelImporter >> initialize [
1✔
393

1✔
394
        super initialize.
1✔
395
        withCommitDiffs := true
1✔
396
]
1✔
397

398
{ #category : 'parsing' }
399
GLPHModelImporter >> parseDiffString: aDiff [
1✔
400
        "parse diff string to create entities for each lines"
1✔
401

1✔
402
        | lines range index firstChangeRange |
1✔
403
        lines := aDiff diffString lines.
1✔
404
        index := 0.
1✔
405
        range := nil.
1✔
406

1✔
407
        lines ifEmpty: [ ^ aDiff diffRanges ].
1✔
408
        lines := self filterCommitChanges: lines.
1✔
409
        (lines first beginsWith: '@@') ifFalse: [ ^ aDiff diffRanges ].
1✔
410

1✔
411
        lines do: [ :line |
1✔
412
                | aChange |
1✔
413
                firstChangeRange := false.
1✔
414
                (line trim beginsWith: #'@@') ifTrue: [
1✔
415
                        range := GLPHEDiffRange newFrom: line.
1✔
416
                        firstChangeRange := true.
1✔
417
                        range := aDiff diffRanges add: range unless: [ :existing :new |
1✔
418
                                         existing originalLineRange = new originalLineRange and: [
1✔
419
                                                 existing newLineRange = new newLineRange ] ] ].
1✔
420

1✔
421
                self withCommitDiffs ifTrue: [
1✔
422
                        firstChangeRange ifFalse: [
1✔
423
                                aChange := GLPHEChange newFrom: line.
1✔
424
                                aChange relativeIndex: index.
1✔
425
                                aChange := range changes add: aChange unless: [ :existing :new |
1✔
426
                                                   existing sourceCode = new sourceCode and: [
1✔
427
                                                           existing index = new index ] ].
1✔
428
                                index := index + 1 ] ] ].
1✔
429

1✔
430
        "add changes to the diff range"
1✔
431
        aDiff diffRanges do: [ :diffRange |
1✔
432
                self glhModel addAll: diffRange changes unless: [ :existing :new |
1✔
433
                        existing diffRange mooseID = new diffRange mooseID and: [
1✔
434
                                existing sourceCode = new sourceCode and: [
1✔
435
                                        existing index = new index ] ] ] ].
1✔
436

1✔
437
        ^ aDiff diffRanges
1✔
438
]
1✔
439

440
{ #category : 'parsing' }
441
GLPHModelImporter >> parseMergeRequestResult: result [
1✔
442

1✔
443
        generalReader on: result readStream.
1✔
444
        ^ generalReader nextAs: #ArrayOfMergeRequest
1✔
445
]
1✔
446

447
{ #category : 'parsing' }
448
GLPHModelImporter >> parseProjectResult: aResult [ 
1✔
449
                | reader |
1✔
450
        reader := NeoJSONReader on: aResult readStream.
1✔
451
        reader for: GLHProject do: [ :mapping |
1✔
452
                mapping mapInstVars. ].
1✔
453
"        reader mapInstVarsFor: GLHProject."
1✔
454

1✔
455
        ^ reader nextAs: GLHProject
1✔
456
]
1✔
457

1✔
458
{ #category : 'accessing' }
1✔
459
GLPHModelImporter >> withCommitsSince: someDays [
1✔
460
        "substract the current date with a given number of days. Use to retrieve the commits submit in the last giving days"
1✔
461

1✔
462
        "(GLPHModelImporter new withCommitsSince: 1 week ) >>> (Date today - 1 week) asDateAndTime"
1✔
463

1✔
464
        "(GLPHModelImporter new withCommitsSince: 30 day ) >>> (Date today - 30 day) asDateAndTime"
1✔
465

1✔
466
        (someDays isKindOf: DateAndTime)
1✔
467
                ifTrue: [ withCommitsSince := someDays ]
1✔
468
                ifFalse: [
1✔
469
                withCommitsSince := (Date today - someDays) asDateAndTime ]
1✔
470
]
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc