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

moosetechnology / GitProjectHealth / 10452332367

19 Aug 2024 11:17AM UTC coverage: 18.86%. First build
10452332367

Pull #33

github

web-flow
Merge e68325622 into f8a271406
Pull Request #33: fix: error if there are no commits in averageTimeBetweenCommits method

0 of 5 new or added lines in 1 file covered. (0.0%)

1585 of 8404 relevant lines covered (18.86%)

0.19 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 : #GitMetric,
4
        #instVars : [
5
                'itsCommits',
6
                'itsMergeRequests'
7
        ],
8
        #category : #'GitLabHealth-Model-Analysis'
9
}
10

11
{ #category : #metrics }
12
GitMetric4User >> averageTimeBetweenCommitSince: since until: until overA: aDateWeekMonthOrYear [
×
13

×
NEW
14
        | commits commitSortedByDate commits1 commits2 differences groupedByDate dateOver average |
×
15
        groupedByDate := self
×
16
                                 setupGroupedDateFrom: since
×
17
                                 to: until
×
18
                                 over: aDateWeekMonthOrYear.
×
19

×
20
        gitAnalyzer := GitAnalyzer new
×
21
                               onModel: glhModel;
×
22
                               glhImporter: glhImporter.
×
23

×
24
        glhImporter withCommitDiffs: false.
×
25
        commits := self
×
26
                           loadCommitsFromProjectsIds: itsProjects keys
×
27
                           since: since
×
28
                           until: until.
×
29
        glhImporter withCommitDiffs: true.
×
30
        commits := commits reject: [ :commit | commit commitCreator ~= user ].
×
31

×
32
        commitSortedByDate := commits sorted: [ :commit1 :commit2 |
×
33
                                      commit1 committed_date
×
34
                                      < commit2 committed_date ].
×
35

×
36
        commitSortedByDate do: [ :commit |
×
37
                dateOver := self
×
38
                                    transformDate: commit committed_date
×
39
                                    to: aDateWeekMonthOrYear.
×
40

×
41
                groupedByDate
×
42
                        at: dateOver printString
×
43
                        ifPresent: [ :value | value add: commit ] ].
×
44

×
45
        groupedByDate := groupedByDate select: [ :group | group size >= 2 ].
×
46

×
47

×
48
        groupedByDate := groupedByDate collect: [ :group |
×
49
                                 differences := (1 to: group size - 1) collect: [ :i |
×
50
                                                        commits1 := group at: i.
×
51
                                                        commits2 := group at: i + 1.
×
52

×
53
                                                        (commits2 committed_date
×
54
                                                         - commits1 committed_date)
×
55
                                                                asSeconds ].
×
56

×
57
                                 differences average asDuration ].
×
58

×
NEW
59
        average := groupedByDate
×
NEW
60
                           ifEmpty: [ nil ]
×
NEW
61
                           ifNotEmpty: [ groupedByDate average ].
×
62

×
63
        ^ {
×
64
                  (#overEach -> aDateWeekMonthOrYear name).
×
65
                  (#forOver -> (groupedByDate keys size printString
×
66
                    , aDateWeekMonthOrYear printString)).
×
NEW
67
                  (#average -> average).
×
68
                  (#details -> groupedByDate).
×
69
                  (#userCommits -> commits size) } asDictionary
×
70
]
×
71

72
{ #category : #churn }
73
GitMetric4User >> codeChurnSince: since until: until onACommitWindowOf: commitLimit overA: aDateWeekMonthOrYear [
×
74

×
75
        | commits res groupedByDate totalContributions userCommits |
×
76
        "for each commit, we get its churn result (a dictionnary)"
×
77
        'GitMetric4User: code churn' recordInfo.
×
78
        totalContributions := OrderedCollection new.
×
79
        groupedByDate := self
×
80
                                 setupGroupedDateFrom: since
×
81
                                 to: until
×
82
                                 over: aDateWeekMonthOrYear.
×
83
        gitAnalyzer := GitAnalyzer new
×
84
                               glhImporter: glhImporter;
×
85
                               onModel: glhModel;
×
86
                               maxChildCommit: commitLimit.
×
87
        glhImporter withCommitDiffs: false.
×
88
        commits := self
×
89
                           loadCommitsFromProjectsIds: itsProjects keys
×
90
                           since: since
×
91
                           until: until.
×
92
        glhImporter withCommitDiffs: true.
×
93
        userCommits := commits reject: [ :commit |
×
94
                               commit commitCreator ~= user ].
×
95
        commits := self
×
96
                           foundSuccessorOf: userCommits
×
97
                           andCompleteImportForMax: commitLimit.
×
98

×
99

×
100
        res := commits collect: [ :commit |
×
101
                       commit -> (gitAnalyzer
×
102
                                fromCommit: commit;
×
103
                                analyseChurn) ].
×
104
        res do: [ :commits4Churns |
×
105
                | commit allChurnsInCommit sumChurnInCommit overDate contribution churnOnCommit |
×
106
                commit := commits4Churns key.
×
107
                allChurnsInCommit := commits4Churns value.
×
108
                sumChurnInCommit := (allChurnsInCommit at: #churns) sum: [ :churn |
×
109
                                            | numerator |
×
110
                                            numerator := churn value at: #churnLoC.
×
111
                                            numerator ].
×
112
                contribution := allChurnsInCommit at: #totalContribution.
×
113
                totalContributions add: contribution.
×
114
                churnOnCommit := {
×
115
                                         (#churnOnCommit -> sumChurnInCommit).
×
116
                                         (#LoCOnCommit -> contribution) } asDictionary.
×
117
                overDate := self
×
118
                                    transformDate: commit created_at
×
119
                                    to: aDateWeekMonthOrYear.
×
120
                groupedByDate
×
121
                        at: overDate printString
×
122
                        ifPresent: [ :array | array add: churnOnCommit ]
×
123
                        ifAbsentPut: [
×
124
                                OrderedCollection new
×
125
                                        add: churnOnCommit;
×
126
                                        yourself ] ].
×
127
        groupedByDate := groupedByDate collect: [ :churnsAtDate |
×
128
                                 | totalChurn totalContribution percentage |
×
129
                                 totalChurn := churnsAtDate sum: [ :churn |
×
130
                                                       churn at: #churnOnCommit ].
×
131
                                 totalContribution := churnsAtDate sum: [ :churn |
×
132
                                                              churn at: #LoCOnCommit ].
×
133
                                 totalContribution = 0
×
134
                                         ifTrue: [ percentage := 0 asFloat ]
×
135
                                         ifFalse: [
×
136
                                         percentage := (totalChurn * 100
×
137
                                                        / totalContribution) asFloat ].
×
138
                                 {
×
139
                                         (#churn -> totalChurn).
×
140
                                         (#contribution -> totalContribution).
×
141
                                         (#percentage -> percentage) } asDictionary ].
×
142
        ^ {
×
143
                  (#details -> groupedByDate).
×
144
                  (#totalContribution -> (totalContributions
×
145
                            ifEmpty: [ 0 ]
×
146
                            ifNotEmpty: [ totalContributions sum ])).
×
147
                  (#totalChurn -> (groupedByDate sum: [ :date | date at: #churn ])).
×
148
                  (#churn
×
149
                   ->
×
150
                   (groupedByDate collect: [ :date | date at: #percentage ]) average).
×
151
                  (#overEach -> aDateWeekMonthOrYear name).
×
152
                  (#forOver -> (groupedByDate keys size printString
×
153
                    , aDateWeekMonthOrYear printString)).
×
154
                  (#userCommits -> commits size).
×
155
                  (#churnWindow -> commitLimit) } asDictionary
×
156
]
×
157

158
{ #category : #metrics }
159
GitMetric4User >> codeContributionsSince: since until: until overA: aDateWeekMonthOrYear [
×
160

×
161
        | commits contributions groupedByDate |
×
162
        'GitMetric4User: code contribution' recordInfo.
×
163

×
164
        groupedByDate := self
×
165
                                 setupGroupedDateFrom: since
×
166
                                 to: until
×
167
                                 over: aDateWeekMonthOrYear.
×
168

×
169
        gitAnalyzer := GitAnalyzer new
×
170
                               onModel: glhModel;
×
171
                               glhImporter: glhImporter.
×
172

×
173
        glhImporter withCommitDiffs: false.
×
174
        commits := self
×
175
                           loadCommitsFromProjectsIds: itsProjects keys
×
176
                           since: since
×
177
                           until: until.
×
178
        glhImporter withCommitDiffs: true.
×
179
        commits := commits reject: [ :commit | commit commitCreator ~= user ].
×
180

×
181
        contributions := commits collect: [ :commit |
×
182
                                 commit -> (gitAnalyzer
×
183
                                          fromCommit: commit;
×
184
                                          analyseCommitContribution) ].
×
185

×
186
        contributions do: [ :assoc |
×
187
                | dateOver |
×
188
                dateOver := self
×
189
                                    transformDate: assoc key created_at
×
190
                                    to: aDateWeekMonthOrYear.
×
191
                groupedByDate
×
192
                        at: dateOver printString
×
193
                        ifPresent: [ :v | v add: assoc value ]
×
194
                        ifAbsentPut: [
×
195
                                OrderedCollection new
×
196
                                        add: assoc value;
×
197
                                        yourself ] ].
×
198

×
199
        groupedByDate := groupedByDate collect: [ :contribs |
×
200
                                 | totalAdd totalDele |
×
201
                                 totalAdd := contribs sum: [ :v | v at: #addition ].
×
202
                                 totalDele := contribs sum: [ :v | v at: #deletion ].
×
203
                                 {
×
204
                                         (#addition -> totalAdd).
×
205
                                         (#deletion -> totalDele) } asDictionary ].
×
206

×
207
        ^ {
×
208
                  (#overEach -> aDateWeekMonthOrYear name).
×
209
                  (#forOver -> (groupedByDate keys size printString
×
210
                    , aDateWeekMonthOrYear printString)).
×
211
                  (#avgAddition
×
212
                   ->
×
213
                   (groupedByDate collect: [ :d | d at: #addition ]) average asFloat).
×
214
                  (#avgDeletion
×
215
                   ->
×
216
                   (groupedByDate collect: [ :d | d at: #deletion ]) average asFloat).
×
217
                  (#details -> groupedByDate).
×
218
                  (#userCommits -> commits size) } asDictionary
×
219
]
×
220

221
{ #category : #metrics }
222
GitMetric4User >> commentsContributionsSince: since until: until overA: aDateWeekMonthOrYear [
×
223

×
224
        | commits contributions groupedByDate |
×
225
        'GitMetric4User: comment contribution' recordInfo.
×
226

×
227
        groupedByDate := self
×
228
                                 setupGroupedDateFrom: since
×
229
                                 to: until
×
230
                                 over: aDateWeekMonthOrYear.
×
231

×
232
        gitAnalyzer := GitAnalyzer new
×
233
                               onModel: glhModel;
×
234
                               glhImporter: glhImporter.
×
235

×
236
        glhImporter withCommitDiffs: false.
×
237
        commits := self
×
238
                           loadCommitsFromProjectsIds: itsProjects keys
×
239
                           since: since
×
240
                           until: until.
×
241
        glhImporter withCommitDiffs: true.
×
242
        commits := commits reject: [ :commit | commit commitCreator ~= user ].
×
243
        commits do: [ :commit | glhImporter completeImportedCommit: commit ].
×
244

×
245

×
246
        contributions := commits collect: [ :commit |
×
247
                                 commit -> (gitAnalyzer
×
248
                                          fromCommit: commit;
×
249
                                          analyseCommentContribution) ].
×
250

×
251

×
252
        contributions do: [ :assoc |
×
253
                | dateOver |
×
254
                dateOver := self
×
255
                                    transformDate: assoc key created_at
×
256
                                    to: aDateWeekMonthOrYear.
×
257
                groupedByDate
×
258
                        at: dateOver printString
×
259
                        ifPresent: [ :v | v add: assoc value ]
×
260
                        ifAbsentPut: [
×
261
                                OrderedCollection new
×
262
                                        add: assoc value;
×
263
                                        yourself ] ].
×
264

×
265
        groupedByDate := groupedByDate collect: [ :contribs |
×
266
                                 contribs
×
267
                                         ifNotEmpty: [ contribs sum ]
×
268
                                         ifEmpty: [ 0 ] ].
×
269

×
270

×
271
        ^ {
×
272
                  (#details -> groupedByDate).
×
273
                  (#totalComments -> groupedByDate values sum).
×
274
                  (#avgComments -> groupedByDate values average asFloat).
×
275
                  (#overEach -> aDateWeekMonthOrYear name).
×
276
                  (#forOver -> (groupedByDate keys size printString
×
277
                    , aDateWeekMonthOrYear printString)).
×
278
                  (#userCommits -> commits size) } asDictionary
×
279
]
×
280

281
{ #category : #metrics }
282
GitMetric4User >> commitFrequencySince: since until: until overA: aDateWeekMonthOrYear [
×
283

×
284
        | periods total groupedByDate userCommits |
×
285
        'GitMetric4User: commit frequency' recordInfo.
×
286

×
287
        groupedByDate := self
×
288
                                 setupGroupedDateFrom: since
×
289
                                 to: until
×
290
                                 over: aDateWeekMonthOrYear.
×
291

×
292
        glhImporter withCommitDiffs: false.
×
293
        userCommits := self
×
294
                               loadCommitsFromProjectsIds: itsProjects keys
×
295
                               since: since
×
296
                               until: until.
×
297
        glhImporter withCommitDiffs: true.
×
298
        userCommits := userCommits reject: [ :c | c commitCreator ~= user ].
×
299

×
300
        userCommits do: [ :c |
×
301
                | dateOver |
×
302
                dateOver := self
×
303
                                    transformDate: c created_at
×
304
                                    to: aDateWeekMonthOrYear.
×
305
                groupedByDate at: dateOver printString ifPresent: [ :v | v add: c ] ].
×
306

×
307
        periods := groupedByDate keys size.
×
308
        total := groupedByDate values sum: [ :commits | commits size ].
×
309

×
310

×
311
        ^ {
×
312
                  (#averageFrac -> (total / periods)).
×
313
                  (#averageFloat -> (total / periods) asFloat).
×
314
                  (#userCommit -> total).
×
315
                  (#forOver -> (groupedByDate keys size printString
×
316
                    , aDateWeekMonthOrYear printString)).
×
317
                  (#periode -> aDateWeekMonthOrYear name).
×
318
                  (#details -> groupedByDate) } asOrderedDictionary
×
319
]
×
320

321
{ #category : #metrics }
322
GitMetric4User >> commitsProducedOnProject: projectId since: sinceDate until: untilDate [
×
323

×
324
        | frequencies |
×
325
        
×
326
        
×
327
        gitAnalyzer := GitAnalyzer new 
×
328
        glhImporter: glhImporter; 
×
329
        onModel: glhModel.
×
330
         
×
331
        frequencies := gitAnalyzer
×
332
                               onProject: (itsProjects at: projectId);
×
333
                               analyseCommitFrequencySince: sinceDate
×
334
                               until: untilDate. 
×
335
        
×
336
        "complete each commit "
×
337
        frequencies values flattened do: [ :commit |
×
338
                glhImporter completeImportedCommit: commit.
×
339
                 ].
×
340
        
×
341
        "Filter the associations in the 'frequencies' collection, removing any commits not created by the specified 'user'. "
×
342
        frequencies associations do: [ :assoc |
×
343
                |commits| 
×
344
                commits := assoc value.
×
345
                assoc value: (commits reject: [ :commit | commit commitCreator ~= user ]). 
×
346
        ].
×
347
        
×
348
        ^ frequencies 
×
349
]
×
350

351
{ #category : #metrics }
352
GitMetric4User >> commitsProducedOnProject: aProjectId since: since until: until overA: aWeekOrMonthOrYear [
×
353
        "'aWeekOrMonthOrYear' should be the class of Data, Week, Month or Year"
×
354

×
355
        | frequency aggregatedFrequencies |
×
356
        aggregatedFrequencies := self
×
357
                                         setupGroupedDateFrom: since
×
358
                                         to: until
×
359
                                         over: aWeekOrMonthOrYear.
×
360

×
361
        frequency := self
×
362
                             commitsProducedOnProject: aProjectId
×
363
                             since: since
×
364
                             until: until.
×
365

×
366
        frequency associations do: [ :assoc |
×
367
                | date commits overDate |
×
368
                date := assoc key.
×
369
                commits := assoc value.
×
370

×
371
                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 "
×
372
                        overDate := self transformDate: date to: aWeekOrMonthOrYear.
×
373
                        aggregatedFrequencies
×
374
                                at: overDate printString
×
375
                                ifPresent: [ :collection | collection addAll: commits ]
×
376
                                ifAbsentPut: [ commits ] ] ].
×
377

×
378
        ^ aggregatedFrequencies
×
379
]
×
380

381
{ #category : #churn }
382
GitMetric4User >> delayUntilFirstChurnSince: since until: until onACommitWindowOf: maxCommitWindow overA: aDateWeekMonthOrYear [
×
383

×
384
        | commits groupedByDate res avg userCommits |
×
385
        'GitMetric4User: delay until first churn' recordInfo.
×
386

×
387
        groupedByDate := self
×
388
                                 setupGroupedDateFrom: since
×
389
                                 to: until
×
390
                                 over: aDateWeekMonthOrYear.
×
391

×
392
        glhImporter withCommitDiffs: false.
×
393
        commits := self
×
394
                           loadCommitsFromProjectsIds: itsProjects keys
×
395
                           since: since
×
396
                           until: until.
×
397
        glhImporter withCommitDiffs: true.
×
398

×
399
        userCommits := commits reject: [ :commit |
×
400
                               commit commitCreator ~= user ].
×
401
        commits := self
×
402
                           foundSuccessorOf: userCommits
×
403
                           andCompleteImportForMax: maxCommitWindow.
×
404

×
405

×
406
        "class commit by dates, filter none user commits"
×
407
        commits do: [ :commit |
×
408
                commit commitCreator = user ifTrue: [
×
409
                        | overDate |
×
410
                        overDate := self
×
411
                                            transformDate: commit created_at
×
412
                                            to: aDateWeekMonthOrYear.
×
413

×
414
                        groupedByDate
×
415
                                at: overDate printString
×
416
                                ifPresent: [ :arrayOfCommits | arrayOfCommits add: commit ]
×
417
                                ifAbsentPut: [
×
418
                                        OrderedCollection new
×
419
                                                add: commit;
×
420
                                                yourself ] ] ].
×
421

×
422

×
423

×
424
        res := groupedByDate collect: [ :commits4Date |
×
425
                       | durationFromA2B |
×
426
                       commits4Date collect: [ :commitA |
×
427
                               | commitB |
×
428
                               commitB := GitAnalyzer new
×
429
                                                  glhImporter: glhImporter;
×
430
                                                  onModel: glhModel;
×
431
                                                  fromCommit: commitA;
×
432
                                                  maxChildCommit: maxCommitWindow;
×
433
                                                  analyseDelayUntilFirstChurn.
×
434

×
435
                               durationFromA2B := commitB
×
436
                                                          ifNil: [ 0 ]
×
437
                                                          ifNotNil: [
×
438
                                                          commitB created_at - commitA created_at ].
×
439
                               durationFromA2B ] ].
×
440

×
441

×
442

×
443
        res := res collect: [ :durationsByDate |
×
444
                       | filtered |
×
445
                       filtered := durationsByDate reject: [ :value | value = 0 ].
×
446
                       filtered isEmpty
×
447
                               ifTrue: [ nil ]
×
448
                               ifFalse: [
×
449
                               (filtered sum: [ :v | v asDuration asSeconds]) / filtered size ] ].
×
450

×
451
        res := res reject: #isNil.
×
452

×
453
        res
×
454
                ifEmpty: [ avg := nil ]
×
455
                ifNotEmpty: [ avg := res values average asFloat ].
×
456

×
457

×
458
        ^ {
×
459
                  (#avgDelay -> avg).
×
460
                  (#overEach -> aDateWeekMonthOrYear name).
×
461
                  (#forOver -> (groupedByDate keys size printString
×
462
                    , aDateWeekMonthOrYear printString)).
×
463
                  (#details -> groupedByDate) } asDictionary
×
464
]
×
465

466
{ #category : #churn }
467
GitMetric4User >> delayUntilFirstChurnSince: since until: until overA: aDateWeekMonthOrYear [
×
468

×
469
        | commits groupedByDate res avg |
×
470
        self
×
471
                deprecated:
×
472
                'Use #delayUntilFirstChurnSince:until:onACommitWindowOf:overA: instead'
×
473
                on: '1 July 2024'
×
474
                in:
×
475
                'Pharo-11.0.0+build.726.sha.aece1b5473acf3830a0e082c1bc3a15d4ff3522b (64 Bit)'.
×
476

×
477
        'GitMetric4User: delay until first churn' recordInfo.
×
478

×
479
        groupedByDate := self
×
480
                                 setupGroupedDateFrom: since
×
481
                                 to: until
×
482
                                 over: aDateWeekMonthOrYear.
×
483

×
484
        commits := self
×
485
                           loadCommitsFromProjectsIds: itsProjects keys
×
486
                           since: since
×
487
                           until: until.
×
488

×
489
        "class commit by dates, filter none user commits"
×
490
        commits do: [ :commit |
×
491
                commit commitCreator = user ifTrue: [
×
492
                        | overDate |
×
493
                        overDate := self
×
494
                                            transformDate: commit created_at
×
495
                                            to: aDateWeekMonthOrYear.
×
496

×
497
                        groupedByDate
×
498
                                at: overDate printString
×
499
                                ifPresent: [ :arrayOfCommits | arrayOfCommits add: commit ]
×
500
                                ifAbsentPut: [
×
501
                                        OrderedCollection new
×
502
                                                add: commit;
×
503
                                                yourself ] ] ].
×
504

×
505

×
506

×
507
        res := groupedByDate collect: [ :commits4Date |
×
508
                       | durationFromA2B |
×
509
                       commits4Date collect: [ :commitA |
×
510
                               | commitB |
×
511
                               commitB := GitAnalyzer new
×
512
                                                  glhImporter: glhImporter;
×
513
                                                  onModel: glhModel;
×
514
                                                  fromCommit: commitA;
×
515
                                                  maxChildCommit: 5;
×
516
                                                  analyseDelayUntilFirstChurn.
×
517

×
518
                               durationFromA2B := commitB
×
519
                                                          ifNil: [ 0 ]
×
520
                                                          ifNotNil: [
×
521
                                                          commitB created_at - commitA created_at ].
×
522
                               durationFromA2B ] ].
×
523

×
524

×
525

×
526
        res := res collect: [ :durationsByDate |
×
527
                       | filtered |
×
528
                       filtered := durationsByDate reject: [ :value | value = 0 ].
×
529
                       filtered isEmpty
×
530
                               ifTrue: [ nil ]
×
531
                               ifFalse: [
×
532
                               (filtered sum: [ :v | v asDuration ]) / filtered size ] ].
×
533

×
534
        res := res reject: #isNil.
×
535

×
536
        res
×
537
                ifEmpty: [ avg := nil ]
×
538
                ifNotEmpty: [ avg := res values sum / res keys size ].
×
539

×
540

×
541
        ^ {
×
542
                  (#avgDelay -> avg).
×
543
                  (#overEach -> aDateWeekMonthOrYear name).
×
544
                  (#forOver -> (groupedByDate keys size printString
×
545
                    , aDateWeekMonthOrYear printString)).
×
546
                  (#details -> groupedByDate) } asDictionary
×
547
]
×
548

549
{ #category : #churn }
550
GitMetric4User >> foundSuccessorOf: userCommits andCompleteImportForMax: commitLimit [
×
551

×
552
        | analyzingCommits i size|
×
553
        analyzingCommits := Set new.
×
554
        glhImporter withCommitDiffs: true.
×
555

×
556
        userCommits do: [ :c |
×
557
                gitAnalyzer
×
558
                        visitChildCommits: c childCommits
×
559
                        toStoreThemIn: analyzingCommits
×
560
                        upto: commitLimit ].
×
561

×
562
        i := 0.
×
563
        size := analyzingCommits size. 
×
564
        analyzingCommits do: [ :c |
×
565
                ('import complete commits  [' , (i:=i+1) printString, '/', size printString , ']'  ) recordInfo.
×
566
                glhImporter completeImportedCommit: c ].
×
567

×
568
        ^ analyzingCommits
×
569
]
×
570

571
{ #category : #analysis }
572
GitMetric4User >> generateAnalysisForPeriod: period over: aDateWeekMonthOrYear withMaxCommitWindows: maxCommitWindow [
×
573

×
574
        | contribution commitFrequency commentContribution mergeRequestDuration codeChurn delayUntilFirstChurn averageTimeBetweenCommits numberOfProjectWithCommit |
×
575
        contribution := self
×
576
                                codeContributionsSince: (period at: #since)
×
577
                                until: (period at: #until)
×
578
                                overA: aDateWeekMonthOrYear.
×
579

×
580
        commitFrequency := self
×
581
                                   commitFrequencySince: (period at: #since)
×
582
                                   until: (period at: #until)
×
583
                                   overA: aDateWeekMonthOrYear.
×
584

×
585
        commentContribution := self
×
586
                                       commentsContributionsSince:
×
587
                                       (period at: #since)
×
588
                                       until: (period at: #until)
×
589
                                       overA: aDateWeekMonthOrYear.
×
590

×
591
        mergeRequestDuration := self
×
592
                                        mergeRequestDurationSince:
×
593
                                        (period at: #since)
×
594
                                        until: (period at: #until)
×
595
                                        overA: aDateWeekMonthOrYear.
×
596

×
597
        codeChurn := self
×
598
                             codeChurnSince: (period at: #since)
×
599
                             until: (period at: #until)
×
600
                             onACommitWindowOf: maxCommitWindow
×
601
                             overA: aDateWeekMonthOrYear.
×
602

×
603
        delayUntilFirstChurn := self
×
604
                                        delayUntilFirstChurnSince:
×
605
                                        (period at: #since)
×
606
                                        until: (period at: #until)
×
607
                                        onACommitWindowOf: maxCommitWindow
×
608
                                        overA: aDateWeekMonthOrYear.
×
609

×
610
        numberOfProjectWithCommit := self
×
611
                                             numberOfProjectWithCommitSince:
×
612
                                             (period at: #since)
×
613
                                             until: (period at: #until)
×
614
                                             overA: aDateWeekMonthOrYear.
×
615
        averageTimeBetweenCommits := self
×
616
                                             averageTimeBetweenCommitSince:
×
617
                                             (period at: #since)
×
618
                                             until: (period at: #until)
×
619
                                             overA: aDateWeekMonthOrYear.
×
620

×
621
        ^ AnalysisReport new
×
622
                  username: self user name;
×
623
                  period: period;
×
624
                  over: aDateWeekMonthOrYear asString;
×
625
                  codeAddition: (contribution at: #avgAddition);
×
626
                  codeDeletion: (contribution at: #avgDeletion);
×
627
                  commitFrequency: (commitFrequency at: #averageFloat);
×
628
                  commentContribution: (commentContribution at: #avgComments);
×
629
                  mergeRequestDuration: (mergeRequestDuration at: #avgDuration);
×
630
                  codeChurn: (codeChurn at: #churn);
×
631
                  delayUntilFirstChurn: (delayUntilFirstChurn at: #avgDelay);
×
632
                  numberOfProjectWithCommit:
×
633
                          (numberOfProjectWithCommit at: #average);
×
634
                  averageTimeBetweenCommits:
×
635
                          (averageTimeBetweenCommits at: #average)
×
636
]
×
637

638
{ #category : #initialization }
639
GitMetric4User >> initialize [
×
640

×
641
        user := GLHUser new.
×
642
        itsProjects := Dictionary new.
×
643
        itsCommits := Dictionary new.
×
644
        itsMergeRequests := Dictionary new
×
645
]
×
646

647
{ #category : #accessing }
648
GitMetric4User >> itsProjects: projects [
×
649
        itsProjects := projects .
×
650
]
×
651

652
{ #category : #churn }
653
GitMetric4User >> loadCommitOfProjects: aCollection since: aTimespan [
×
654
        |commits|
×
655
        
×
656
        commits := (aCollection collect: [ :id |
×
657
                 glhImporter
×
658
                        importCommitsOProject: (itsProjects at: id)
×
659
                        since: aTimespan
×
660
                        until: nil ]) flattened.
×
661

×
662
        commits do: [ :commit |
×
663
                glhImporter completeImportedCommit: commit. 
×
664
                 ].
×
665

×
666
        ^ self userCommits.
×
667
]
×
668

669
{ #category : #metrics }
670
GitMetric4User >> mergeRequestDurationSince: since until: until overA: aDateWeekMonthOrYear [
×
671

×
672
        | mergeRequest res groupedByDate filterGroups avg |
×
673
        groupedByDate := self
×
674
                                 setupGroupedDateFrom: since
×
675
                                 to: until
×
676
                                 over: aDateWeekMonthOrYear.
×
677

×
678
        gitAnalyzer := GitAnalyzer new
×
679
                               glhImporter: glhImporter;
×
680
                               onModel: glhModel.
×
681

×
682
        glhImporter withCommitDiffs: false.
×
683
        mergeRequest := self
×
684
                                loadMergeRequestsFromProjectsIds: itsProjects keys
×
685
                                since: since
×
686
                                until: until.
×
687
        glhImporter withCommitDiffs: true.
×
688

×
689
        mergeRequest ifEmpty: [
×
690
                ^ {
×
691
                          (#avgDuration -> nil).
×
692
                          (#overEach -> aDateWeekMonthOrYear name).
×
693
                          (#forOver -> (groupedByDate keys size printString
×
694
                            , aDateWeekMonthOrYear printString)).
×
695
                          (#totalMergeRequest -> 0).
×
696
                          (#details -> nil) } asDictionary ].
×
697

×
698
        res := mergeRequest collect: [ :mr |
×
699
                       gitAnalyzer analyseMergeResquestValidation: mr ].
×
700

×
701

×
702
        res do: [ :dic |
×
703
                | overDate |
×
704
                overDate := self
×
705
                                    transformDate: (dic at: #created_at)
×
706
                                    to: aDateWeekMonthOrYear.
×
707

×
708
                groupedByDate
×
709
                        at: overDate printString
×
710
                        ifPresent: [ :durations | durations add: (dic at: #duration) ]
×
711
                        ifAbsentPut: [
×
712
                                OrderedCollection new
×
713
                                        add: (dic at: #duration);
×
714
                                        yourself ] ].
×
715

×
716

×
717
        filterGroups := groupedByDate reject: [ :array | array isEmpty ].
×
718

×
719
        filterGroups associations do: [ :assoc |
×
720
                | sum denominator |
×
721
                denominator := assoc value size.
×
722

×
723
                sum := assoc value sum: [ :v |
×
724
                               v ifNil: [
×
725
                                       denominator := denominator - 1.
×
726
                                       0 asDuration ] ].
×
727
                denominator = 0 ifTrue: [ denominator := 1 ].
×
728

×
729
                filterGroups at: assoc key put: sum / denominator ].
×
730

×
731

×
732
        filterGroups keys
×
733
                ifEmpty: [ avg := 0 ]
×
734
                ifNotEmpty: [
×
735
                avg := filterGroups values sum / filterGroups keys size ].
×
736

×
737

×
738
        ^ {
×
739
                  (#avgDuration -> avg).
×
740
                  (#overEach -> aDateWeekMonthOrYear name).
×
741
                  (#forOver -> (groupedByDate keys size printString
×
742
                    , aDateWeekMonthOrYear printString)).
×
743
                  (#totalMergeRequest -> mergeRequest size).
×
744
                  (#details -> groupedByDate) } asDictionary
×
745
]
×
746

747
{ #category : #metrics }
748
GitMetric4User >> numberOfProjectWithCommitSince: since until: until overA: aDateWeekMonthOrYear [
×
749
        | groupedByDate commits userCommits dateOver projects |
×
750
        groupedByDate := self
×
751
                                 setupGroupedDateFrom: since
×
752
                                 to: until
×
753
                                 over: aDateWeekMonthOrYear.
×
754
                
×
755
        gitAnalyzer := GitAnalyzer new
×
756
                               onModel: glhModel;
×
757
                               glhImporter: glhImporter.
×
758

×
759
        glhImporter withCommitDiffs: false.
×
760
        commits := self
×
761
                           loadCommitsFromProjectsIds: itsProjects keys
×
762
                           since: since
×
763
                           until: until.
×
764
        glhImporter withCommitDiffs: true.
×
765
        userCommits := commits reject: [ :commit | commit commitCreator ~= user ].
×
766
        
×
767

×
768
        userCommits do: [ :userCommit |
×
769
                 dateOver := self
×
770
                                    transformDate: userCommit committed_date 
×
771
                                    to: aDateWeekMonthOrYear.
×
772
                        
×
773
                groupedByDate at: dateOver printString ifPresent: [ :value | value add: (userCommit repository project) ].
×
774
        ].
×
775

×
776
        groupedByDate := groupedByDate collect: [ :group |                 
×
777
                projects := Set newFrom: group.                
×
778
                projects size.
×
779
        ].
×
780

×
781
        ^ {
×
782
                  (#overEach -> aDateWeekMonthOrYear name).
×
783
                  (#forOver -> (groupedByDate keys size printString
×
784
                    , aDateWeekMonthOrYear printString)).
×
785
                  (#average
×
786
                   ->
×
787
                   groupedByDate average asFloat).
×
788
                  (#details -> groupedByDate).
×
789
                  (#userCommits -> commits size) } asDictionary
×
790

×
791
]
×
792

793
{ #category : #accessing }
794
GitMetric4User >> user [
×
795
        ^ user
×
796
]
×
797

798
{ #category : #accessing }
799
GitMetric4User >> user: anUser [
×
800
        user := anUser. 
×
801
]
×
802

803
{ #category : #accessing }
804
GitMetric4User >> userCommits [
×
805
        ^ user commits
×
806
]
×
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