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

moosetechnology / GitProjectHealth / 10918907131

18 Sep 2024 08:57AM UTC coverage: 20.103% (-0.2%) from 20.328%
10918907131

push

github

web-flow
Merge pull request #61 from moosetechnology/feat-jira-time-vs-merge-request-time

feat: add jira time and merge request time difference metric

0 of 207 new or added lines in 11 files covered. (0.0%)

4 existing lines in 2 files now uncovered.

1961 of 9755 relevant lines covered (20.1%)

0.2 hits per line

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

0.0
/src/GitLabHealth-Model-Analysis/GitMetricExporter.class.st
1
Class {
2
        #name : #GitMetricExporter,
3
        #superclass : #Object,
4
        #instVars : [
5
                'glhImporter',
6
                'jiraImporter',
7
                'label',
8
                'entities',
9
                'projectCache',
10
                'sinceTimeLimit',
11
                'runningPeriods',
12
                'maxCommitWindow',
13
                'over',
14
                'emailDomain',
15
                'metrics',
16
                'analyses'
17
        ],
18
        #category : #'GitLabHealth-Model-Analysis'
19
}
20

21
{ #category : #'as yet unclassified' }
22
GitMetricExporter class >> demoPeriod [
×
23

×
24
        ^ self new
×
25
                  addAPeriodFrom: '01 march 2023' to: '31 may 2023';
×
26
                  addAPeriodFrom: '01 december 2023' to: '29 february 2024';
×
27
                  addAPeriodFrom: '01 march 2024' to: '31 may 2024'
×
28
]
×
29

30
{ #category : #adding }
31
GitMetricExporter >> addAPeriodFrom: since to: until [
×
32

×
33
        runningPeriods add: {
×
34
                        (#since -> since asDate).
×
35
                        (#until -> until asDate) } asDictionary.
×
36
        
×
37
        ^runningPeriods 
×
38
]
×
39

40
{ #category : #adding }
41
GitMetricExporter >> addEntitiesFromUserNames: userNames [
×
42
        "import all the project since a certain time"
×
43
        
×
44
        self
×
45
                deprecated: 'Use #setupAnalysesForUsersWithNames instead'
×
46
                on: '03 Sept 2024'
×
47
                in:
×
48
                'Pharo-11.0.0+build.726.sha.aece1b5473acf3830a0e082c1bc3a15d4ff3522b (64 Bit)'.
×
49

×
50
        'Import all projects from the Git repository' recordInfo.
×
51
        projectCache := projectCache ifNil: [
×
52
                                glhImporter importProjectsSince: sinceTimeLimit ].
×
53

×
54
        "then collect the project in which the user has be seen commited"
×
55
        entities addAll: (userNames collect: [ :username |
×
56
                         | projects  i size |
×
57
                         projects := self
×
58
                                             findParticipationOfCommitAuthorNamed: username
×
59
                                             amongProjects: projectCache.
×
60

×
61
                        "metrics := GitMetric4User new.
×
62
                         metrics
×
63
                                 glhImporter: glhImporter;
×
64
                                 jiraImporter: jiraImporter;
×
65
                                 findUserNamed: username."
×
66

×
67

×
68

×
69
                         i := 0.
×
70
                         size := projects size.
×
71
                         metrics itsProjects: (projects collect: [ :p |
×
72
                                          (' ' join: {
×
73
                                                           'complete import of project:'.
×
74
                                                           p name printString.
×
75
                                                           '['.
×
76
                                                           (i := i + 1) printString.
×
77
                                                           '/'.
×
78
                                                           size.
×
79
                                                           ']' }) recordInfo.
×
80

×
81
                                          p id -> (glhImporter completeImportProject: p) ]) asDictionary.
×
82

×
83
                         metrics ]).
×
84

×
85
        ^ self
×
86
]
×
87

88
{ #category : #adding }
89
GitMetricExporter >> addEntitiesFromUserNamesAndProjects: usersWithProjects [
×
90

×
91
        self
×
92
                deprecated: 'Use #setupAnalysesForUsersWithNames instead'
×
93
                on: '03 Sept 2024'
×
94
                in:
×
95
                'Pharo-11.0.0+build.726.sha.aece1b5473acf3830a0e082c1bc3a15d4ff3522b (64 Bit)'.
×
96

×
97
        entities addAll: (usersWithProjects associations collect: [ :assoc |
×
98
                         | username projects  |
×
99
                         username := assoc key.
×
100
                         projects := assoc value.
×
101

×
102
                        " metrics := GitMetric4User new.
×
103
                         metrics
×
104
                                 glhImporter: glhImporter;
×
105
                                 jiraImporter: jiraImporter;
×
106
                                 findUserNamed: username.
×
107
                         metrics loadProjectsFromIds: projects."
×
108

×
109
                         username ]).
×
110

×
111
        ^ self 
×
112
]
×
113

114
{ #category : #utilities }
115
GitMetricExporter >> constructFilePath: runningOver [
×
116

×
117
        | file |
×
118
        file := (FileLocator home
×
119
                 /
×
120
                         ('GitlabHealth-' , label printString , '-' , runningOver printString
×
121
                          , '-'
×
122
                          , (DateAndTime now printString replaceAll: $: with: $-)
×
123
                          , '.csv')) asFileReference.
×
124
        ^ file
×
125
]
×
126

127
{ #category : #exporting }
128
GitMetricExporter >> csvMetricsFor: metricCollection at: date [
×
129

×
130
        | csvMetrics |
×
131
        csvMetrics := metricCollection collect: [ :metric |
×
132
                              metric new description , ' - ' , date asString
×
133
                              -> [ :groupAnalyses |
×
134
                                      | analysis |
×
135
                                      analysis := self
×
136
                                                          getAnalysisWithDate: date
×
137
                                                          from: groupAnalyses.
×
138
                                      analysis
×
139
                                              ifNil: [ nil ]
×
140
                                              ifNotNil: [ analysis metrics at: metric new name ] ] ].
×
141

×
142
        ^ csvMetrics asOrderedDictionary
×
143
]
×
144

145
{ #category : #accessing }
146
GitMetricExporter >> entities: aCollection [ 
×
147
        entities := aCollection
×
148
]
×
149

150
{ #category : #exporting }
151
GitMetricExporter >> exportFor: usersWithProjects [
×
152

×
153
        self
×
154
                deprecated: 'Use #exportInCSV instead'
×
155
                on: '03 Sept 2024'
×
156
                in:
×
157
                'Pharo-11.0.0+build.726.sha.aece1b5473acf3830a0e082c1bc3a15d4ff3522b (64 Bit)'.
×
158

×
159
        self exportFor: usersWithProjects over: {
×
160
                        Date.
×
161
                        Week.
×
162
                        Month.
×
163
                        Year }
×
164
]
×
165

166
{ #category : #exporting }
167
GitMetricExporter >> exportFor: usersWithProjects over: aCollectionOfDateWeekMonthOrYear [
×
168

×
169
        self
×
170
                deprecated: 'Use #exportInCSV instead'
×
171
                on: '03 Sept 2024'
×
172
                in:
×
173
                'Pharo-11.0.0+build.726.sha.aece1b5473acf3830a0e082c1bc3a15d4ff3522b (64 Bit)'.
×
174

×
175
        entities ifNil: [
×
176
                self addEntitiesFromUserNamesAndProjects: usersWithProjects ].
×
177

×
178
        self exportFor: aCollectionOfDateWeekMonthOrYear
×
179
]
×
180

181
{ #category : #exporting }
182
GitMetricExporter >> exportInCSV [
×
183

×
184
        self exportUserAnalysesInCSV.
×
185
        self exportProjectAnalysesInCSV.
×
186
]
×
187

188
{ #category : #exporting }
189
GitMetricExporter >> exportInDB: repository [
×
190

×
191
        repository enableSingleton.
×
192
        analyses do: [ :analysis | analysis save ]
×
193
]
×
194

195
{ #category : #exporting }
196
GitMetricExporter >> exportInS3: bucketName accessKey: accessKey secretKey: secretKey region: region [
×
197

×
198
        | s3 bucket ston date fileName |
×
199
        AWSS3Config default
×
200
                accessKeyId: accessKey;
×
201
                secretKey: secretKey;
×
202
                regionName: region.
×
203

×
204
        s3 := AWSS3 new.
×
205
        bucket := s3 bucketNamed: bucketName.
×
206

×
207
        ston := STON toString: analyses.
×
208

×
209
        date := Date today asString copyReplaceAll: ' ' asString with: '-'.
×
210
        fileName := ('-' join: {
×
211
                                     'analyse'.
×
212
                                     label.
×
213
                                     over asString.
×
214
                                     date }) , '.ston'.
×
215

×
216
        bucket atKey: fileName putObject: ston
×
217
]
×
218

219
{ #category : #exporting }
220
GitMetricExporter >> exportProjectAnalysesInCSV [
×
221

×
222
        | exportBrowserModel groupedByOver group groupOver groupByName periods csvMetrics file |
×
223
        exportBrowserModel := MiExportModel new.
×
224

×
225
        groupedByOver := self projectAnalyses groupedBy: #over.
×
226

×
227
        groupedByOver associations do: [ :groupAssociation |
×
228
                group := groupAssociation value.
×
229
                groupOver := groupAssociation key.
×
230

×
231

×
232
                groupByName := group groupedBy: #projectName.
×
233
                exportBrowserModel entitiesList: groupByName.
×
234

×
235
                exportBrowserModel removeColumnForQueryNamed: #Type.
×
236
                exportBrowserModel removeColumnForQueryNamed: #Name.
×
237

×
238
                exportBrowserModel
×
239
                        addColumnForQuery: [ :groupAnalyses |
×
240
                        (groupAnalyses at: 1) projectName ]
×
241
                        withName: #'Project name'.
×
242

×
243
                periods := (group groupedBy: #period) keys.
×
244

×
245
                periods do: [ :period |
×
246
                        csvMetrics := self
×
247
                                              csvMetricsFor: self projectMetrics
×
248
                                              at: (period at: #since).
×
249

×
250

×
251
                        csvMetrics associations do: [ :association |
×
252
                                exportBrowserModel
×
253
                                        addColumnForQuery: association value
×
254
                                        withName: association key ] ].
×
255

×
256
                file := self constructFilePath: groupOver.
×
257
                file writeStreamDo: [ :aStream |
×
NEW
258
                                                aStream
×
NEW
259
                                << 'sep=,';
×
NEW
260
                                << OSPlatform current lineEnding.
×
261
                        exportBrowserModel writeCSVOn: aStream ] ]
×
262
]
×
263

264
{ #category : #exporting }
265
GitMetricExporter >> exportUserAnalysesInCSV [
×
266

×
267
        | exportBrowserModel groupedByOver group groupOver groupByName periods csvMetrics file |
×
268
        exportBrowserModel := MiExportModel new.
×
269
        groupedByOver := self userAnalyses groupedBy: #over.
×
270
        
×
271
        groupedByOver associations do: [ :groupAssociation |
×
272
                group := groupAssociation value.
×
273
                groupOver := groupAssociation key.
×
NEW
274
                
×
275
                groupByName := group groupedBy: #username.
×
276
                exportBrowserModel entitiesList: groupByName.
×
277
                exportBrowserModel removeColumnForQueryNamed: #Type.
×
278
                exportBrowserModel removeColumnForQueryNamed: #Name.
×
NEW
279
                
×
280
                exportBrowserModel
×
281
                        addColumnForQuery: [ :groupAnalyses |
×
282
                        (groupAnalyses at: 1) username ]
×
283
                        withName: #'User name'.
×
NEW
284
                        
×
285
                periods := (group groupedBy: #period) keys.
×
286
                periods do: [ :period |
×
287
                        csvMetrics := self
×
288
                                              csvMetricsFor: self userMetrics
×
289
                                              at: (period at: #since).
×
290
                        csvMetrics associations do: [ :association |
×
291
                                exportBrowserModel
×
292
                                        addColumnForQuery: association value
×
293
                                        withName: association key ] ].
×
NEW
294
                        
×
NEW
295
                        
×
296
                file := self constructFilePath: groupOver.
×
NEW
297
                
×
298
                file writeStreamDo: [ :aStream |
×
NEW
299
                        aStream
×
NEW
300
                                << 'sep=,';
×
NEW
301
                                << OSPlatform current lineEnding.
×
302
                        exportBrowserModel writeCSVOn: aStream ] ]
×
303
]
×
304

305
{ #category : #projects }
306
GitMetricExporter >> findParticipationOfCommitAuthorNamed: username amongProjects: aCollectionOfProjects [
×
307

×
308
        | response itsProjects i size |
×
309
        i := 1.
×
310
        size := aCollectionOfProjects size.
×
311
        itsProjects := aCollectionOfProjects select: [ :project |
×
312
                               (' ' join: {
×
313
                                                'search'.
×
314
                                                username printString.
×
315
                                                'in Project:'.
×
316
                                                project name printString.
×
317
                                                '['.
×
318
                                                (i := i + 1) printString.
×
319
                                                '/'.
×
320
                                                size.
×
321
                                                ']' }) recordInfo.
×
322

×
323
                               response := glhImporter glhApi
×
324
                                                   commitsOfUser: username
×
325
                                                   inProject: project id
×
326
                                                   since: '01 january 2023' asDateAndTime
×
327
                                                   until: Date today asDateAndTime.
×
328
                               response := glhImporter parseCommitsResult: response.
×
329
                               response isNotEmpty
×
330
                 ].
×
331

×
332
        ^ itsProjects
×
333
]
×
334

335
{ #category : #projects }
336
GitMetricExporter >> findProjectsOfUser: aCollection [ 
×
337
        self shouldBeImplemented.
×
338
]
×
339

340
{ #category : #analysis }
341
GitMetricExporter >> generateAnalysesOver: aDateWeekMonthOrYear [
×
342

×
NEW
343
        analyses := OrderedCollection new.
×
344
        runningPeriods do: [ :period |
×
NEW
345
                analyses addAll: (self
×
NEW
346
                                 generateUsersAnalysesDuringPeriod: period
×
NEW
347
                                 over: aDateWeekMonthOrYear).
×
NEW
348

×
NEW
349
                analyses addAll: (self
×
NEW
350
                                 generateProjectsAnalysesDuringPeriod: period
×
NEW
351
                                 over: aDateWeekMonthOrYear) ].
×
352

×
NEW
353
        ^ analyses
×
354
]
×
355

356
{ #category : #analysis }
357
GitMetricExporter >> generateProjectsAnalysesDuringPeriod: period over: aDateWeekMonthOrYear [
×
358

×
359
        ^self projectEntities collect: [ :project |
×
360
                ProjectAnalysisReport new
×
361
                        projectName: project name;
×
362
                        period: period;
×
363
                        over: aDateWeekMonthOrYear ]
×
364
]
×
365

366
{ #category : #analysis }
367
GitMetricExporter >> generateUsersAnalysesDuringPeriod: period over: aDateWeekMonthOrYear [
×
368

×
369
        | userAnalysisReport newMetric result |
×
370
        ^ self userEntities collect: [ :user |
×
371
                  userAnalysisReport := UserAnalysisReport new
×
372
                                                username: user name;
×
373
                                                period: period;
×
374
                                                over: aDateWeekMonthOrYear.
×
375

×
376
                  metrics do: [ :metric |
×
377
                          newMetric := metric new
×
378
                                               glhImporter: glhImporter;
×
379
                                               jiraImporter: jiraImporter;
×
380
                                               setPeriodSince: (period at: #since)
×
381
                                               until: (period at: #until);
×
382
                                               over: aDateWeekMonthOrYear;
×
383
                                               user: user;
×
384
                                                                        emailDomain: emailDomain.
×
385

×
386

×
387
                          result := newMetric calculate.
×
388
                          userAnalysisReport metrics at: newMetric name put: result ].
×
389

×
390
                  userAnalysisReport ]
×
391
]
×
392

393
{ #category : #utilities }
394
GitMetricExporter >> getAnalysisWithDate: date from: analysisCollection [
×
395

×
396
        ^analysisCollection
×
397
                detect: [ :groupAnalysis | (groupAnalysis period at: #since) = date ]
×
398
                ifNone: [ nil ]
×
399
]
×
400

401
{ #category : #accessing }
402
GitMetricExporter >> glhImporter: anImporter [
×
403

×
404
        glhImporter := anImporter withInitialCommits: false; yourself. 
×
405
]
×
406

407
{ #category : #adding }
408
GitMetricExporter >> importAnalysesFromS3: bucketName accessKey: accessKey secretKey: secretKey region: region [
×
409

×
410
        | s3 bucket xmlObjects contentElements filesContent |
×
411
        AWSS3Config default
×
412
                accessKeyId: accessKey;
×
413
                secretKey: secretKey;
×
414
                regionName: region.
×
415

×
416
        s3 := AWSS3 new.
×
417
        bucket := s3 bucketNamed: bucketName.
×
418
        xmlObjects := bucket listObjects.
×
419
        contentElements := xmlObjects root elementsSelect: [ :element |
×
420
                                   element isNamed: 'Contents' ].
×
421

×
422
        filesContent := contentElements collect: [ :contentElement |
×
423
                                | keyValue |
×
424
                                keyValue := contentElement contentStringAt: 'Key'.
×
425
                                bucket getObject: keyValue ].
×
426

×
427
        ^ analyses := (filesContent collect: [ :file | STON fromString: file ])
×
428
                              flattened
×
429
]
×
430

431
{ #category : #initialization }
432
GitMetricExporter >> initialize [
×
433

×
434
        entities := OrderedCollection new.
×
435
        "set up the minimal date from which we are looking for the commits a particular user in projects"
×
436
        sinceTimeLimit := '2024-01-01' asDateAndTime.
×
437
        runningPeriods := OrderedCollection new.
×
438
        maxCommitWindow := 3.
×
439
        over := Date.
×
440

×
441
        analyses := OrderedCollection new.
×
442

×
443
        metrics := {
×
444
                           CodeAdditionMetric.
×
445
                           CodeDeletionMetric.
×
446
                           CommentContributionMetric.
×
447
                           CommitFrequencyMetric.
×
448
                           CodeChurnMetric.
×
449
                           DelayUntilFirstChurnMetric.
×
450
                           TimeBetweenCommitMetric.
×
451
                           ContributedProjectMetric.
×
452
                           MergeRequestDurationMetric.
×
453
                           OpenedMergeRequestMetric.
×
454
                           ClosedMergeRequestMetric.
×
455
                           MergedMergeRequestMetric.
×
456
                           SelfMergedUnderAMinuteMergeRequestMetric.
×
NEW
457
                           ClosedTicketsMetric. JiraTimeMRTimeDifferenceMetric }
×
458
]
×
459

460
{ #category : #accessing }
461
GitMetricExporter >> jiraImporter: anObject [
×
462

×
463
        jiraImporter := anObject
×
464
]
×
465

466
{ #category : #accessing }
467
GitMetricExporter >> label: aString [ 
×
468
        label := aString
×
469
]
×
470

471
{ #category : #accessing }
472
GitMetricExporter >> maxCommitWindow: anInteger [
×
473
        maxCommitWindow := anInteger abs
×
474
]
×
475

476
{ #category : #adding }
477
GitMetricExporter >> onlyImportProjectsOfGroup: groupId [
×
478

×
479
        | group |
×
480
        group := glhImporter importGroup: groupId.
×
481
        projectCache := group toScope: GLHProject
×
482
]
×
483

484
{ #category : #accessing }
485
GitMetricExporter >> projectAnalyses [
×
486

×
487
        ^ analyses select: [ :analysis | analysis class = ProjectAnalysisReport ]
×
488
]
×
489

490
{ #category : #accessing }
491
GitMetricExporter >> projectEntities [
×
492

×
493
        ^ entities select: [ :entity | entity class = GLHProject ]
×
494
]
×
495

496
{ #category : #accessing }
497
GitMetricExporter >> projectMetrics [
×
498

×
499
        ^ metrics select: [ :metric | metric inheritsFrom: ProjectMetric ]
×
500
]
×
501

502
{ #category : #setup }
503
GitMetricExporter >> setupAnalysisForProjectsWithIds: projectIds [
×
504

×
505
        | projects |
×
506
        projects := glhImporter importProjects: projectIds.
×
507

×
508
        entities addAll: projects
×
509
]
×
510

511
{ #category : #setup }
512
GitMetricExporter >> setupAnalysisForUsersWithNames: userNames [
×
513
        "import all the project since a certain time"
×
514

×
515
        | users |
×
516
        users := userNames collect: [ :username |
×
517
                         glhImporter importUserByUsername: username ].
×
518

×
519
        glhImporter userCatalogue scrapeAuthorNamesForUsers: users.
×
520
        
×
521
        users do: [ :user |
×
522
                |projects |
×
523
                projects := glhImporter importContributedProjectsOfUser: user.
×
524
                                projects do: [ :project |
×
525
                                glhImporter completeImportProject: project ].         
×
526
                
×
527
        ].
×
528

×
529
        entities addAll: users.
×
530

×
531
        ^ self
×
532
]
×
533

534
{ #category : #accessing }
535
GitMetricExporter >> userAnalyses [
×
536

×
537
        ^ analyses select: [ :analysis | analysis class = UserAnalysisReport ]
×
538
]
×
539

540
{ #category : #accessing }
541
GitMetricExporter >> userEntities [
×
542

×
543
        ^ entities select: [ :entity | entity class = GLHUser ]
×
544
]
×
545

546
{ #category : #accessing }
547
GitMetricExporter >> userMetrics [
×
548

×
549
        ^ metrics select: [ :metric | metric inheritsFrom: UserMetric ]
×
550
]
×
551

552
{ #category : #setup }
553
GitMetricExporter >> withEmailDomain: anEmailDomain [
×
554

×
555
        "define the email domain of your Git user. Usefull to link them between service (i.e. Jira)"
×
556
        emailDomain := anEmailDomain
×
557
]
×
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