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

moosetechnology / GitProjectHealth / 10450017301

19 Aug 2024 08:36AM UTC coverage: 18.876%. First build
10450017301

Pull #30

github

web-flow
Merge b05027828 into 157ef9319
Pull Request #30: feat(metrics): number of project with a commit of the user

0 of 61 new or added lines in 3 files covered. (0.0%)

1585 of 8397 relevant lines covered (18.88%)

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 over: aDateWeekMonthOrYear [
×
13

×
14
        | commits commitSortedByDate commits1 commits2 differences groupedByDate dateOver |
×
15
        
×
16
        groupedByDate := self
×
17
                                 setupGroupedDateFrom: since
×
18
                                 to: until
×
19
                                 over: aDateWeekMonthOrYear.
×
20
        
×
21
        gitAnalyzer := GitAnalyzer new
×
22
                               onModel: glhModel;
×
23
                               glhImporter: glhImporter.
×
24

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

×
33
        commitSortedByDate := commits sorted: [ :commit1 :commit2 |
×
34
                                      commit1 committed_date
×
35
                                      < commit2 committed_date ].
×
36
                        
×
37
        commitSortedByDate do: [ :commit | 
×
38
                 dateOver := self
×
39
                                    transformDate: commit committed_date 
×
40
                                    to: aDateWeekMonthOrYear.
×
41
                
×
42
                groupedByDate at: dateOver printString ifPresent: [ :value | value add: commit ].
×
43
        ].
×
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 - commits1 committed_date) asSeconds ].
×
54

×
55
                differences average asDuration.    
×
56
        ].
×
57
        
×
58

×
59
        ^{
×
60
                  (#overEach -> aDateWeekMonthOrYear name).
×
61
                  (#forOver -> (groupedByDate keys size printString
×
62
                    , aDateWeekMonthOrYear printString)).
×
63
                  (#average -> groupedByDate average).
×
64
                  (#details -> groupedByDate).
×
65
                  (#userCommits -> commits size) } asDictionary.
×
66
]
×
67

68
{ #category : #churn }
69
GitMetric4User >> codeChurnSince: since until: until onACommitWindowOf: commitLimit overA: aDateWeekMonthOrYear [
×
70

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

×
95

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

154
{ #category : #metrics }
155
GitMetric4User >> codeContributionsSince: since until: until overA: aDateWeekMonthOrYear [
×
156

×
157
        | commits contributions groupedByDate |
×
158
        'GitMetric4User: code contribution' recordInfo.
×
159

×
160
        groupedByDate := self
×
161
                                 setupGroupedDateFrom: since
×
162
                                 to: until
×
163
                                 over: aDateWeekMonthOrYear.
×
164

×
165
        gitAnalyzer := GitAnalyzer new
×
166
                               onModel: glhModel;
×
167
                               glhImporter: glhImporter.
×
168

×
169
        glhImporter withCommitDiffs: false.
×
170
        commits := self
×
171
                           loadCommitsFromProjectsIds: itsProjects keys
×
172
                           since: since
×
173
                           until: until.
×
174
        glhImporter withCommitDiffs: true.
×
175
        commits := commits reject: [ :commit | commit commitCreator ~= user ].
×
176

×
177
        contributions := commits collect: [ :commit |
×
178
                                 commit -> (gitAnalyzer
×
179
                                          fromCommit: commit;
×
180
                                          analyseCommitContribution) ].
×
181

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

×
195
        groupedByDate := groupedByDate collect: [ :contribs |
×
196
                                 | totalAdd totalDele |
×
197
                                 totalAdd := contribs sum: [ :v | v at: #addition ].
×
198
                                 totalDele := contribs sum: [ :v | v at: #deletion ].
×
199
                                 {
×
200
                                         (#addition -> totalAdd).
×
201
                                         (#deletion -> totalDele) } asDictionary ].
×
202

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

217
{ #category : #metrics }
218
GitMetric4User >> commentsContributionsSince: since until: until overA: aDateWeekMonthOrYear [
×
219

×
220
        | commits contributions groupedByDate |
×
221
        'GitMetric4User: comment contribution' recordInfo.
×
222

×
223
        groupedByDate := self
×
224
                                 setupGroupedDateFrom: since
×
225
                                 to: until
×
226
                                 over: aDateWeekMonthOrYear.
×
227

×
228
        gitAnalyzer := GitAnalyzer new
×
229
                               onModel: glhModel;
×
230
                               glhImporter: glhImporter.
×
231

×
232
        glhImporter withCommitDiffs: false.
×
233
        commits := self
×
234
                           loadCommitsFromProjectsIds: itsProjects keys
×
235
                           since: since
×
236
                           until: until.
×
237
        glhImporter withCommitDiffs: true.
×
238
        commits := commits reject: [ :commit | commit commitCreator ~= user ].
×
239
        commits do: [ :commit | glhImporter completeImportedCommit: commit ].
×
240

×
241

×
242
        contributions := commits collect: [ :commit |
×
243
                                 commit -> (gitAnalyzer
×
244
                                          fromCommit: commit;
×
245
                                          analyseCommentContribution) ].
×
246

×
247

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

×
261
        groupedByDate := groupedByDate collect: [ :contribs |
×
262
                                 contribs
×
263
                                         ifNotEmpty: [ contribs sum ]
×
264
                                         ifEmpty: [ 0 ] ].
×
265

×
266

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

277
{ #category : #metrics }
278
GitMetric4User >> commitFrequencySince: since until: until overA: aDateWeekMonthOrYear [
×
279

×
280
        | periods total groupedByDate userCommits |
×
281
        'GitMetric4User: commit frequency' recordInfo.
×
282

×
283
        groupedByDate := self
×
284
                                 setupGroupedDateFrom: since
×
285
                                 to: until
×
286
                                 over: aDateWeekMonthOrYear.
×
287

×
288
        glhImporter withCommitDiffs: false.
×
289
        userCommits := self
×
290
                               loadCommitsFromProjectsIds: itsProjects keys
×
291
                               since: since
×
292
                               until: until.
×
293
        glhImporter withCommitDiffs: true.
×
294
        userCommits := userCommits reject: [ :c | c commitCreator ~= user ].
×
295

×
296
        userCommits do: [ :c |
×
297
                | dateOver |
×
298
                dateOver := self
×
299
                                    transformDate: c created_at
×
300
                                    to: aDateWeekMonthOrYear.
×
301
                groupedByDate at: dateOver printString ifPresent: [ :v | v add: c ] ].
×
302

×
303
        periods := groupedByDate keys size.
×
304
        total := groupedByDate values sum: [ :commits | commits size ].
×
305

×
306

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

317
{ #category : #'as yet unclassified' }
318
GitMetric4User >> commitsProducedOnProject: projectId since: sinceDate until: untilDate [
×
319

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

347
{ #category : #metrics }
348
GitMetric4User >> commitsProducedOnProject: aProjectId since: since until: until overA: aWeekOrMonthOrYear [
×
349
        "'aWeekOrMonthOrYear' should be the class of Data, Week, Month or Year"
×
350

×
351
        | frequency aggregatedFrequencies |
×
352
        aggregatedFrequencies := self
×
353
                                         setupGroupedDateFrom: since
×
354
                                         to: until
×
355
                                         over: aWeekOrMonthOrYear.
×
356

×
357
        frequency := self
×
358
                             commitsProducedOnProject: aProjectId
×
359
                             since: since
×
360
                             until: until.
×
361

×
362
        frequency associations do: [ :assoc |
×
363
                | date commits overDate |
×
364
                date := assoc key.
×
365
                commits := assoc value.
×
366

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

×
374
        ^ aggregatedFrequencies
×
375
]
×
376

377
{ #category : #churn }
378
GitMetric4User >> delayUntilFirstChurnSince: since until: until onACommitWindowOf: maxCommitWindow overA: aDateWeekMonthOrYear [
×
379

×
380
        | commits groupedByDate res avg userCommits |
×
381
        'GitMetric4User: delay until first churn' recordInfo.
×
382

×
383
        groupedByDate := self
×
384
                                 setupGroupedDateFrom: since
×
385
                                 to: until
×
386
                                 over: aDateWeekMonthOrYear.
×
387

×
388
        glhImporter withCommitDiffs: false.
×
389
        commits := self
×
390
                           loadCommitsFromProjectsIds: itsProjects keys
×
391
                           since: since
×
392
                           until: until.
×
393
        glhImporter withCommitDiffs: true.
×
394

×
395
        userCommits := commits reject: [ :commit |
×
396
                               commit commitCreator ~= user ].
×
397
        commits := self
×
398
                           foundSuccessorOf: userCommits
×
399
                           andCompleteImportForMax: maxCommitWindow.
×
400

×
401

×
402
        "class commit by dates, filter none user commits"
×
403
        commits do: [ :commit |
×
404
                commit commitCreator = user ifTrue: [
×
405
                        | overDate |
×
406
                        overDate := self
×
407
                                            transformDate: commit created_at
×
408
                                            to: aDateWeekMonthOrYear.
×
409

×
410
                        groupedByDate
×
411
                                at: overDate printString
×
412
                                ifPresent: [ :arrayOfCommits | arrayOfCommits add: commit ]
×
413
                                ifAbsentPut: [
×
414
                                        OrderedCollection new
×
415
                                                add: commit;
×
416
                                                yourself ] ] ].
×
417

×
418

×
419

×
420
        res := groupedByDate collect: [ :commits4Date |
×
421
                       | durationFromA2B |
×
422
                       commits4Date collect: [ :commitA |
×
423
                               | commitB |
×
424
                               commitB := GitAnalyzer new
×
425
                                                  glhImporter: glhImporter;
×
426
                                                  onModel: glhModel;
×
427
                                                  fromCommit: commitA;
×
428
                                                  maxChildCommit: maxCommitWindow;
×
429
                                                  analyseDelayUntilFirstChurn.
×
430

×
431
                               durationFromA2B := commitB
×
432
                                                          ifNil: [ 0 ]
×
433
                                                          ifNotNil: [
×
434
                                                          commitB created_at - commitA created_at ].
×
435
                               durationFromA2B ] ].
×
436

×
437

×
438

×
439
        res := res collect: [ :durationsByDate |
×
440
                       | filtered |
×
441
                       filtered := durationsByDate reject: [ :value | value = 0 ].
×
442
                       filtered isEmpty
×
443
                               ifTrue: [ nil ]
×
444
                               ifFalse: [
×
445
                               (filtered sum: [ :v | v asDuration asSeconds]) / filtered size ] ].
×
446

×
447
        res := res reject: #isNil.
×
448

×
449
        res
×
450
                ifEmpty: [ avg := nil ]
×
451
                ifNotEmpty: [ avg := res values average asFloat ].
×
452

×
453

×
454
        ^ {
×
455
                  (#avgDelay -> avg).
×
456
                  (#overEach -> aDateWeekMonthOrYear name).
×
457
                  (#forOver -> (groupedByDate keys size printString
×
458
                    , aDateWeekMonthOrYear printString)).
×
459
                  (#details -> groupedByDate) } asDictionary
×
460
]
×
461

462
{ #category : #churn }
463
GitMetric4User >> delayUntilFirstChurnSince: since until: until overA: aDateWeekMonthOrYear [
×
464

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

×
473
        'GitMetric4User: delay until first churn' recordInfo.
×
474

×
475
        groupedByDate := self
×
476
                                 setupGroupedDateFrom: since
×
477
                                 to: until
×
478
                                 over: aDateWeekMonthOrYear.
×
479

×
480
        commits := self
×
481
                           loadCommitsFromProjectsIds: itsProjects keys
×
482
                           since: since
×
483
                           until: until.
×
484

×
485
        "class commit by dates, filter none user commits"
×
486
        commits do: [ :commit |
×
487
                commit commitCreator = user ifTrue: [
×
488
                        | overDate |
×
489
                        overDate := self
×
490
                                            transformDate: commit created_at
×
491
                                            to: aDateWeekMonthOrYear.
×
492

×
493
                        groupedByDate
×
494
                                at: overDate printString
×
495
                                ifPresent: [ :arrayOfCommits | arrayOfCommits add: commit ]
×
496
                                ifAbsentPut: [
×
497
                                        OrderedCollection new
×
498
                                                add: commit;
×
499
                                                yourself ] ] ].
×
500

×
501

×
502

×
503
        res := groupedByDate collect: [ :commits4Date |
×
504
                       | durationFromA2B |
×
505
                       commits4Date collect: [ :commitA |
×
506
                               | commitB |
×
507
                               commitB := GitAnalyzer new
×
508
                                                  glhImporter: glhImporter;
×
509
                                                  onModel: glhModel;
×
510
                                                  fromCommit: commitA;
×
511
                                                  maxChildCommit: 5;
×
512
                                                  analyseDelayUntilFirstChurn.
×
513

×
514
                               durationFromA2B := commitB
×
515
                                                          ifNil: [ 0 ]
×
516
                                                          ifNotNil: [
×
517
                                                          commitB created_at - commitA created_at ].
×
518
                               durationFromA2B ] ].
×
519

×
520

×
521

×
522
        res := res collect: [ :durationsByDate |
×
523
                       | filtered |
×
524
                       filtered := durationsByDate reject: [ :value | value = 0 ].
×
525
                       filtered isEmpty
×
526
                               ifTrue: [ nil ]
×
527
                               ifFalse: [
×
528
                               (filtered sum: [ :v | v asDuration ]) / filtered size ] ].
×
529

×
530
        res := res reject: #isNil.
×
531

×
532
        res
×
533
                ifEmpty: [ avg := nil ]
×
534
                ifNotEmpty: [ avg := res values sum / res keys size ].
×
535

×
536

×
537
        ^ {
×
538
                  (#avgDelay -> avg).
×
539
                  (#overEach -> aDateWeekMonthOrYear name).
×
540
                  (#forOver -> (groupedByDate keys size printString
×
541
                    , aDateWeekMonthOrYear printString)).
×
542
                  (#details -> groupedByDate) } asDictionary
×
543
]
×
544

545
{ #category : #churn }
546
GitMetric4User >> foundSuccessorOf: userCommits andCompleteImportForMax: commitLimit [
×
547

×
548
        | analyzingCommits i size|
×
549
        analyzingCommits := Set new.
×
550
        glhImporter withCommitDiffs: true.
×
551

×
552
        userCommits do: [ :c |
×
553
                gitAnalyzer
×
554
                        visitChildCommits: c childCommits
×
555
                        toStoreThemIn: analyzingCommits
×
556
                        upto: commitLimit ].
×
557

×
558
        i := 0.
×
559
        size := analyzingCommits size. 
×
560
        analyzingCommits do: [ :c |
×
561
                ('import complete commits  [' , (i:=i+1) printString, '/', size printString , ']'  ) recordInfo.
×
562
                glhImporter completeImportedCommit: c ].
×
563

×
564
        ^ analyzingCommits
×
565
]
×
566

567
{ #category : #'as yet unclassified' }
568
GitMetric4User >> generateAnalysisForPeriod: period over: over withMaxCommitWindows: maxCommitWindow [
×
569

×
NEW
570
        | contribution codeAddition codeDeletion commitFrequency commentContribution mergeRequestDuration codeChurn delayUntilFirstChurn averageTimeBetweenCommits averageTimeBetweenCommits |
×
571
        
×
572
        contribution := self
×
573
                                codeContributionsSince: (period at: #since)
×
574
                                until: (period at: #until)
×
575
                                overA: over.
×
576
        codeAddition := contribution at: #avgAddition.
×
577
        codeDeletion := contribution at: #avgDeletion.
×
578

×
579
        commitFrequency := (self
×
580
                                    commitFrequencySince: (period at: #since)
×
581
                                    until: (period at: #until)
×
582
                                    overA: over) at: #averageFloat.
×
583

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

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

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

×
602
        delayUntilFirstChurn := (self
×
603
                                         delayUntilFirstChurnSince:
×
604
                                         (period at: #since)
×
605
                                         until: (period at: #until)
×
606
                                         onACommitWindowOf: maxCommitWindow
×
607
                                         overA: over) at: #avgDelay.
×
608
                
×
NEW
609
        numberOfProjectWithCommit := self numberOfProjectWithCommitSince: (period at: #since) until: (period at: #until) overA: over.        
×
610
        averageTimeBetweenCommits := (self averageTimeBetweenCommitSince: (period at: #since) until: (period at: #until) over: over) at: #average.
×
611

×
612
        ^ AnalysisReport new
×
613
                  username: self user name;
×
614
                  period: period;
×
615
                  codeAddition: codeAddition;
×
616
                  codeDeletion: codeDeletion;
×
617
                  commitFrequency: commitFrequency;
×
618
                  commentContribution: commentContribution;
×
619
                  mergeRequestDuration: mergeRequestDuration;
×
620
                  codeChurn: codeChurn;
×
621
                  delayUntilFirstChurn: delayUntilFirstChurn;
×
NEW
622
                numberOfProjectWithCommit: (numberOfProjectWithCommit at: #average);
×
623
                  averageTimeBetweenCommits: averageTimeBetweenCommits.
×
624
]
×
625

626
{ #category : #initialization }
627
GitMetric4User >> initialize [
×
628

×
629
        user := GLHUser new.
×
630
        itsProjects := Dictionary new.
×
631
        itsCommits := Dictionary new.
×
632
        itsMergeRequests := Dictionary new
×
633
]
×
634

635
{ #category : #accessing }
636
GitMetric4User >> itsProjects: projects [
×
637
        itsProjects := projects .
×
638
]
×
639

640
{ #category : #churn }
641
GitMetric4User >> loadCommitOfProjects: aCollection since: aTimespan [
×
642
        |commits|
×
643
        
×
644
        commits := (aCollection collect: [ :id |
×
645
                 glhImporter
×
646
                        importCommitsOProject: (itsProjects at: id)
×
647
                        since: aTimespan
×
648
                        until: nil ]) flattened.
×
649

×
650
        commits do: [ :commit |
×
651
                glhImporter completeImportedCommit: commit. 
×
652
                 ].
×
653

×
654
        ^ self userCommits.
×
655
]
×
656

657
{ #category : #metrics }
658
GitMetric4User >> mergeRequestDurationSince: since until: until overA: aDateWeekMonthOrYear [
×
659

×
660
        | mergeRequest res groupedByDate filterGroups avg |
×
661
        groupedByDate := self
×
662
                                 setupGroupedDateFrom: since
×
663
                                 to: until
×
664
                                 over: aDateWeekMonthOrYear.
×
665

×
666
        gitAnalyzer := GitAnalyzer new
×
667
                               glhImporter: glhImporter;
×
668
                               onModel: glhModel.
×
669

×
670
        glhImporter withCommitDiffs: false.
×
671
        mergeRequest := self
×
672
                                loadMergeRequestsFromProjectsIds: itsProjects keys
×
673
                                since: since
×
674
                                until: until.
×
675
        glhImporter withCommitDiffs: true.
×
676

×
677
        mergeRequest ifEmpty: [
×
678
                ^ {
×
679
                          (#avgDuration -> nil).
×
680
                          (#overEach -> aDateWeekMonthOrYear name).
×
681
                          (#forOver -> (groupedByDate keys size printString
×
682
                            , aDateWeekMonthOrYear printString)).
×
683
                          (#totalMergeRequest -> 0).
×
684
                          (#details -> nil) } asDictionary ].
×
685

×
686
        res := mergeRequest collect: [ :mr |
×
687
                       gitAnalyzer analyseMergeResquestValidation: mr ].
×
688

×
689

×
690
        res do: [ :dic |
×
691
                | overDate |
×
692
                overDate := self
×
693
                                    transformDate: (dic at: #created_at)
×
694
                                    to: aDateWeekMonthOrYear.
×
695

×
696
                groupedByDate
×
697
                        at: overDate printString
×
698
                        ifPresent: [ :durations | durations add: (dic at: #duration) ]
×
699
                        ifAbsentPut: [
×
700
                                OrderedCollection new
×
701
                                        add: (dic at: #duration);
×
702
                                        yourself ] ].
×
703

×
704

×
705
        filterGroups := groupedByDate reject: [ :array | array isEmpty ].
×
706

×
707
        filterGroups associations do: [ :assoc |
×
708
                | sum denominator |
×
709
                denominator := assoc value size.
×
710

×
711
                sum := assoc value sum: [ :v |
×
712
                               v ifNil: [
×
713
                                       denominator := denominator - 1.
×
714
                                       0 asDuration ] ].
×
715
                denominator = 0 ifTrue: [ denominator := 1 ].
×
716

×
717
                filterGroups at: assoc key put: sum / denominator ].
×
718

×
719

×
720
        filterGroups keys
×
721
                ifEmpty: [ avg := 0 ]
×
722
                ifNotEmpty: [
×
723
                avg := filterGroups values sum / filterGroups keys size ].
×
724

×
725

×
726
        ^ {
×
727
                  (#avgDuration -> avg).
×
728
                  (#overEach -> aDateWeekMonthOrYear name).
×
729
                  (#forOver -> (groupedByDate keys size printString
×
730
                    , aDateWeekMonthOrYear printString)).
×
731
                  (#totalMergeRequest -> mergeRequest size).
×
732
                  (#details -> groupedByDate) } asDictionary
×
733
]
×
734

735
{ #category : #metrics }
NEW
736
GitMetric4User >> numberOfProjectWithCommitSince: since until: until overA: aDateWeekMonthOrYear [
×
NEW
737
        | groupedByDate commits userCommits dateOver projects |
×
NEW
738
        groupedByDate := self
×
NEW
739
                                 setupGroupedDateFrom: since
×
NEW
740
                                 to: until
×
NEW
741
                                 over: aDateWeekMonthOrYear.
×
NEW
742
                
×
NEW
743
        gitAnalyzer := GitAnalyzer new
×
NEW
744
                               onModel: glhModel;
×
NEW
745
                               glhImporter: glhImporter.
×
NEW
746

×
NEW
747
        glhImporter withCommitDiffs: false.
×
NEW
748
        commits := self
×
NEW
749
                           loadCommitsFromProjectsIds: itsProjects keys
×
NEW
750
                           since: since
×
NEW
751
                           until: until.
×
NEW
752
        glhImporter withCommitDiffs: true.
×
NEW
753
        userCommits := commits reject: [ :commit | commit commitCreator ~= user ].
×
NEW
754
        
×
NEW
755

×
NEW
756
        userCommits do: [ :userCommit |
×
NEW
757
                 dateOver := self
×
NEW
758
                                    transformDate: userCommit committed_date 
×
NEW
759
                                    to: aDateWeekMonthOrYear.
×
NEW
760
                        
×
NEW
761
                groupedByDate at: dateOver printString ifPresent: [ :value | value add: (userCommit repository project) ].
×
NEW
762
        ].
×
NEW
763

×
NEW
764
        groupedByDate := groupedByDate collect: [ :group |                 
×
NEW
765
                projects := Set newFrom: group.                
×
NEW
766
                projects size.
×
NEW
767
        ].
×
NEW
768

×
NEW
769
        ^ {
×
NEW
770
                  (#overEach -> aDateWeekMonthOrYear name).
×
NEW
771
                  (#forOver -> (groupedByDate keys size printString
×
NEW
772
                    , aDateWeekMonthOrYear printString)).
×
NEW
773
                  (#average
×
NEW
774
                   ->
×
NEW
775
                   groupedByDate average asFloat).
×
NEW
776
                  (#details -> groupedByDate).
×
NEW
777
                  (#userCommits -> commits size) } asDictionary
×
NEW
778

×
NEW
779
]
×
780

781
{ #category : #accessing }
782
GitMetric4User >> user [
×
783
        ^ user
×
784
]
×
785

786
{ #category : #accessing }
787
GitMetric4User >> user: anUser [
×
788
        user := anUser. 
×
789
]
×
790

791
{ #category : #accessing }
792
GitMetric4User >> userCommits [
×
793
        ^ user commits
×
794
]
×
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