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

moosetechnology / GitProjectHealth / 9682577336

26 Jun 2024 03:32PM UTC coverage: 29.519% (+2.6%) from 26.896%
9682577336

Pull #7

github

web-flow
Merge 0d36202b7 into dfd76b711
Pull Request #7: Optimize code and writting tests

514 of 1154 new or added lines in 11 files covered. (44.54%)

17 existing lines in 3 files now uncovered.

2177 of 7375 relevant lines covered (29.52%)

0.3 hits per line

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

0.0
/src/GitLabHealth-Model-Analysis/GitMetric4User.class.st
1
Class {
2
        #name : #GitMetric4User,
3
        #superclass : #Object,
4
        #instVars : [
5
                'user',
6
                'itsProjects',
7
                'itsGroups',
8
                'itsCommits',
9
                'gitAnalyzer',
10
                'glhModel',
11
                'glhImporter',
12
                'itsMergeRequests'
13
        ],
14
        #category : #'GitLabHealth-Model-Analysis'
15
}
16

17
{ #category : #churn }
18
GitMetric4User >> codeChurnSince: since until: until onACommitWindowOf: commitLimit overA: aDateWeekMonthOrYear [
×
19

×
20
        | commits res groupedByDate totalContributions |
×
21
        
×
22
                ('GitMetric4User: code churn')
×
23
                recordInfo.
×
24
        
×
25
        totalContributions := OrderedCollection new.
×
26
                groupedByDate := self
×
27
                                 setupGroupedDateFrom: since
×
28
                                 to: until
×
29
                                 over: aDateWeekMonthOrYear.
×
30
        gitAnalyzer := GitAnalyzer new
×
31
                               glhImporter: glhImporter;
×
32
                               onModel: glhModel;
×
33
                               maxChildCommit: commitLimit.
×
34

×
35
        commits := self
×
36
                           loadCommitOfProjects: itsProjects keys
×
37
                           since: since
×
38
                           until: until.
×
39
        commits := commits reject: [ :commit | commit commitCreator ~= user ].
×
40

×
41

×
42
        "for each commit, we get its churn result (a dictionnary)"
×
43
        res := commits collect: [ :commit |
×
44
                       commit -> (gitAnalyzer
×
45
                                fromCommit: commit;
×
46
                                analyseChurn) ].
×
47

×
48

×
NEW
49
        res do: [ :commits4Churns |
×
NEW
50
                | commit allChurnsInCommit sumChurnInCommit overDate contribution churnOnCommit|
×
NEW
51
                commit := commits4Churns key.
×
NEW
52
                allChurnsInCommit := commits4Churns value.
×
NEW
53
                sumChurnInCommit := (allChurnsInCommit at: #churns) sum: [ :churn |
×
54
                                    | numerator |
×
NEW
55
                                    numerator := churn value at: #churnLoC .
×
NEW
56
                                                        "debug halt"
×
NEW
57
                                                        self haltIf: [ numerator = -1 ].
×
NEW
58
                                                        numerator.             
×
NEW
59
                         ].
×
NEW
60
                contribution := allChurnsInCommit at: #totalContribution.
×
61
                totalContributions add: contribution.
×
NEW
62
                
×
NEW
63
                churnOnCommit := { (#churnOnCommit -> sumChurnInCommit). (#LoCOnCommit -> contribution). } asDictionary.
×
NEW
64
                
×
65
                overDate := self
×
66
                                    transformDate: commit created_at
×
67
                                    to: aDateWeekMonthOrYear.
×
68
                groupedByDate
×
69
                        at: overDate printString
×
NEW
70
                        ifPresent: [ :array | array add: churnOnCommit ]
×
71
                        ifAbsentPut: [
×
72
                                OrderedCollection new
×
NEW
73
                                        add: churnOnCommit;
×
74
                                        yourself ] ].
×
75

×
76

×
NEW
77
        groupedByDate := groupedByDate collect: [ :churnsAtDate |
×
NEW
78
                                 | totalChurn totalContribution percentage|
×
NEW
79
                                 totalChurn := churnsAtDate sum: [ :churn |
×
NEW
80
                                                                                                        
×
NEW
81
                                                       churn at: #churnOnCommit ].
×
NEW
82
                                 totalContribution := churnsAtDate sum: [ :churn |
×
NEW
83
                                                              churn at: #LoCOnCommit ].
×
NEW
84
                                                         (totalContribution = 0) ifTrue: [ percentage := 0 asFloat ] ifFalse: [ percentage := (((totalChurn * 100) / totalContribution) asFloat)  ].
×
NEW
85
                                                        "percentage := (((totalChurn * 100) / totalContribution) asFloat)"
×
NEW
86
                                                        { (#churn -> totalChurn) . (#contribution -> totalContribution) . (#percentage ->  percentage) } asDictionary 
×
NEW
87
                                  ].
×
88

×
89
        ^ {
×
90
                  (#details -> groupedByDate).
×
91
                  (#totalContribution -> (totalContributions ifEmpty: [ 0 ] ifNotEmpty: [ totalContributions sum ]) ).
×
NEW
92
                  (#totalChurn -> (groupedByDate sum: [ :date | date at: #churn ])).
×
NEW
93
                  
×
NEW
94
"                (
×
NEW
95
                #churn -> ((groupedByDate sum: [ :frac | frac numerator ]) ->
×
NEW
96
                     (groupedByDate sum: [ :frac | frac denominator ]))
×
NEW
97
                )."
×
NEW
98
                (
×
NEW
99
                #churn -> ((groupedByDate collect: [:date | date at: #percentage]) average )
×
NEW
100
                ).
×
NEW
101
                
×
102
                  (#overEach -> aDateWeekMonthOrYear name).
×
103
                  (#forOver -> (groupedByDate keys size printString
×
104
                    , aDateWeekMonthOrYear printString)).
×
105
                  (#userCommits -> commits size).
×
106
                  (#churnWindow -> commitLimit) } asDictionary
×
107
]
×
UNCOV
108

×
UNCOV
109
{ #category : #metrics }
×
110
GitMetric4User >> codeContributionsSince: since until: until overA: aDateWeekMonthOrYear [
×
111

×
112
        | commits contributions groupedByDate |
×
113
        
×
114
                        ('GitMetric4User: code contribution') recordInfo.
×
115
        
×
116
                glhImporter withCommitDiffs: false.
×
117
        
×
118
                groupedByDate := self
×
119
                                 setupGroupedDateFrom: since
×
120
                                 to: until
×
121
                                 over: aDateWeekMonthOrYear.
×
122
                
×
123
        gitAnalyzer := GitAnalyzer new
×
124
                               onModel: glhModel;
×
125
                               glhImporter: glhImporter.
×
126

×
127
        commits := self
×
128
                           loadCommitOfProjects: itsProjects keys
×
129
                           since: since
×
130
                           until: until.
×
131
        commits := commits reject: [ :commit | commit commitCreator ~= user ].
×
132

×
133
        contributions := commits collect: [ :commit |
×
134
                                 commit -> (gitAnalyzer
×
135
                                          fromCommit: commit;
×
136
                                          analyseCommitContribution) ].
×
137

×
138
        contributions do: [ :assoc |
×
139
                | dateOver |
×
140
                dateOver := self
×
141
                                    transformDate: assoc key created_at
×
142
                                    to: aDateWeekMonthOrYear.
×
143
                groupedByDate
×
144
                        at: dateOver printString
×
145
                        ifPresent: [ :v | v add: assoc value ]
×
146
                        ifAbsentPut: [
×
147
                                OrderedCollection new
×
148
                                        add: assoc value;
×
149
                                        yourself ] ].
×
150

×
151
        groupedByDate := groupedByDate collect: [ :contribs |
×
152
                                 | totalAdd totalDele |
×
153
                                 totalAdd := contribs sum: [ :v | v at: #addition ].
×
154
                                 totalDele := contribs sum: [ :v | v at: #deletion ].
×
155
                                 {
×
156
                                         (#addition -> totalAdd).
×
157
                                         (#deletion -> totalDele) } asDictionary ].
×
158

×
159
                glhImporter withCommitDiffs: true.
×
160

×
161
        ^ {
×
162
                  (#overEach -> aDateWeekMonthOrYear name).
×
163
                  (#forOver -> (groupedByDate keys size printString
×
164
                    , aDateWeekMonthOrYear printString)).
×
NEW
165
                  (#avgAddition -> (groupedByDate collect: [:d | d at: #addition]) average asFloat ).
×
NEW
166
                  (#avgDeletion -> (groupedByDate collect: [:d | d at: #deletion]) average asFloat ).
×
167
                  (#details -> groupedByDate).
×
168
                  (#userCommits -> commits size) } asDictionary
×
169
]
×
UNCOV
170

×
UNCOV
171
{ #category : #metrics }
×
172
GitMetric4User >> commentsContributionsSince: since until: until overA: aDateWeekMonthOrYear [
×
173

×
174
        | commits contributions groupedByDate |
×
NEW
175
        'GitMetric4User: comment contribution' recordInfo.
×
NEW
176

×
177
        groupedByDate := self
×
178
                                 setupGroupedDateFrom: since
×
179
                                 to: until
×
180
                                 over: aDateWeekMonthOrYear.
×
181

×
182
        gitAnalyzer := GitAnalyzer new
×
183
                               onModel: glhModel;
×
184
                               glhImporter: glhImporter.
×
185

×
186
        commits := self
×
187
                           loadCommitOfProjects: itsProjects keys
×
188
                           since: since
×
189
                           until: until.
×
190
        commits := commits reject: [ :commit | commit commitCreator ~= user ].
×
191

×
192
        contributions := commits collect: [ :commit |
×
193
                                 commit -> (gitAnalyzer
×
194
                                          fromCommit: commit;
×
195
                                          analyseCommentContributions) ].
×
196

×
197

×
198
        contributions do: [ :assoc |
×
199
                | dateOver |
×
200
                dateOver := self
×
201
                                    transformDate: assoc key created_at
×
202
                                    to: aDateWeekMonthOrYear.
×
203
                groupedByDate
×
204
                        at: dateOver printString
×
205
                        ifPresent: [ :v | v add: assoc value ]
×
206
                        ifAbsentPut: [
×
207
                                OrderedCollection new
×
208
                                        add: assoc value;
×
209
                                        yourself ] ].
×
210

×
211
        groupedByDate := groupedByDate collect: [ :contribs |
×
212
                                 contribs
×
213
                                         ifNotEmpty: [ contribs sum ]
×
214
                                         ifEmpty: [ 0 ] ].
×
215

×
216

×
217
        ^ {
×
218
                  (#details -> groupedByDate).
×
219
                  (#totalComments -> groupedByDate values sum).
×
220
                  (#avgComments
×
NEW
221
                   -> (groupedByDate values average asFloat)).
×
222
                  (#overEach -> aDateWeekMonthOrYear name).
×
223
                  (#forOver -> (groupedByDate keys size printString
×
224
                    , aDateWeekMonthOrYear printString)).
×
225
                  (#userCommits -> commits size) } asDictionary
×
226
]
×
UNCOV
227

×
UNCOV
228
{ #category : #metrics }
×
229
GitMetric4User >> commitFrequencySince: since until: until overA: aDateWeekMonthOrYear [
×
230

×
NEW
231
        | periods total groupedByDate userCommits |
×
232
        'GitMetric4User: commit frequency' recordInfo.
×
233

×
NEW
234

×
235
        groupedByDate := self
×
236
                                 setupGroupedDateFrom: since
×
237
                                 to: until
×
238
                                 over: aDateWeekMonthOrYear.
×
239

×
NEW
240
        glhImporter withCommitDiffs: false.
×
241
        userCommits := self
×
242
                               loadCommitOfProjects: itsProjects keys
×
243
                               since: since
×
244
                               until: until.
×
NEW
245
        glhImporter withCommitDiffs: true.
×
246
        userCommits := userCommits reject: [ :c | c commitCreator ~= user ].
×
247

×
248
        userCommits do: [ :c |
×
249
                | dateOver |
×
250
                dateOver := self
×
251
                                    transformDate: c created_at
×
252
                                    to: aDateWeekMonthOrYear.
×
253
                groupedByDate at: dateOver printString ifPresent: [ :v | v add: c ] ].
×
254

×
255
        periods := groupedByDate keys size.
×
256
        total := groupedByDate values sum: [ :commits | commits size ].
×
257

×
258

×
259
        ^ {
×
260
                  (#averageFrac -> (total / periods)).
×
261
                  (#averageFloat -> (total / periods) asFloat).
×
262
                  (#userCommit -> total).
×
263
                  (#forOver -> (groupedByDate keys size printString
×
264
                    , aDateWeekMonthOrYear printString)).
×
265
                  (#periode -> aDateWeekMonthOrYear name).
×
266
                  (#details -> groupedByDate) } asOrderedDictionary
×
267
]
×
268

×
269
{ #category : #'as yet unclassified' }
×
270
GitMetric4User >> commitsProducedOnProject: projectId since: sinceDate until: untilDate [
×
271

×
272
        | frequencies |
×
273
        
×
274
        
×
275
        gitAnalyzer := GitAnalyzer new 
×
276
        glhImporter: glhImporter; 
×
277
        onModel: glhModel.
×
278
         
×
279
        frequencies := gitAnalyzer
×
280
                               onProject: (itsProjects at: projectId);
×
281
                               analyseCommitFrequencySince: sinceDate
×
282
                               until: untilDate. 
×
283
        
×
284
        "complete each commit "
×
285
        frequencies values flattened do: [ :commit |
×
286
                glhImporter completeImportedCommit: commit.
×
287
                 ].
×
288
        
×
289
        "Filter the associations in the 'frequencies' collection, removing any commits not created by the specified 'user'. "
×
290
        frequencies associations do: [ :assoc |
×
291
                |commits| 
×
292
                commits := assoc value.
×
293
                assoc value: (commits reject: [ :commit | commit commitCreator ~= user ]). 
×
294
        ].
×
295
        
×
296
        ^ frequencies 
×
297
]
×
298

×
299
{ #category : #metrics }
×
300
GitMetric4User >> commitsProducedOnProject: aProjectId since: since until: until overA: aWeekOrMonthOrYear [
×
301
        "'aWeekOrMonthOrYear' should be the class of Week, Month or Year"
×
302

×
303
        "self commitFrequencyOnProject: 6462 since: (Date today - 60 day) until: (Date today) overA: Week. "
×
304

×
305
        | frequency aggregatedFrequencies |
×
306
        aggregatedFrequencies := self setupGroupedDateFrom: since to: until  over: aWeekOrMonthOrYear.
×
307
        
×
308
        frequency := self
×
309
                             commitsProducedOnProject: aProjectId
×
310
                             since: since
×
311
                             until: until.
×
312

×
313

×
314
        frequency associations do: [ :assoc |
×
315
                | date commits overDate |
×
316
                date := assoc key.
×
317
                commits := assoc value.
×
318

×
319
                commits ifNotEmpty: [ " convert the date as its week date. For some english reason, the week start in sunday so we should add a + 1 day "
×
320
                        overDate := self transformDate: date to: aWeekOrMonthOrYear.
×
321
                        aggregatedFrequencies
×
322
                                at: overDate printString
×
323
                                ifPresent: [ :collection | collection addAll: commits ]
×
324
                                ifAbsentPut: [ commits ] ] ].
×
325

×
326
        ^ aggregatedFrequencies
×
327
]
×
328

×
NEW
329
{ #category : #churn }
×
NEW
330
GitMetric4User >> delayUntilFirstChurnSince: since until: until onACommitWindowOf: maxCommitWindow overA: aDateWeekMonthOrYear [
×
NEW
331

×
NEW
332
        | commits groupedByDate res avg |
×
NEW
333
        'GitMetric4User: delay until first churn' recordInfo.
×
NEW
334

×
NEW
335
        groupedByDate := self
×
NEW
336
                                 setupGroupedDateFrom: since
×
NEW
337
                                 to: until
×
NEW
338
                                 over: aDateWeekMonthOrYear.
×
NEW
339

×
NEW
340
        commits := self
×
NEW
341
                           loadCommitOfProjects: itsProjects keys
×
NEW
342
                           since: since
×
NEW
343
                           until: until.
×
NEW
344

×
NEW
345
        "class commit by dates, filter none user commits"
×
NEW
346
        commits do: [ :commit |
×
NEW
347
                commit commitCreator = user ifTrue: [
×
NEW
348
                        | overDate |
×
NEW
349
                        overDate := self
×
NEW
350
                                            transformDate: commit created_at
×
NEW
351
                                            to: aDateWeekMonthOrYear.
×
NEW
352

×
NEW
353
                        groupedByDate
×
NEW
354
                                at: overDate printString
×
NEW
355
                                ifPresent: [ :arrayOfCommits | arrayOfCommits add: commit ]
×
NEW
356
                                ifAbsentPut: [
×
NEW
357
                                        OrderedCollection new
×
NEW
358
                                                add: commit;
×
NEW
359
                                                yourself ] ] ].
×
NEW
360

×
NEW
361

×
NEW
362

×
NEW
363
        res := groupedByDate collect: [ :commits4Date |
×
NEW
364
                       | durationFromA2B |
×
NEW
365
                       commits4Date collect: [ :commitA |
×
NEW
366
                               | commitB |
×
NEW
367
                               commitB := GitAnalyzer new
×
NEW
368
                                                  glhImporter: glhImporter;
×
NEW
369
                                                  onModel: glhModel;
×
NEW
370
                                                  fromCommit: commitA;
×
NEW
371
                                                  maxChildCommit: maxCommitWindow;
×
NEW
372
                                                  analyseAmandment.
×
NEW
373

×
NEW
374
                               durationFromA2B := commitB
×
NEW
375
                                                          ifNil: [ 0 ]
×
NEW
376
                                                          ifNotNil: [
×
NEW
377
                                                          commitB created_at - commitA created_at ].
×
NEW
378
                               durationFromA2B ] ].
×
NEW
379

×
NEW
380

×
NEW
381

×
NEW
382
        res := res collect: [ :durationsByDate |
×
NEW
383
                       | filtered |
×
NEW
384
                       filtered := durationsByDate reject: [ :value | value = 0 ].
×
NEW
385
                       filtered isEmpty
×
NEW
386
                               ifTrue: [ nil ]
×
NEW
387
                               ifFalse: [
×
NEW
388
                               (filtered sum: [ :v | v asDuration ]) / filtered size ] ].
×
NEW
389

×
NEW
390
        res := res reject: #isNil.
×
NEW
391

×
NEW
392
        res
×
NEW
393
                ifEmpty: [ avg := nil ]
×
NEW
394
                ifNotEmpty: [ avg := res values sum / res keys size ].
×
NEW
395

×
NEW
396

×
NEW
397
        ^ {
×
NEW
398
                  (#avgDelay -> avg).
×
NEW
399
                  (#overEach -> aDateWeekMonthOrYear name).
×
NEW
400
                  (#forOver -> (groupedByDate keys size printString
×
NEW
401
                    , aDateWeekMonthOrYear printString)).
×
NEW
402
                  (#details -> groupedByDate) } asDictionary
×
NEW
403
]
×
NEW
404

×
405
{ #category : #churn }
×
406
GitMetric4User >> delayUntilFirstChurnSince: since until: until overA: aDateWeekMonthOrYear [
×
407

×
408
        | commits groupedByDate res avg |
×
409
        
×
410
                ('GitMetric4User: delay until first churn') recordInfo.        
×
411
        
×
412
        groupedByDate := self
×
413
                                 setupGroupedDateFrom: since
×
414
                                 to: until
×
415
                                 over: aDateWeekMonthOrYear.
×
416

×
417
        commits := self
×
418
                           loadCommitOfProjects: itsProjects keys
×
419
                           since: since
×
420
                           until: until.
×
421

×
422
        "class commit by dates, filter none user commits"
×
423
        commits do: [ :commit |
×
424
                commit commitCreator = user ifTrue: [
×
425
                        | overDate |
×
426
                        overDate := self
×
427
                                            transformDate: commit created_at
×
428
                                            to: aDateWeekMonthOrYear.
×
429

×
430
                        groupedByDate
×
431
                                at: overDate printString
×
432
                                ifPresent: [ :arrayOfCommits | arrayOfCommits add: commit ]
×
433
                                ifAbsentPut: [
×
434
                                        OrderedCollection new
×
435
                                                add: commit;
×
436
                                                yourself ] ] ].
×
437

×
438

×
439

×
440
        res := groupedByDate collect: [ :commits4Date |
×
441
                       | durationFromA2B |
×
442
                       commits4Date collect: [ :commitA |
×
443
                               | commitB |
×
444
                               commitB := GitAnalyzer new
×
445
                                                  glhImporter: glhImporter;
×
446
                                                  onModel: glhModel;
×
447
                                                  fromCommit: commitA;
×
448
                                                                                maxChildCommit: 5;
×
449
                                                  analyseAmandment.
×
450

×
451
                               durationFromA2B := commitB
×
452
                                                          ifNil: [ 0 ]
×
453
                                                          ifNotNil: [
×
454
                                                          commitB created_at - commitA created_at ].
×
455
                               durationFromA2B ] ].
×
456

×
457

×
458

×
459
        res := res collect: [ :durationsByDate |
×
460
                       | filtered |
×
461
                       filtered := durationsByDate reject: [ :value | value = 0 ].
×
462
                       filtered isEmpty
×
463
                               ifTrue: [ nil ]
×
464
                               ifFalse: [
×
465
                               (filtered sum: [ :v | v asDuration ]) / filtered size ] ].
×
466

×
467
        res := res reject: #isNil.
×
468
        
×
469
        res ifEmpty: [ avg:= nil ] ifNotEmpty: [ avg := res values sum / res keys size. ].
×
470

×
471

×
472
        ^ {
×
473
                  (#avgDelay -> avg).
×
474
                  (#overEach -> aDateWeekMonthOrYear name).
×
475
                  (#forOver -> (groupedByDate keys size printString
×
476
                    , aDateWeekMonthOrYear printString)).
×
477
                  (#details -> groupedByDate) } asDictionary
×
478
]
×
479

×
480
{ #category : #'as yet unclassified' }
×
481
GitMetric4User >> findUserNamed: aUsername [
×
482

×
483
        user := glhImporter importUserByUsername: aUsername.
×
484
        ^ user
×
485
]
×
486

×
487
{ #category : #accessing }
×
488
GitMetric4User >> glhImporter: aGLPHModelImporter [ 
×
489
        glhImporter := aGLPHModelImporter
×
490
]
×
491

×
492
{ #category : #initialization }
×
493
GitMetric4User >> initialize [
×
494

×
495
        user := GLHUser new.
×
496
        itsProjects := Dictionary new.
×
497
        itsCommits := Dictionary new.
×
498
        itsGroups := Dictionary new.
×
499
        itsMergeRequests := Dictionary new
×
500
]
×
501

×
NEW
502
{ #category : #accessing }
×
NEW
503
GitMetric4User >> itsProjects: projects [
×
NEW
504
        itsProjects := projects .
×
NEW
505
]
×
NEW
506

×
507
{ #category : #churn }
×
508
GitMetric4User >> loadCommitOfProjects: aCollection since: aTimespan [
×
509
        |commits|
×
510
        
×
511
        commits := (aCollection collect: [ :id |
×
512
                 glhImporter
×
513
                        importCommitsOProject: (itsProjects at: id)
×
514
                        since: aTimespan
×
515
                        until: nil ]) flattened.
×
516

×
517
        commits do: [ :commit |
×
518
                glhImporter completeImportedCommit: commit. 
×
519
                 ].
×
520

×
521
        ^ self userCommits.
×
522
]
×
523

×
524
{ #category : #churn }
×
525
GitMetric4User >> loadCommitOfProjects: aCollection since: since until: until [
×
526

×
NEW
527
        | allCommits period |
×
NEW
528
        period := ('commits since ' , since printString , ' to '
×
NEW
529
                   , until printString) asSymbol.
×
NEW
530

×
NEW
531
        "download commits unless project cache is not empty"
×
NEW
532
        allCommits := aCollection collect: [ :idProject |
×
NEW
533
                              | project |
×
NEW
534
                              project := itsProjects at: idProject.
×
NEW
535
                              project repository cacheAt: period ifAbsentPut: [
×
NEW
536
                                      | foundCommits |
×
NEW
537
                                      foundCommits := glhImporter
×
NEW
538
                                                              importCommitsOProject: project
×
NEW
539
                                                              since: since
×
NEW
540
                                                              until: until.
×
NEW
541
                                      foundCommits ] ].
×
542

×
543
        allCommits := allCommits flatten.
×
NEW
544
        
×
NEW
545
        allCommits := glhImporter glhModel
×
NEW
546
                              addAll: allCommits
×
NEW
547
                              unless: glhImporter blockOnIdEquality.
×
NEW
548
        
×
549
        allCommits do: [ :commit |
×
550
                glhImporter completeImportedCommit: commit ].
×
551

×
552
        glhImporter chainsCommitsFrom: allCommits.
×
553

×
554
        ^ allCommits
×
555
]
×
556

×
557
{ #category : #churn }
×
558
GitMetric4User >> loadMergeRequestsOfProjects: aCollection since: since until: until [
×
559

×
NEW
560
        | allMr period|
×
NEW
561
        "itsMergeRequests ifNil: [ itsMergeRequests := Dictionary new ]."
×
NEW
562
        
×
NEW
563
        period := ('mr since ' , since printString , ' to '
×
NEW
564
                   , until printString) asSymbol.
×
NEW
565

×
NEW
566
        allMr := aCollection collect: [ :idProject |
×
NEW
567
                              | project mr|
×
NEW
568
                              project := itsProjects at: idProject.
×
NEW
569
                              project cacheAt: period ifAbsentPut: [ 
×
NEW
570
                                                        mr :=        glhImporter
×
NEW
571
                                                        importMergeRequests: project
×
572
                                                        since: since
×
NEW
573
                                                        until: until.
×
NEW
574
                                                        mr.         
×
NEW
575
                         ].        
×
NEW
576
                ].
×
NEW
577
        
×
NEW
578
        ^  allMr flattened.
×
579

×
580
]
×
581

×
582
{ #category : #loading }
×
583
GitMetric4User >> loadProjects: projectIds [
×
584

×
585
        projectIds do: [ :id |
×
586
                
×
587
                itsProjects at: id ifAbsentPut: [ glhImporter importProject: id ] ].
×
588

×
589
        ^ itsProjects
×
590
]
×
591

×
592
{ #category : #metrics }
×
593
GitMetric4User >> mergeRequestDurationSince: since until: until overA: aDateWeekMonthOrYear [
×
594

×
595
        | mergeRequest res groupedByDate filterGroups avg |
×
596
        groupedByDate := self
×
597
                                 setupGroupedDateFrom: since
×
598
                                 to: until
×
599
                                 over: aDateWeekMonthOrYear.
×
600

×
601
        gitAnalyzer := GitAnalyzer new
×
602
                               glhImporter: glhImporter;
×
603
                               onModel: glhModel.
×
604

×
NEW
605
        glhImporter withCommitDiffs: false.
×
606
        mergeRequest := self
×
607
                                loadMergeRequestsOfProjects: itsProjects keys
×
608
                                since: since
×
609
                                until: until.
×
NEW
610
        glhImporter withCommitDiffs: true.
×
611

×
612
        mergeRequest ifEmpty: [
×
613
                ^ {
×
614
                          (#avgDuration -> nil).
×
615
                          (#overEach -> aDateWeekMonthOrYear name).
×
616
                          (#forOver -> (groupedByDate keys size printString
×
617
                            , aDateWeekMonthOrYear printString)).
×
618
                          (#totalMergeRequest -> 0).
×
619
                          (#details -> nil) } asDictionary ].
×
620

×
621
        res := mergeRequest collect: [ :mr |
×
622
                       gitAnalyzer analyseMergeResquestValidation: mr ].
×
623

×
624

×
625
        res do: [ :dic |
×
626
                | overDate |
×
627
                overDate := self
×
628
                                    transformDate: (dic at: #created_at)
×
629
                                    to: aDateWeekMonthOrYear.
×
630

×
631
                groupedByDate
×
632
                        at: overDate printString
×
633
                        ifPresent: [ :durations | durations add: (dic at: #duration) ]
×
634
                        ifAbsentPut: [
×
635
                                OrderedCollection new
×
636
                                        add: (dic at: #duration);
×
637
                                        yourself ] ].
×
638

×
639

×
640
        filterGroups := groupedByDate reject: [ :array | array isEmpty ].
×
641

×
642
        filterGroups associations do: [ :assoc |
×
643
                | sum denominator |
×
644
                denominator := assoc value size.
×
645

×
646
                sum := assoc value sum: [ :v |
×
647
                               v ifNil: [
×
648
                                       denominator := denominator - 1.
×
649
                                       0 asDuration ] ].
×
650
                denominator = 0 ifTrue: [ denominator := 1 ].
×
651

×
652
                filterGroups at: assoc key put: sum / denominator ].
×
653

×
654

×
655
        filterGroups keys
×
656
                ifEmpty: [ avg := 0 ]
×
657
                ifNotEmpty: [
×
658
                avg := filterGroups values sum / filterGroups keys size ].
×
659

×
660

×
661
        ^ {
×
662
                  (#avgDuration -> avg).
×
663
                  (#overEach -> aDateWeekMonthOrYear name).
×
664
                  (#forOver -> (groupedByDate keys size printString
×
665
                    , aDateWeekMonthOrYear printString)).
×
666
                  (#totalMergeRequest -> mergeRequest size).
×
667
                  (#details -> groupedByDate) } asDictionary
×
668
]
×
669

×
670
{ #category : #setup }
×
671
GitMetric4User >> setupGroupedDateFrom: since to: until over: aDateWeekMonthOrYear [
×
672

×
673
        | groupedByDate start end over increment|
×
674
        groupedByDate := OrderedDictionary new.
×
675

×
676
        increment := 1.
×
677
        start := self transformDate: since to: aDateWeekMonthOrYear.
×
678
        end := self transformDate: until to: aDateWeekMonthOrYear.
×
679

×
680
        groupedByDate
×
681
                at: start printString
×
682
                ifAbsentPut: [ OrderedCollection new ].
×
683
        
×
684
        over := aDateWeekMonthOrYear name asLowercase asSymbol.
×
685
                over = #date ifTrue: [ over := #day ].
×
686
                over = #month ifTrue: [ increment := 32. over := #day ].
×
687
                 
×
688

×
689
        [ groupedByDate keys last asDateAndTime < end ] whileTrue: [
×
690
                | index  |
×
691
                index := groupedByDate keys last asDateAndTime + (increment perform: over).
×
692
                index := self transformDate: index to: aDateWeekMonthOrYear.
×
693
                groupedByDate
×
694
                        at: index printString
×
695
                        ifAbsentPut: [ OrderedCollection new ] ].
×
696
        
×
697
        
×
698
        over = #day ifTrue: [ 
×
699
                groupedByDate keys do: [ :date |
×
700
                        |aWeekday|
×
701
                         aWeekday := date asDate weekday. 
×
702
                        ((aWeekday =  #Sunday) or: [ aWeekday = #Saturday ] )ifTrue: [ 
×
703
                                groupedByDate removeKey: date. 
×
704
                                 ] 
×
705
                         ].
×
706
                 ].
×
707
        
×
708

×
709
        groupedByDate
×
710
                at: end printString
×
711
                ifAbsentPut: [ OrderedCollection new ].
×
712

×
713
        ^ groupedByDate
×
714
]
×
715

×
716
{ #category : #'as yet unclassified' }
×
717
GitMetric4User >> transformDate: date to: aWeekOrMonthOrYear [
×
718

×
719
        aWeekOrMonthOrYear = Month ifTrue: [ ^ date asDate month asDate ].
×
720

×
721
        ^ (date asDate perform: ('as' , aWeekOrMonthOrYear name) asSymbol)
×
722
                  asDate
×
723
]
×
724

×
725
{ #category : #accessing }
×
726
GitMetric4User >> user [
×
727
        ^ user
×
728
]
×
729

×
730
{ #category : #accessing }
×
731
GitMetric4User >> user: anUser [
×
732
        user := anUser. 
×
733
]
×
734

×
735
{ #category : #accessing }
×
736
GitMetric4User >> userCommits [
×
737
        ^ user commits
×
738
]
×
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