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

moosetechnology / GitProjectHealth / 12691758925

09 Jan 2025 02:19PM UTC coverage: 61.247% (+2.0%) from 59.199%
12691758925

Pull #114

github

web-flow
Merge 43f172566 into ad6480d24
Pull Request #114: refactor: replace GLHApi and GLPHApi with Gitlab Pharo API

286 of 506 new or added lines in 15 files covered. (56.52%)

120 existing lines in 3 files now uncovered.

9516 of 15537 relevant lines covered (61.25%)

0.61 hits per line

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

45.28
/src/GitLabHealth-Model-Importer/GLHModelImporter.class.st
1
Class {
2
        #name : #GLHModelImporter,
3
        #superclass : #GPModelImporter,
4
        #instVars : [
5
                'withInitialCommits',
6
                'withInitialMergeRequest',
7
                'generalReader'
8
        ],
9
        #category : #'GitLabHealth-Model-Importer'
10
}
11

12
{ #category : #'private - api' }
13
GLHModelImporter >> addCommits: commitsList toRepository: aProjectRepository [
×
14
        "I take a list of GLHCommit. But some might have been parsed but are already on the model..."
×
15

×
16
        "I return the list of added commits"
×
17

×
18
        | existingCommits newlyFoundCommit |
×
19
        existingCommits := aProjectRepository mooseModel allWithType:
×
20
                                   GLHCommit.
×
21
        newlyFoundCommit := commitsList reject: [ :commitParsed |
×
22
                                    existingCommits anySatisfy: [ :existingCommit |
×
23
                                            existingCommit id = commitParsed id ] ].
×
24
        aProjectRepository mooseModel addAll: newlyFoundCommit.
×
25
        aProjectRepository commits addAll: newlyFoundCommit.
×
26
        ^ newlyFoundCommit
×
27
]
×
28

29
{ #category : #private }
30
GLHModelImporter >> addGroupResultToModel: groupResult [
1✔
31
        |group|
1✔
32
        group := self glhModel add: groupResult unless: self blockOnIdEquality.
1✔
33
        self glhModel
1✔
34
                addAll: group projects
1✔
35
                unless: self blockOnIdEquality.
1✔
36
        ^ group 
1✔
37
]
1✔
38

39
{ #category : #'as yet unclassified' }
40
GLHModelImporter >> chainsCommitsFrom: commitsCollection [
1✔
41

1✔
42
        | dic |
1✔
43
        
1✔
44
        ('Chains ', commitsCollection size printString , ' commits') recordInfo.
1✔
45
        
1✔
46
        dic := ((self glhModel allWithType: GLHCommit) collect: [ :commit |
1✔
47
                        commit id -> commit ]) asSet asDictionary.
1✔
48

1✔
49
        commitsCollection do: [ :commit |
1✔
50
                commit parent_ids do: [ :parentId | 
1✔
51
                        dic
1✔
52
                                at: parentId
1✔
53
                                ifPresent: [ :parentCommit |
1✔
54
                                        parentCommit childCommits
1✔
55
                                                add: commit
1✔
56
                                                unless: self blockOnIdEquality ]
1✔
57
                                ifAbsent: [  ] ] ].
1✔
58
        ^ commitsCollection
1✔
59
]
1✔
60

61
{ #category : #'private - api' }
62
GLHModelImporter >> completeImportProject: aGLHProject [
1✔
63

1✔
64
        | importedProject |
1✔
65
        ('Complete import of project: ' , aGLHProject id printString)
1✔
66
                recordInfo.
1✔
67
        aGLHProject repository ifNotNil: [ ^ aGLHProject ].
1✔
68

1✔
69
        importedProject := self glhModel
1✔
70
                                   add: aGLHProject
1✔
71
                                   unless: self blockOnIdEquality.
1✔
72

1✔
73
        self importPipelinesOfProject: importedProject.
1✔
74

1✔
75
        "aGLHProject creator: (self importUser: aGLHProject creator_id)."
1✔
76

1✔
77
        (self importUser: importedProject creator_id) addCreatedProject:
1✔
78
                importedProject.
1✔
79

1✔
80

1✔
81
        importedProject repository: GLHRepository new.
1✔
82
        self glhModel add: importedProject repository.
1✔
83
        self importRepository: importedProject repository.
1✔
84

1✔
85
        ^ importedProject
1✔
86
]
1✔
87

88
{ #category : #'as yet unclassified' }
89
GLHModelImporter >> completeImportedCommit: aCommit [
1✔
90

1✔
91
        ('completing commit: ' , aCommit short_id printString) recordInfo.
1✔
92
        self importCreatorOfCommit: aCommit.
1✔
93

1✔
94
        self withCommitDiffs ifTrue: [
1✔
95
                | diffs |
1✔
96
                aCommit diffs ifEmpty: [
1✔
97
                        diffs := self importDiffOfCommit: aCommit.
1✔
98
                        self glhModel addAll: diffs unless: self blockForDiffEquality ] ].
1✔
99

1✔
100
        ^ aCommit
1✔
101
]
1✔
102

103
{ #category : #'private - configure reader' }
104
GLHModelImporter >> configureReaderForCommit: reader [
1✔
105

1✔
106
          reader for: GLHCommit do: [ :mapping |
1✔
107
                mapping mapInstVars:
1✔
108
                        #( id short_id title author_name author_email committer_name
1✔
109
                           committer_email message web_url ).
1✔
110
                (mapping mapInstVar: #authored_date) valueSchema: DateAndTime.
1✔
111
                (mapping mapInstVar: #committed_date) valueSchema: DateAndTime.
1✔
112
                (mapping mapInstVar: #created_at) valueSchema: DateAndTime.
1✔
113
                (mapping mapInstVar: #parent_ids) valueSchema: #ArrayOfIds.
1✔
114
                mapping
1✔
115
                        mapProperty: 'stats'
1✔
116
                        getter: [ :el | "Not used" ]
1✔
117
                        setter: [ :commit :value |
1✔
118
                                commit deletions: (value at: #deletions).
1✔
119
                                commit additions: (value at: #additions) ] ].
1✔
120

1✔
121
        reader for: DateAndTime customDo: [ :mapping |
1✔
122
                mapping decoder: [ :string | DateAndTime fromString: string ] ].
1✔
123

1✔
124
        reader
1✔
125
                for: #ArrayOfIds
1✔
126
                customDo: [ :mapping | mapping decoder: [ :string | string ] ].
1✔
127
  
1✔
128
        reader
1✔
129
                for: #ArrayOfCommit
1✔
130
                customDo: [ :customMappting |
1✔
131
                customMappting listOfElementSchema: GLHCommit ].
1✔
132

1✔
133
]
1✔
134

135
{ #category : #'private - configure reader' }
136
GLHModelImporter >> configureReaderForDiffs: reader [
1✔
137

1✔
138
        reader for: GLHDiff do: [ :mapping |
1✔
139
                mapping mapInstVars:
1✔
140
                        #( deleted_file new_file new_path old_path renamed_file ).
1✔
141
                mapping mapInstVar: #diffString to: #diff ].
1✔
142

1✔
143
        reader
1✔
144
                for: #ArrayOfDiffs
1✔
145
                customDo: [ :customMappting |
1✔
146
                customMappting listOfElementSchema: GLHDiff ].
1✔
147
        ^ reader
1✔
148
]
1✔
149

150
{ #category : #'private - configure reader' }
151
GLHModelImporter >> configureReaderForGroup: reader [
1✔
152

1✔
153
        reader for: GLHGroup do: [ :mapping |
1✔
154
                mapping mapInstVars.
1✔
155
                (mapping mapInstVar: #projects) valueSchema: #ArrayOfProjects ].
1✔
156
        reader mapInstVarsFor: GLHProject.
1✔
157
        reader
1✔
158
                for: #ArrayOfProjects
1✔
159
                customDo: [ :customMappting |
1✔
160
                customMappting listOfElementSchema: GLHProject ].
1✔
161
        reader
1✔
162
                for: #ArrayOfGroups
1✔
163
                customDo: [ :customMappting |
1✔
164
                customMappting listOfElementSchema: GLHGroup ]
1✔
165
]
1✔
166

167
{ #category : #private }
168
GLHModelImporter >> convertApiFileAsFile: aAPIFile [
×
169

×
170
        aAPIFile type = 'tree' ifTrue: [ 
×
171
                ^ GLHFileDirectory new
×
172
                          name: aAPIFile name;
×
173
                          yourself ].
×
174
        ^ GLHFileBlob new
×
175
                  name: aAPIFile name;
×
176
                  yourself
×
177
]
×
178

179
{ #category : #'as yet unclassified' }
180
GLHModelImporter >> detectEntityType: aType overAttribut: aSelector equalTo: value [
1✔
181

1✔
182
        ^ (self glhModel allWithType: aType) detect: [ :entity |
1✔
183
                  (entity perform: aSelector) = value ] ifNone: [ nil ]. 
1✔
184
]
1✔
185

186
{ #category : #accessing }
187
GLHModelImporter >> glhApi [
×
188

×
189
        self
×
190
                deprecated: 'Use #repoApi instead'
×
191
                on: '7 October 2024'
×
192
                in:
×
193
                'Pharo-11.0.0+build.726.sha.aece1b5473acf3830a0e082c1bc3a15d4ff3522b (64 Bit)'.
×
194

×
195
        ^ repoApi
×
196
]
×
197

198
{ #category : #accessing }
199
GLHModelImporter >> glhApi: anObject [
×
200

×
201
        self
×
202
                deprecated: 'Use #repoApi: instead'
×
203
                on: '7 October 2024'
×
204
                in:
×
205
                'Pharo-11.0.0+build.726.sha.aece1b5473acf3830a0e082c1bc3a15d4ff3522b (64 Bit)'.
×
206

×
207
        repoApi := anObject
×
208
]
×
209

210
{ #category : #accessing }
211
GLHModelImporter >> glhModel [
1✔
212

1✔
213
        ^ glhModel
1✔
214
]
1✔
215

216
{ #category : #accessing }
217
GLHModelImporter >> glhModel: anObject [
1✔
218

1✔
219
        glhModel := anObject
1✔
220
]
1✔
221

222
{ #category : #users }
223
GLHModelImporter >> importActiveHumanUsers [
×
224

×
NEW
225
        | params result users |
×
NEW
226
        params := { 
×
NEW
227
                #humans -> 'true'.
×
NEW
228
                #active -> 'true'.
×
NEW
229
                #without_project_bots -> 'true'
×
NEW
230
        } asDictionary.
×
NEW
231
        result := self repoApi users allWithParams: params.
×
NEW
232
        users := (result collect: [ :usersJson | self parseUsersResult: usersJson ]) flattened.
×
NEW
233
        
×
NEW
234
        self glhModel
×
NEW
235
                                 addAll: users
×
NEW
236
                                 unless: self blockOnIdEquality.
×
237

×
NEW
238
        ^ users
×
239
]
×
240

241
{ #category : #api }
242
GLHModelImporter >> importAllGroups [
×
243

×
NEW
244
        | params results groups |
×
NEW
245
        
×
NEW
246
        params := { 
×
NEW
247
                        #top_level_only -> 'true'
×
NEW
248
        } asDictionary.
×
NEW
249
        results := self repoApi groups getAllWithParams: params.
×
NEW
250
        
×
NEW
251
        groups := (results collect: [ :groupsJson | generalReader
×
NEW
252
                                            on: groupsJson readStream;
×
NEW
253
                                            nextAs: #ArrayOfGroups. ]) flattened.
×
NEW
254
        ^ groups
×
UNCOV
255
]
×
256

257
{ #category : #'as yet unclassified' }
258
GLHModelImporter >> importAndLoadLatestsCommitsOfProject: aGLHProject [
×
259

×
NEW
260
        | commits |
×
NEW
261
        self completeImportProject: aGLHProject.
×
NEW
262
        commits := self importLastestCommitsOfProject: aGLHProject.
×
263
        commits do: [ :commit | self completeImportedCommit: commit ].
×
264
        self chainsCommitsFrom: commits.
×
265
        ^ commits
×
266
]
×
267

268
{ #category : #commits }
269
GLHModelImporter >> importCommit: aCommitID ofProject: aGLHProject [
×
270

×
271
        | result parsedResult |
×
272
        (self glhModel allWithType: GLHCommit) asOrderedCollection
×
273
                detect: [ :commit | commit id = aCommitID ]
×
274
                ifFound: [ :commit | ^ commit ].
×
NEW
275
        result := self repoApi commits get: aCommitID inProject: aGLHProject id.
×
NEW
276
        
×
277
        parsedResult := self parseCommitResult: result.
×
NEW
278
        
×
279
        self
×
280
                addCommits: { parsedResult }
×
281
                toRepository: aGLHProject repository.
×
282
        ^ parsedResult
×
283
]
×
284

285
{ #category : #commits }
286
GLHModelImporter >> importCommitOfProject: anProject withId: anID [
1✔
287

1✔
288
        | commit result |
1✔
289
        anID ifNil: [ ^ nil ].
1✔
290

1✔
291
        ('looking for commit ' , anID printString , ' in project : '
1✔
292
         , anProject id printString) recordInfo.
1✔
293

1✔
294
        commit := (self
1✔
295
                           detectEntityType: GLHCommit
1✔
296
                           overAttribut: #id
1✔
297
                           equalTo: anID) ifNil: [
1✔
298
                          result := self repoApi commits get: anID inProject: anProject id.
1✔
299
                          commit := (self parseCommitsResult: '[' , result , ']')
1✔
300
                                            first.
1✔
301

1✔
302
                          self glhModel add: commit unless: self blockOnIdEquality.
1✔
303
                          commit repository: anProject repository.
1✔
304

1✔
305
                          commit ].
1✔
306

1✔
307
        self withCommitDiffs ifTrue: [ self importDiffOfCommit: commit ].
1✔
308

1✔
309
        ^ commit
1✔
310
]
1✔
311

312
{ #category : #commits }
313
GLHModelImporter >> importCommits: aGLHProject [
×
314
        "limited to the last 20 commits"
×
315

×
NEW
316
        | results parsedResults params |
×
NEW
317
        params := { 
×
NEW
318
         #with_stats -> 'true'
×
NEW
319
        } asDictionary.
×
NEW
320
        results := self repoApi commits getByPage: 1 perPage: 20 inProject: aGLHProject id withParams: params.
×
NEW
321
        
×
322
        parsedResults := self parseCommitsResult: results.
×
323
        self glhModel addAll: parsedResults unless: self blockOnIdEquality.
×
324

×
325
        parsedResults do: [ :commit |
×
326
                commit repository: aGLHProject repository ].
×
327

×
328
        self withCommitDiffs ifTrue: [
×
329
                parsedResults do: [ :commit | self importDiffOfCommit: commit ] ].
×
330
        
×
331
        ^ parsedResults. 
×
332
]
×
333

334
{ #category : #'as yet unclassified' }
335
GLHModelImporter >> importCommitsFollowing: aCommit upToDays: aNumberOfDay [
×
336
        "import the 'n' commits of a project starting from an initial 'aCommit' commit. 
×
337
        Lazy import does not import the entities inside the model"
×
338

×
339
        | date |
×
340
        date := aCommit created_at asDateAndTime.
×
341

×
342
        ^ self
×
343
                  importCommitsOfBranch: aCommit branch
×
344
                  forRefName: aCommit branch name
×
345
                  since: date
×
346
                  until: (date + aNumberOfDay day)
×
347
]
×
348

349
{ #category : #commit }
350
GLHModelImporter >> importCommitsOfBranch: aGLHBranch forRefName: refName since: fromDate [
×
351

×
352
        ^ self
×
353
                  importCommitsOfBranch: aGLHBranch
×
354
                  forRefName: aGLHBranch name
×
355
                  since: fromDate
×
356
                  until: nil
×
357
]
×
358

359
{ #category : #commits }
360
GLHModelImporter >> importCommitsOfBranch: aGLHBranch forRefName: refName since: fromDate until: toDate [
×
361

×
NEW
362
        | params result allCommits |
×
NEW
363
        params := { 
×
NEW
364
          #ref_name -> aGLHBranch name.
×
NEW
365
          #since ->  (fromDate ifNotNil: [ fromDate asDateAndTime asString ] ifNil: [ '' ]).
×
NEW
366
          #until -> (toDate ifNotNil: [ toDate asDateAndTime asString ] ifNil: [ '' ]). 
×
NEW
367
        } asDictionary.
×
NEW
368
        result := self repoApi commits getAllInProject: aGLHBranch repository project id withParams: params.
×
NEW
369
        
×
NEW
370
        allCommits := (result collect: [ :commitsJson | self parseCommitsResult: commitsJson ]) flattened.
×
NEW
371
        
×
372
        aGLHBranch commits
×
NEW
373
                        addAll: allCommits
×
374
                        unless: self blockOnIdEquality.
×
375

×
376
        self glhModel
×
377
                addAll: aGLHBranch commits
×
378
                unless: self blockOnIdEquality.
×
379

×
NEW
380
        ^ allCommits
×
381
]
×
382

383
{ #category : #commit }
384
GLHModelImporter >> importCommitsOfBranch: aGLHBranch forRefName: refName until: toDate [
×
385

×
386
        ^ self
×
387
                  importCommitsOfBranch: aGLHBranch
×
388
                  forRefName: aGLHBranch name
×
389
                  since: nil
×
390
                  until: toDate
×
391
]
×
392

393
{ #category : #commits }
394
GLHModelImporter >> importCommitsOfProject: aProject since: fromDate until: toDate [
1✔
395

1✔
396
        | params results allCommits |
1✔
397
        params := { 
1✔
398
                #since -> (fromDate ifNotNil: [ fromDate asDateAndTime asString ] ifNil: ['']).
1✔
399
                #until -> (toDate ifNotNil: [ toDate asDateAndTime asString ] ifNil: ['']).
1✔
400
                #with_stats -> 'true'.
1✔
401
                #all -> 'true'
1✔
402
        } asDictionary.
1✔
403
        results := self repoApi commits getAllInProject: aProject id withParams: params.
1✔
404
        
1✔
405
        allCommits := (results collect: [ :commitsJson | self parseCommitsResult: commitsJson ]) flattened.
1✔
406
        
1✔
407
        (aProject repository commits) addAll: allCommits unless: self blockOnIdEquality.
1✔
408

1✔
409
        ^ self glhModel addAll: allCommits unless: self blockOnIdEquality
1✔
410
]
1✔
411

412
{ #category : #projects }
NEW
413
GLHModelImporter >> importContributedProjectsOfUser: aGLHUser [
×
NEW
414

×
NEW
415
        | remaningProjects params results projects |
×
NEW
416
        params := { 
×
NEW
417
                #order_by -> 'last_activity_at'.
×
NEW
418
                #simple -> 'true'.
×
NEW
419
        } asDictionary.
×
NEW
420
        results := self repoApi projects contributedProjectsOfUser: aGLHUser id withParams: params.
×
NEW
421
        
×
NEW
422
        projects := (results collect: [ :projectsJson | self parseArrayOfProject: projectsJson ]) flattened.
×
NEW
423
        
×
NEW
424
        self glhModel
×
425
                                 addAll: projects
×
426
                                 unless: self blockOnIdEquality.                                
×
NEW
427
        
×
NEW
428
        remaningProjects := self importProjects:
×
NEW
429
                                    ((projects collect: #id) difference:
×
NEW
430
                                             ((self userCatalogue atId: aGLHUser id) at:
×
NEW
431
                                                      #contributedProjects)).
×
NEW
432

×
NEW
433
        aGLHUser contributedProjects
×
NEW
434
                addAll: projects , remaningProjects
×
NEW
435
                unless: self blockOnIdEquality.
×
NEW
436

×
NEW
437
        self userCatalogue
×
NEW
438
                addUser: aGLHUser
×
NEW
439
                withProjects: (aGLHUser contributedProjects collect: #id).
×
NEW
440

×
441
        ^ projects
×
NEW
442
]
×
443

444
{ #category : #commits }
445
GLHModelImporter >> importCreatorOfCommit: aCommit [
1✔
446

1✔
447
        aCommit commitCreator ifNil: [
1✔
448
                aCommit commitCreator:
1✔
449
                        (self importUserByUsername: aCommit author_name) ].
1✔
450
        self userCatalogue
1✔
451
                addUser: aCommit commitCreator
1✔
452
                withProject: aCommit repository project id.
1✔
453
        ^ aCommit commitCreator
1✔
454
]
1✔
455

456
{ #category : #api }
457
GLHModelImporter >> importDiffOfCommit: aCommit [
1✔
458

1✔
459
        | result diffsResult |
1✔
460
        aCommit diffs ifNotEmpty: [
1✔
461
                'Diff already importer: ' , aCommit short_id printString recordInfo.
1✔
462
                ^ aCommit diffs ].
1✔
463
        ('Import diff of commit: ' , aCommit short_id printString) recordInfo.
1✔
464
        
1✔
465
        result := self repoApi commits diffOf: aCommit id inProject: aCommit repository project id  uniDiff: true.
1✔
466
        
1✔
467
        (self isServerError: result) ifTrue: [ ^ {  } ].
1✔
468
        diffsResult := self newParseDiffResult: result.
1✔
469

1✔
470
        ^ aCommit diffs addAll: diffsResult unless: self blockForDiffEquality.
1✔
471

1✔
472
]
1✔
473

474
{ #category : #'private - api' }
UNCOV
475
GLHModelImporter >> importDirectoryFiles: aDirectoryFile OfBranch: aBranch [
×
UNCOV
476

×
UNCOV
477
        | result files apiFiles params |
×
NEW
478
        params := { 
×
NEW
479
                #ref -> aBranch name.
×
NEW
480
                #path -> (aDirectoryFile path , '/')
×
UNCOV
481
        } asDictionary.
×
UNCOV
482
        result := self repoApi repositories repositoryTreeOfProject: aBranch repository project id withParams: params.
×
UNCOV
483
                         " treeOfRepository: aBranch repository project id
×
UNCOV
484
                          ofBranch: aBranch name
×
UNCOV
485
                          andPath: aDirectoryFile path , '/'."
×
UNCOV
486
        apiFiles := (result collect: [ :treeJson | self parseFileTreeResult: treeJson ]) flattened.
×
UNCOV
487
        files := apiFiles collect: [ :apiFile |
×
NEW
488
                         self convertApiFileAsFile: apiFile ].
×
489
        
×
490
        files do: [ :file |
×
NEW
491
                self glhModel add: file.
×
NEW
492
                aDirectoryFile addFile: file ].
×
NEW
493
        
×
NEW
494
        files
×
NEW
495
                select: [ :file | file isKindOf: GLHFileDirectory ]
×
NEW
496
                thenCollect: [ :file |
×
NEW
497
                self importDirectoryFiles: file OfBranch: aBranch ]
×
498
]
×
499

500
{ #category : #'private - api' }
501
GLHModelImporter >> importFilesOfBranch: aBranch [
×
502

×
NEW
503
        | result files apiFiles params |
×
504
        params := { 
×
505
                #ref -> aBranch name.
×
506
        } asDictionary.
×
NEW
507
        
×
508
        result := self repoApi repositories repositoryTreeOfProject: aBranch repository project id withParams: params.
×
509
        
×
510
                          "treeOfRepository: aBranch repository project id
×
511
                          ofBranch: aBranch name
×
512
                          andPath: nil."
×
UNCOV
513
        apiFiles := (result collect: [ :filesJson | self parseFileTreeResult: filesJson  ]) flattened.
×
NEW
514
        files := apiFiles collect: [ :apiFile | 
×
515
                         self convertApiFileAsFile: apiFile ].
×
516
        files do: [ :file | 
×
NEW
517
                self glhModel add: file.
×
NEW
518
                aBranch addFile: file ].
×
NEW
519
        files
×
NEW
520
                select: [ :file | file isKindOf: GLHFileDirectory ]
×
NEW
521
                thenCollect: [ :file | 
×
NEW
522
                self importDirectoryFiles: file OfBranch: aBranch ]
×
NEW
523
]
×
524

525
{ #category : #api }
526
GLHModelImporter >> importGroup: aGroupID [
1✔
527

1✔
528
        | result groupResult |
1✔
529
        ('Import group: ' , aGroupID printString) recordInfo.
1✔
530

1✔
531
        result := self repoApi groups get: aGroupID.
1✔
532
        
1✔
533
        "group: aGroupID."
1✔
534
        groupResult := self parseGroupResult: result.
1✔
535
        groupResult := self addGroupResultToModel: groupResult.
1✔
536

1✔
537
        groupResult projects do: [ :project |
1✔
538
                self completeImportProject: project ].
1✔
539

1✔
540
        (self subGroupsOf: aGroupID) do: [ :subGroup |
1✔
541
                
1✔
542
                groupResult subGroups
1✔
543
                        add: (self importGroup: subGroup id)
1✔
544
                        unless: self blockOnIdEquality ].
1✔
545
        ^ groupResult
1✔
546
]
1✔
547

548
{ #category : #api }
UNCOV
549
GLHModelImporter >> importJobsOf: aPipeline [
×
UNCOV
550

×
UNCOV
551
        | jobs results |
×
UNCOV
552
        results := self repoApi jobs allForPipeline: aPipeline id inProject: aPipeline project id.
×
UNCOV
553
                          "jobsOfProject: aPipeline project id
×
UNCOV
554
                          ofPipelines: aPipeline id."
×
UNCOV
555
        jobs := (results collect: [ :jobsJson | self parseJobsResult: jobsJson ofProject: aPipeline project ]) flattened.
×
UNCOV
556
        jobs do: [ :job | aPipeline addJob: job ].
×
UNCOV
557
        self glhModel addAll: jobs.
×
UNCOV
558
        
×
UNCOV
559
        ^jobs
×
UNCOV
560

×
UNCOV
561
]
×
562

563
{ #category : #commits }
564
GLHModelImporter >> importLastestCommitsOfProject: aGLHProject [
1✔
565
        "limited to the last 50 commits"
1✔
566

1✔
567
        | results parsedResults params |
1✔
568
        params := { 
1✔
569
                #with_stats -> 'true'.
1✔
570
                #all -> true
1✔
571
         } asDictionary.
1✔
572
        results := self repoApi commits getByPage: 1 perPage: 50 inProject: aGLHProject id withParams: params.
1✔
573

1✔
574
        parsedResults := self parseCommitsResult: results.
1✔
575
        parsedResults := self glhModel
1✔
576
                                 addAll: parsedResults
1✔
577
                                 unless: self blockOnIdEquality.
1✔
578

1✔
579
        aGLHProject repository commits
1✔
580
                addAll: parsedResults
1✔
581
                unless: self blockOnIdEquality.
1✔
582

1✔
583
        self withCommitDiffs ifTrue: [
1✔
584
                parsedResults do: [ :commit | self importDiffOfCommit: commit ] ].
1✔
585

1✔
586
        ^ parsedResults
1✔
587
]
1✔
588

589
{ #category : #commit }
UNCOV
590
GLHModelImporter >> importParentCommitsOfCommit: aGLHCommit since: aDate [
×
UNCOV
591

×
UNCOV
592
        | parentsIds commits |
×
UNCOV
593
        commits := OrderedCollection new.
×
UNCOV
594
        aGLHCommit created_at asDateAndTime < aDate asDateAndTime ifTrue: [
×
UNCOV
595
                 
×
UNCOV
596
                ^ commits
×
UNCOV
597
                          add: aGLHCommit;
×
UNCOV
598
                          yourself ].
×
UNCOV
599

×
UNCOV
600
        parentsIds := aGLHCommit parent_ids.
×
UNCOV
601

×
UNCOV
602
        commits addAll: (parentsIds collect: [ :id |
×
NEW
603
                         self
×
604
                                 importCommitOfProject: aGLHCommit repository project
×
605
                                 withId: id ]).
×
606

×
607

×
608
        ^ (commits collect: [ :parentCommit |
×
609
                   self importParentCommitsOfCommit: parentCommit since: aDate ])
×
610
                  flatten
×
611
]
×
612

613
{ #category : #'private - api' }
614
GLHModelImporter >> importPipelinesOfProject: aGLHProject [
1✔
615

1✔
616
        (self pipelinesOf: aGLHProject id) do: [ :pipeline |
1✔
617
                self glhModel add: pipeline unless: self blockOnIdEquality .
1✔
618
                aGLHProject pipelines add: pipeline unless: self blockOnIdEquality]
1✔
619
]
1✔
620

621
{ #category : #projects }
622
GLHModelImporter >> importProject: aProjectID [
×
623

×
624
        | result projectResult |
×
625
        ('Import project with id: ' , aProjectID printString) recordInfo.
×
UNCOV
626

×
NEW
627
        result := self repoApi projects get: aProjectID.
×
UNCOV
628
        projectResult := self parseProjectResult: result.
×
UNCOV
629

×
UNCOV
630
        ^ self completeImportProject: projectResult
×
UNCOV
631
]
×
632

633
{ #category : #imports }
UNCOV
634
GLHModelImporter >> importProjects [
×
NEW
635

×
636
        | result projects |
×
637
        ('import all Projects') recordInfo.
×
638

×
639
        result := self repoApi projects all.
×
640
        projects := (result collect: [ :projectsJson | self parseArrayOfProject: projectsJson ]) flattened.
×
NEW
641
        
×
642
        self glhModel addAll: projects unless: self blockOnIdEquality.
×
643

×
644
        ^ projects
×
645
]
×
646

647
{ #category : #projects }
648
GLHModelImporter >> importProjects: aCollectionOfProjectID [
×
649

×
NEW
650
        ^ aCollectionOfProjectID collect: [ :id | self importProject: id ]
×
NEW
651
]
×
652

653
{ #category : #repository }
654
GLHModelImporter >> importRepository: aGLHRepository [
1✔
655

1✔
656
        | resultBranches branches |
1✔
657
        [
1✔
658
        ('import the repository of project ' , aGLHRepository project name)
1✔
659
                recordInfo.
1✔
660

1✔
661
        resultBranches := self repoApi branches getAllFromProject: aGLHRepository project id.
1✔
662
        
1✔
663
        branches := (resultBranches collect: [ :branchesJson | self parseBranchesResult: branchesJson ]) flattened.
1✔
664

1✔
665
        'import the branches of project ' recordInfo.
1✔
666

1✔
667
        branches := aGLHRepository branches
1✔
668
                            addAll: branches
1✔
669
                            unless: self blockOnNameEquality.
1✔
670
        branches := self glhModel
1✔
671
                            addAll: branches
1✔
672
                            unless: self blockOnNameEquality.
1✔
673

1✔
674

1✔
675
        self withFiles ifTrue: [
1✔
676
                branches do: [ :branch | self importFilesOfBranch: branch ] ] ]
1✔
677
                on: NeoJSONParseError
1✔
678
                do: [
1✔
679
                self inform: aGLHRepository project name , ' has no repository' ]
1✔
680
]
1✔
681

682
{ #category : #'private - api' }
683
GLHModelImporter >> importUser: aUserID [
1✔
684

1✔
685
        | result userResult |
1✔
686
        (self glhModel allWithType: GLHUser)
1✔
687
                detect: [ :user | user id = aUserID ]
1✔
688
                ifFound: [ :user | ^ user ].
1✔
689
        ('Import user: ' , aUserID printString) recordInfo.
1✔
690
        
1✔
691
        result := self repoApi users get: aUserID.
1✔
692
        userResult := self parseUserResult: result.
1✔
693
        
1✔
694
        ^ self glhModel add: userResult unless: self blockOnIdEquality
1✔
695
]
1✔
696

697
{ #category : #user }
698
GLHModelImporter >> importUserByUsername: anUsername [
1✔
699

1✔
700
        | dicUsername resultUser |
1✔
701
        dicUsername := ((self glhModel allWithType: GLHUser) collect: [ :user |
1✔
702
                                user username -> user ]) asSet asDictionary.
1✔
703

1✔
704
        dicUsername addAll: self userCatalogue collectUsernames.
1✔
705

1✔
706

1✔
707
        resultUser := dicUsername
1✔
708
                              at: anUsername
1✔
709
                              ifAbsent: [ "thus we have to import this new user"
1✔
710
                                      | result userId searchResult params |
1✔
711
                                      ('Import user with username: '
1✔
712
                                       , anUsername printString) recordInfo.
1✔
713
                                      params := { (#search -> anUsername) } asDictionary.
1✔
714
                                      result := self repoApi users allWithParams: params.
1✔
715
                                                        
1✔
716
                                                         "when result is an error"
1✔
717
                                                         result isArray ifFalse: [ result := { result } ].
1✔
718
                                                        
1✔
719
                                      searchResult :=  (result collect: [ :usersJson |
1✔
720
                                                               NeoJSONReader fromString: usersJson ])
1✔
721
                                                              first.
1✔
722

1✔
723
                                      (searchResult class = Dictionary and: [
1✔
724
                                               (searchResult at: #message) includesSubstring:
1✔
725
                                                       '403 Forbidden' ])
1✔
726
                                              ifTrue: [ "if the result is an 403 error we fake a new user"
1✔
727
                                                      self glhModel
1✔
728
                                                              add: (GLHUser new
1✔
729
                                                                               username: anUsername;
1✔
730
                                                                               name: anUsername;
1✔
731
                                                                               yourself)
1✔
732
                                                              unless: [ :nu :ou | nu username = ou username ] ]
1✔
733
                                              ifFalse: [
1✔
734
                                                      searchResult
1✔
735
                                                              ifEmpty: [ "results can be empty thus we force a new user with the info we have "
1✔
736
                                                                      self glhModel
1✔
737
                                                                              add: (GLHUser new
1✔
738
                                                                                               username: anUsername;
1✔
739
                                                                                               name: anUsername;
1✔
740
                                                                                               yourself)
1✔
741
                                                                              unless: [ :nu :ou | nu username = ou username ] ]
1✔
742
                                                              ifNotEmpty: [ "because we may already have the researched user, we look by ID in the model"
1✔
743
                                                                      userId := searchResult first at: #id.
1✔
744
                                                                      (self glhModel allWithType: GLHUser)
1✔
745
                                                                              detect: [ :user | user id = userId ]
1✔
746
                                                                              ifNone: [ self importUser: userId ] ] ] ].
1✔
747

1✔
748
        self userCatalogue addUser: resultUser withName: anUsername.
1✔
749

1✔
750
        ^ resultUser
1✔
751
]
1✔
752

753
{ #category : #initialization }
754
GLHModelImporter >> initReader [
1✔
755

1✔
756
        generalReader := NeoJSONReader new.
1✔
757
        self configureReaderForCommit: generalReader.
1✔
758
        self configureReaderForGroup: generalReader.
1✔
759
        self configureReaderForDiffs: generalReader. 
1✔
760
]
1✔
761

762
{ #category : #initialization }
763
GLHModelImporter >> initialize [
1✔
764

1✔
765
        super initialize.
1✔
766
        withCommitDiffs := false.
1✔
767
        withInitialCommits := false.
1✔
768
        withInitialMergeRequest := false.
1✔
769

1✔
770
        withCommitsSince := (Date today - 1 week) asDateAndTime.
1✔
771

1✔
772
        self initReader.
1✔
773

1✔
774
]
1✔
775

776
{ #category : #api }
777
GLHModelImporter >> isServerError: aString [
1✔
778
        ^ aString = '{"message":"500 Internal Server Error"}'
1✔
779
]
1✔
780

781
{ #category : #importer }
UNCOV
782
GLHModelImporter >> loadAllProjectsFromRepositorySoftware [
×
UNCOV
783
        "heavy import that load all the active project inside the model. Only import the project entities"
×
UNCOV
784
        |projects|
×
UNCOV
785
        
×
UNCOV
786
        projects := self repoApi projects. 
×
UNCOV
787
]
×
788

789
{ #category : #private }
UNCOV
790
GLHModelImporter >> newParseCommitResult: result [
×
UNCOV
791

×
UNCOV
792
        generalReader  on: result readStream.
×
UNCOV
793

×
NEW
794
        ^ generalReader nextAs: GLHCommit
×
795
]
×
796

797
{ #category : #private }
798
GLHModelImporter >> newParseDiffResult: result [
1✔
799

1✔
800
        generalReader on: result readStream.
1✔
801
        ^ generalReader nextAs: #ArrayOfDiffs
1✔
802
]
1✔
803

804
{ #category : #parsing }
805
GLHModelImporter >> parseArrayOfProject: arrayOfProjects [
×
806

×
807
        | reader |
×
808
        reader := NeoJSONReader on: arrayOfProjects readStream.
×
UNCOV
809
        reader
×
NEW
810
                for: #ArrayOfProjects
×
UNCOV
811
                customDo: [ :customMappting |
×
UNCOV
812
                customMappting listOfElementSchema: GLHProject ].
×
UNCOV
813
        reader for: GLHProject do: [ :mapping |
×
UNCOV
814
                mapping mapInstVar: #name to: #name.
×
UNCOV
815
                mapping mapInstVar: #description to: #description.
×
UNCOV
816
                mapping mapInstVar: #id to: #id.
×
NEW
817
                mapping mapInstVar: #archived to: #archived.
×
818
                mapping mapInstVar: #web_url to: #html_url.
×
819
                mapping mapInstVar: #topics to: #topics ].
×
820
        ^ reader nextAs: #ArrayOfProjects
×
821
]
×
822

823
{ #category : #private }
824
GLHModelImporter >> parseBranchesResult: result [
1✔
825

1✔
826
        | reader |
1✔
827
        reader := NeoJSONReader on: result readStream.
1✔
828
        reader mapInstVarsFor: GLHBranch.
1✔
829
        reader
1✔
830
                for: #ArrayOfBranch
1✔
831
                customDo: [ :customMappting | 
1✔
832
                customMappting listOfElementSchema: GLHBranch ].
1✔
833
        ^ reader nextAs: #ArrayOfBranch
1✔
834
]
1✔
835

836
{ #category : #private }
UNCOV
837
GLHModelImporter >> parseCommitResult: result [
×
UNCOV
838

×
UNCOV
839
        | reader |
×
UNCOV
840
        reader := NeoJSONReader on: result readStream.
×
UNCOV
841

×
UNCOV
842
        reader for: GLHCommit do: [ :mapping |
×
UNCOV
843
                mapping mapInstVars:
×
UNCOV
844
                        #( id short_id title author_name author_email committer_name
×
UNCOV
845
                           committer_email message web_url ).
×
UNCOV
846
                (mapping mapInstVar: #authored_date) valueSchema: DateAndTime.
×
UNCOV
847
                (mapping mapInstVar: #committed_date) valueSchema: DateAndTime.
×
UNCOV
848
                (mapping mapInstVar: #created_at) valueSchema: DateAndTime.
×
NEW
849
                (mapping mapInstVar: #parent_ids) valueSchema: #ArrayOfIds.
×
850
                mapping
×
851
                        mapProperty: 'stats'
×
852
                        getter: [ :el | "Not used" ]
×
853
                        setter: [ :commit :value |
×
854
                                commit deletions: (value at: #deletions).
×
855
                                commit additions: (value at: #additions) ] ].
×
856

×
857
        reader for: DateAndTime customDo: [ :mapping |
×
858
                mapping decoder: [ :string | DateAndTime fromString: string ] ].
×
859

×
860
        reader
×
861
                for: #ArrayOfIds
×
862
                customDo: [ :mapping | mapping decoder: [ :string | string ] ].
×
863

×
864

×
865
        ^ reader nextAs: GLHCommit
×
866
]
×
867

868
{ #category : #private }
869
GLHModelImporter >> parseCommitsResult: result [
1✔
870

1✔
871
        | reader |
1✔
872
        reader := NeoJSONReader on: result readStream.
1✔
873

1✔
874
          reader for: GLHCommit do: [ :mapping |
1✔
875
                mapping mapInstVars:
1✔
876
                        #( id short_id title author_name author_email committer_name
1✔
877
                           committer_email message web_url ).
1✔
878
                (mapping mapInstVar: #authored_date) valueSchema: DateAndTime.
1✔
879
                (mapping mapInstVar: #committed_date) valueSchema: DateAndTime.
1✔
880
                (mapping mapInstVar: #created_at) valueSchema: DateAndTime.
1✔
881
                (mapping mapInstVar: #parent_ids) valueSchema: #ArrayOfIds.
1✔
882
                mapping
1✔
883
                        mapProperty: 'stats'
1✔
884
                        getter: [ :el | "Not used" ]
1✔
885
                        setter: [ :commit :value |
1✔
886
                                commit deletions: (value at: #deletions).
1✔
887
                                commit additions: (value at: #additions) ] ].
1✔
888

1✔
889
        reader for: DateAndTime customDo: [ :mapping |
1✔
890
                mapping decoder: [ :string | DateAndTime fromString: string ] ].
1✔
891

1✔
892
        reader
1✔
893
                for: #ArrayOfIds
1✔
894
                customDo: [ :mapping | mapping decoder: [ :string | string ] ].
1✔
895
  
1✔
896
        reader
1✔
897
                for: #ArrayOfCommit
1✔
898
                customDo: [ :customMappting |
1✔
899
                customMappting listOfElementSchema: GLHCommit ].
1✔
900

1✔
901
        ^ reader nextAs: #ArrayOfCommit
1✔
902
]
1✔
903

904
{ #category : #private }
UNCOV
905
GLHModelImporter >> parseDiffResult: result [
×
UNCOV
906

×
UNCOV
907
        | reader |
×
UNCOV
908
        self
×
UNCOV
909
                deprecated: 'Use #newParseDiffResult: instead'
×
UNCOV
910
                on: '28 June 2024'
×
UNCOV
911
                in:
×
UNCOV
912
                'Pharo-11.0.0+build.726.sha.aece1b5473acf3830a0e082c1bc3a15d4ff3522b (64 Bit)'.
×
UNCOV
913
        reader := NeoJSONReader on: result readStream.
×
UNCOV
914
        reader for: GLHDiff do: [ :mapping |
×
UNCOV
915
                mapping mapInstVars:
×
UNCOV
916
                        #( deleted_file new_file new_path old_path renamed_file ).
×
NEW
917
                mapping mapInstVar: #diffString to: #diff ].
×
918

×
919
        reader
×
920
                for: #ArrayOfDiffs
×
921
                customDo: [ :customMappting |
×
922
                customMappting listOfElementSchema: GLHDiff ].
×
923
        ^ reader nextAs: #ArrayOfDiffs
×
924
]
×
925

926
{ #category : #private }
927
GLHModelImporter >> parseFileTreeResult: aResult [
×
928

×
929
        | reader |
×
930
        reader := NeoJSONReader on: aResult readStream.
×
931
        reader mapInstVarsFor: GLHApiFile.
×
932
        reader
×
933
                for: #ArrayOfFile
×
934
                customDo: [ :customMappting | 
×
935
                customMappting listOfElementSchema: GLHApiFile ].
×
936
        ^ reader nextAs: #ArrayOfFile
×
937
]
×
938

939
{ #category : #private }
940
GLHModelImporter >> parseGroupResult: aResult [
1✔
941

1✔
942
        | reader |
1✔
943

1✔
944
        reader := NeoJSONReader on: aResult readStream.
1✔
945
        reader for: GLHGroup do: [ :mapping |
1✔
946
                mapping mapInstVars.
1✔
947
                (mapping mapInstVar: #projects) valueSchema: #ArrayOfProjects ].
1✔
948
        reader mapInstVarsFor: GLHProject.
1✔
949
        reader
1✔
950
                for: #ArrayOfProjects
1✔
951
                customDo: [ :customMappting |
1✔
952
                customMappting listOfElementSchema: GLHProject ].
1✔
953
        ^ reader nextAs: GLHGroup
1✔
954
]
1✔
955

956
{ #category : #private }
UNCOV
957
GLHModelImporter >> parseJobsResult: result ofProject: aProject [
×
UNCOV
958

×
UNCOV
959
        | reader |
×
UNCOV
960
        reader := NeoJSONReader on: result readStream.
×
UNCOV
961
        reader for: GLHJob do: [ :mapping |
×
UNCOV
962
                mapping mapInstVars: #( id allow_failure web_url name ).
×
UNCOV
963

×
UNCOV
964
                mapping
×
UNCOV
965
                        mapProperty: #user
×
UNCOV
966
                        getter: [ :object | #ignore ]
×
UNCOV
967
                        setter: [ :object :value |
×
UNCOV
968
                        object user: (self importUser: (value at: #id)) ].
×
NEW
969

×
970
                mapping
×
971
                        mapProperty: #commit
×
972
                        getter: [ :object | #ignore ]
×
973
                        setter: [ :object :value |
×
974
                                value ifNotNil: [
×
975
                                        object commit:
×
976
                                                (self importCommit: (value at: #id) ofProject: aProject) ] ].
×
977

×
978
                mapping
×
979
                        mapProperty: #duration
×
980
                        getter: [ :object | #ignore ]
×
981
                        setter: [ :object :value |
×
982
                        value ifNotNil: [ object duration: value seconds ] ] ].
×
983

×
984
        reader
×
985
                for: #ArrayOfGLHJob
×
986
                customDo: [ :customMappting |
×
987
                customMappting listOfElementSchema: GLHJob ].
×
988
        ^ reader nextAs: #ArrayOfGLHJob
×
989
]
×
990

991
{ #category : #private }
992
GLHModelImporter >> parsePipelinesResult: result [
×
993

×
994
        | reader |
×
995
        
×
996
        (result includesSubstring: '{"message":"40' )ifTrue: [ ^ {  } ].
×
997
        
×
998
        reader := NeoJSONReader on: result readStream.
×
999
        reader mapInstVarsFor: GLHPipeline.
×
1000
        reader for: GLHPipeline do: [ :mapping |
×
1001
                mapping
×
1002
                        mapProperty: #created_at
×
UNCOV
1003
                        getter: [ :object | #ignore ]
×
NEW
1004
                        setter: [ :object :value |
×
UNCOV
1005
                        object runDate: (DateAndTime fromString: value) ] ].
×
UNCOV
1006
        reader
×
UNCOV
1007
                for: #ArrayOfPipelines
×
UNCOV
1008
                customDo: [ :customMappting |
×
UNCOV
1009
                customMappting listOfElementSchema: GLHPipeline ].
×
UNCOV
1010
        ^ reader nextAs: #ArrayOfPipelines
×
UNCOV
1011
]
×
1012

1013
{ #category : #parsing }
UNCOV
1014
GLHModelImporter >> parseProjectResult: aResult [ 
×
UNCOV
1015
                | reader |
×
UNCOV
1016
        reader := NeoJSONReader on: aResult readStream.
×
UNCOV
1017
        reader for: GLHProject do: [ :mapping |
×
UNCOV
1018
                mapping mapInstVars. ].
×
UNCOV
1019
"        reader mapInstVarsFor: GLHProject."
×
UNCOV
1020

×
UNCOV
1021
        ^ reader nextAs: GLHProject
×
UNCOV
1022
]
×
UNCOV
1023

×
UNCOV
1024
{ #category : #private }
×
UNCOV
1025
GLHModelImporter >> parseSubGroupResult: aResult [
×
NEW
1026

×
1027
        | reader |
×
1028
        reader := NeoJSONReader on: aResult readStream.
×
1029
        self configureReaderForGroup: reader.
×
1030
        ^ reader nextAs: #ArrayOfGroups
×
1031
]
×
1032

×
1033
{ #category : #private }
×
1034
GLHModelImporter >> parseUserResult: result [
×
1035

×
1036
        | reader |
×
NEW
1037
        reader := NeoJSONReader on: result readStream.
×
1038
        reader mapInstVarsFor: GLHUser.
×
1039
        ^ reader nextAs: GLHUser
×
1040
]
×
1041

×
1042
{ #category : #private }
×
1043
GLHModelImporter >> parseUsersResult: result [
×
1044

×
1045
        | reader |
×
NEW
1046
        reader := NeoJSONReader on: result readStream.
×
1047

×
1048
        reader mapInstVarsFor: GLHUser.
×
1049

×
1050
        reader
×
1051
                for: #ArrayOfUser
×
1052
                customDo: [ :customMappting |
×
1053
                customMappting listOfElementSchema: GLHUser ].
×
1054

×
NEW
1055
        ^ reader nextAs: #ArrayOfUser
×
1056
]
×
1057

×
1058
{ #category : #'private - api' }
×
1059
GLHModelImporter >> pipelinesOf: aProjectID [
×
1060

×
1061
        | result |
×
1062
        ('Search pipelines of: ' , aProjectID printString) recordInfo.
×
1063
        result := self repoApi pipelines getAllInProject: aProjectID.
×
1064
        "pipelinesOfProject: aProjectID."
×
1065
        ^ (result collect: [ :pipelinesJson | self parsePipelinesResult: pipelinesJson ]) flattened
×
1066
]
×
1067

×
1068
{ #category : #'as yet unclassified' }
×
1069
GLHModelImporter >> selectEntityType: aType overAttribut: aSelector equalTo: value [
×
1070

×
NEW
1071
        ^ (self glhModel allWithType: aType)
×
1072
                select: [ :entity | (entity perform: aSelector) = value ]
×
1073
]
×
1074

×
1075
{ #category : #'private - api' }
×
NEW
1076
GLHModelImporter >> subGroupsOf: aGroupID [
×
NEW
1077

×
NEW
1078
        | results subgroups |
×
1079
        ('Search subgroup of: ' , aGroupID printString) recordInfo.
×
1080
        results := self repoApi groups subgroupsOf: aGroupID.
×
NEW
1081
        subgroups := (results collect: [ :subgroupsJson | self parseSubGroupResult: subgroupsJson ]) flattened.
×
1082
        
×
1083
        ^ subgroups
×
1084
]
×
1085

×
1086
{ #category : #accessing }
×
1087
GLHModelImporter >> withInitialCommits: boolean [
×
NEW
1088
        withInitialCommits := boolean 
×
1089
]
×
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