From 91556503b6c919d6972f00f1dd5f8da12d4197f6 Mon Sep 17 00:00:00 2001 From: Kilian B <60846047+knowbased@users.noreply.github.com> Date: Tue, 21 Oct 2025 13:23:06 +0200 Subject: [PATCH 01/16] feat: create GLHNotePosition and add reader in Gitlab importer --- .../GitlabMergeRequestsMock.class.st | 5 + .../GitlabModelImporter.class.st | 58 +++++++++- src/GitLabHealth-Model/GLHNote.class.st | 15 ++- .../GLHNotePosition.class.st | 100 ++++++++++++++++++ .../GitModelImporter.class.st | 11 ++ 5 files changed, 184 insertions(+), 5 deletions(-) create mode 100644 src/GitLabHealth-Model/GLHNotePosition.class.st diff --git a/src/GitLabHealth-Model-Importer-Tests/GitlabMergeRequestsMock.class.st b/src/GitLabHealth-Model-Importer-Tests/GitlabMergeRequestsMock.class.st index 5158ec7b..ddafca61 100644 --- a/src/GitLabHealth-Model-Importer-Tests/GitlabMergeRequestsMock.class.st +++ b/src/GitLabHealth-Model-Importer-Tests/GitlabMergeRequestsMock.class.st @@ -180,6 +180,11 @@ GitlabMergeRequestsMock >> getAllOfProject: anUndefinedObject [ ]' } ] +{ #category : #api } +GitlabMergeRequestsMock >> getAllOfProject: project withParams: params [ + ^self getAllOfProject: project +] + { #category : #api } GitlabMergeRequestsMock >> getByPage: anInteger perPage: anInteger2 inProject: anUndefinedObject [ ^ '[ diff --git a/src/GitLabHealth-Model-Importer/GitlabModelImporter.class.st b/src/GitLabHealth-Model-Importer/GitlabModelImporter.class.st index a0006833..82381683 100644 --- a/src/GitLabHealth-Model-Importer/GitlabModelImporter.class.st +++ b/src/GitLabHealth-Model-Importer/GitlabModelImporter.class.st @@ -359,9 +359,58 @@ GitlabModelImporter >> configureReaderForNote: reader [ super configureReaderForNote: reader. reader for: GLHNote do: [ :mapping | - (mapping mapInstVar: #created_at) valueSchema: DateAndTime. - (mapping mapInstVar: #updated_at) valueSchema: DateAndTime ] + (mapping mapInstVar: #updated_at) valueSchema: DateAndTime. + + (mapping mapInstVar: #position) valueSchema: GLHNotePosition ] +] + +{ #category : #'private - configure reader' } +GitlabModelImporter >> configureReaderForNotePosition: reader [ + + super configureReaderForNotePosition: reader. + + reader for: GLHNotePosition do: [ :mapping | + mapping mapInstVar: #file_path to: #new_path. + mapping mapInstVar: #original_file_path to: #old_path. + + mapping + mapProperty: #new_line + getter: [ ] + setter: [ :notePosition :newLine | + notePosition start_line: newLine asString. + notePosition start_line_type: 'new' ]. + + mapping + mapProperty: #old_line + getter: [ ] + setter: [ :notePosition :oldLine | + notePosition start_line: oldLine asString. + notePosition start_line_type: 'old' ]. + + mapping + mapProperty: #line_range + getter: [ ] + setter: [ :notePosition :rawLineRange | + + rawLineRange ifNotNil: [ + | start startType startLine end endType endLine | + start := rawLineRange at: #start. + startType := start at: #type. + startLine := (start at: #type) = 'new' + ifTrue: [ start at: #new_line ] + ifFalse: [ start at: #old_line ]. + notePosition start_line_type: (start at: #type). + notePosition start_line: startLine. + + + end := rawLineRange at: #end. + endType := end at: #type. + endLine := (end at: #type) = 'new' + ifTrue: [ end at: #new_line ] + ifFalse: [ end at: #old_line ]. + notePosition end_line_type: (end at: #type). + notePosition end_line: endLine ] ] ] ] { #category : #'private - configure reader' } @@ -1333,7 +1382,7 @@ GitlabModelImporter >> importMergeRequestsOfProject: aGLHProject since: fromDate aGLHProject mergeRequests do: [ :mr | self importDiffOfMergeRequest: mr ] ]. - self glhModel + mergeRequests := self glhModel addAll: mergeRequests unless: (self blockEqualityOn: #iid). @@ -1926,6 +1975,7 @@ GitlabModelImporter >> parseNoteJson: results [ | reader | "Créer un lecteur JSON" + reader := generalReader on: results readStream. "Corriger la conversion des dates" @@ -1933,7 +1983,7 @@ GitlabModelImporter >> parseNoteJson: results [ mapping decoder: [ :string | DateAndTime readFrom: string readStream ] ]." - + ^ reader nextAs: #ArrayOfNote ] diff --git a/src/GitLabHealth-Model/GLHNote.class.st b/src/GitLabHealth-Model/GLHNote.class.st index 032e80fa..de2c0445 100644 --- a/src/GitLabHealth-Model/GLHNote.class.st +++ b/src/GitLabHealth-Model/GLHNote.class.st @@ -56,7 +56,8 @@ Class { '#internal => FMProperty', '#imported => FMProperty', '#imported_from => FMProperty', - '#mergeRequest => FMOne type: #GLHMergeRequest opposite: #note' + '#mergeRequest => FMOne type: #GLHMergeRequest opposite: #note', + '#position => FMOne type: #GLHNotePosition opposite: #note' ], #category : #'GitLabHealth-Model-Entities' } @@ -253,6 +254,18 @@ GLHNote >> noteable_type: anObject [ noteable_type := anObject ] +{ #category : #accessing } +GLHNote >> position [ + + ^ position +] + +{ #category : #accessing } +GLHNote >> position: anObject [ + + position := anObject +] + { #category : #accessing } GLHNote >> project_id [ diff --git a/src/GitLabHealth-Model/GLHNotePosition.class.st b/src/GitLabHealth-Model/GLHNotePosition.class.st new file mode 100644 index 00000000..22c09cfe --- /dev/null +++ b/src/GitLabHealth-Model/GLHNotePosition.class.st @@ -0,0 +1,100 @@ +Class { + #name : #GLHNotePosition, + #superclass : #GLHEntity, + #traits : 'FamixTNamedEntity', + #classTraits : 'FamixTNamedEntity classTrait', + #instVars : [ + '#file_path => FMProperty', + '#original_file_path => FMProperty', + '#start_line => FMProperty', + '#start_line_type => FMProperty', + '#end_line => FMProperty', + '#end_line_type => FMProperty', + '#note => FMOne type: #GLHNote opposite: #position' + ], + #category : #'GitLabHealth-Model-Entities' +} + +{ #category : #accessing } +GLHNotePosition >> end_line [ + + ^ end_line +] + +{ #category : #accessing } +GLHNotePosition >> end_line: anObject [ + + end_line := anObject +] + +{ #category : #accessing } +GLHNotePosition >> end_line_type [ + + ^ end_line_type +] + +{ #category : #accessing } +GLHNotePosition >> end_line_type: anObject [ + + end_line_type := anObject +] + +{ #category : #accessing } +GLHNotePosition >> file_path [ + + ^ file_path +] + +{ #category : #accessing } +GLHNotePosition >> file_path: anObject [ + + file_path := anObject +] + +{ #category : #accessing } +GLHNotePosition >> note [ + + ^ note +] + +{ #category : #accessing } +GLHNotePosition >> note: anObject [ + + note := anObject +] + +{ #category : #accessing } +GLHNotePosition >> original_file_path [ + + ^ original_file_path +] + +{ #category : #accessing } +GLHNotePosition >> original_file_path: anObject [ + + original_file_path := anObject +] + +{ #category : #accessing } +GLHNotePosition >> start_line [ + + ^ start_line +] + +{ #category : #accessing } +GLHNotePosition >> start_line: anObject [ + + start_line := anObject +] + +{ #category : #accessing } +GLHNotePosition >> start_line_type [ + + ^ start_line_type +] + +{ #category : #accessing } +GLHNotePosition >> start_line_type: anObject [ + + start_line_type := anObject +] diff --git a/src/GitProjectHealth-Model-Importer/GitModelImporter.class.st b/src/GitProjectHealth-Model-Importer/GitModelImporter.class.st index 165980f4..9fcb89c6 100644 --- a/src/GitProjectHealth-Model-Importer/GitModelImporter.class.st +++ b/src/GitProjectHealth-Model-Importer/GitModelImporter.class.st @@ -309,6 +309,17 @@ GitModelImporter >> configureReaderForNote: reader [ customMappting listOfElementSchema: GLHNote ] ] +{ #category : #'private - configure reader' } +GitModelImporter >> configureReaderForNotePosition: reader [ + + reader mapInstVarsFor: GLHNotePosition. + + reader + for: #ArrayOfNotePosition + customDo: [ :customMappting | + customMappting listOfElementSchema: GLHNotePosition ] +] + { #category : #'private - configure reader' } GitModelImporter >> configureReaderForPipeline: reader [ From 83a3e50ed5cbdc5df67ef80a9971794dda8c0c7f Mon Sep 17 00:00:00 2001 From: Kilian B <60846047+knowbased@users.noreply.github.com> Date: Tue, 21 Oct 2025 14:23:56 +0200 Subject: [PATCH 02/16] feat: add notePosition to the metamodel generator --- .../GLHMetamodelGenerator.class.st | 61 ++++++++++++++----- .../GitModelImporter.class.st | 8 +-- 2 files changed, 49 insertions(+), 20 deletions(-) diff --git a/src/GitLabHealth-Model-Generator/GLHMetamodelGenerator.class.st b/src/GitLabHealth-Model-Generator/GLHMetamodelGenerator.class.st index 64d64f73..aa8593ad 100644 --- a/src/GitLabHealth-Model-Generator/GLHMetamodelGenerator.class.st +++ b/src/GitLabHealth-Model-Generator/GLHMetamodelGenerator.class.st @@ -22,6 +22,7 @@ Class { 'deletion', 'lineOfCode', 'note', + 'notePosition', 'entity', 'release', 'tag', @@ -176,6 +177,15 @@ GLHMetamodelGenerator >> defineClasses [ comment: 'a note (a diff) proposed in a Merge Request; can be accepted, modified or deleted'. + note := builder + newClassNamed: #Note + comment: + 'a note (a diff) proposed in a Merge Request; can be accepted, modified or deleted'. + + notePosition := builder + newClassNamed: #NotePosition + comment: + 'indicate the position of a note'. tag := builder newClassNamed: #Tag @@ -187,16 +197,16 @@ GLHMetamodelGenerator >> defineClasses [ newClassNamed: #Release comment: 'a Release is typically associated with a tag and provide additional metadata and assets that can be distributed to users'. - + issue := builder newClassNamed: #Issue comment: 'an Issues help collaboration within a team to plan, track, and deliver work'. - + milestone := builder - newClassNamed: #Milestone - comment: - 'a Milestone is use to track progress on groups of issues or pull requests in a repository'. + newClassNamed: #Milestone + comment: + 'a Milestone is use to track progress on groups of issues or pull requests in a repository' ] { #category : #definition } @@ -214,11 +224,12 @@ GLHMetamodelGenerator >> defineHierarchy [ diff --|> #TNamedEntity. job --|> #TNamedEntity. note --|> #TNamedEntity. - + notePosition --|> #TNamedEntity. + tRef --|> #TNamedEntity. - tRef <|-- commit . - tRef <|-- branch . - tRef <|-- tag . + tRef <|-- commit. + tRef <|-- branch. + tRef <|-- tag. change --|> #TNamedEntity. change <|-- addition. @@ -227,7 +238,7 @@ GLHMetamodelGenerator >> defineHierarchy [ mergeRequest --|> #TNamedEntity. issue --|> #TNamedEntity. - milestone --|> #TNamedEntity. + milestone --|> #TNamedEntity ] { #category : #definition } @@ -248,12 +259,13 @@ GLHMetamodelGenerator >> defineProperties [ self mergeRequestProperties. self diffRangeProperties. self noteProperties. + self notePositionProperties. self tagProperties. self releaseProperties. self issueProperties. self milestoneProperties. - - self tRefProperties. + + self tRefProperties ] { #category : #definition } @@ -289,7 +301,8 @@ GLHMetamodelGenerator >> defineRelations [ self issueRelations. self mergeRequestsRelations. self noteRelations. - self milestoneRelations. + self milestoneRelations. + self notePositionRelations ] { #category : #definition } @@ -504,6 +517,24 @@ GLHMetamodelGenerator >> milestoneRelations [ (milestone property: #mergeRequest) <>-* (mergeRequest property: #milestone). ] +{ #category : #notes } +GLHMetamodelGenerator >> notePositionProperties [ + + notePosition property: #file_path type: #String. + notePosition property: #original_file_path type: #String. + notePosition property: #start_line type: #Number. + notePosition property: #start_line_type type: #String. + notePosition property: #end_line type: #Number. + notePosition property: #end_line_type type: #String. + notePosition property: #note type: #Object +] + +{ #category : #notes } +GLHMetamodelGenerator >> notePositionRelations [ + + (notePosition property: #note) - (note property: #position) +] + { #category : #notes } GLHMetamodelGenerator >> noteProperties [ note property: #id type: #Number. @@ -534,10 +565,10 @@ GLHMetamodelGenerator >> noteProperties [ ] -{ #category : #'merge requests' } +{ #category : #notes } GLHMetamodelGenerator >> noteRelations [ - (note property: #mergeRequest) *- (mergeRequest property: #note) + (note property: #position) - (notePosition property: #note). ] { #category : #pipelines } diff --git a/src/GitProjectHealth-Model-Importer/GitModelImporter.class.st b/src/GitProjectHealth-Model-Importer/GitModelImporter.class.st index 9fcb89c6..636decfd 100644 --- a/src/GitProjectHealth-Model-Importer/GitModelImporter.class.st +++ b/src/GitProjectHealth-Model-Importer/GitModelImporter.class.st @@ -314,10 +314,8 @@ GitModelImporter >> configureReaderForNotePosition: reader [ reader mapInstVarsFor: GLHNotePosition. - reader - for: #ArrayOfNotePosition - customDo: [ :customMappting | - customMappting listOfElementSchema: GLHNotePosition ] + reader for: #ArrayOfNotePosition customDo: [ :customMapping | + customMapping listOfElementSchema: GLHNotePosition ] ] { #category : #'private - configure reader' } @@ -671,7 +669,7 @@ GitModelImporter >> initReader [ string ifNil: [ nil ] ifNotNil: [ DateAndTime fromString: string ] ] ]. configurators := (self class allSelectors select: [ :m | - m beginsWith: #configureReaderFor ]) asSet. + m beginsWith: #configureReaderFor ]) asSet. configurators do: [ :configureReader | self perform: configureReader with: generalReader ] From 733f0b40e5f44896a0f6a00631b7da8a42605e7f Mon Sep 17 00:00:00 2001 From: Kilian B <60846047+knowbased@users.noreply.github.com> Date: Tue, 21 Oct 2025 14:25:52 +0200 Subject: [PATCH 03/16] fix: add mr -> note relation --- .../GLHMetamodelGenerator.class.st | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/GitLabHealth-Model-Generator/GLHMetamodelGenerator.class.st b/src/GitLabHealth-Model-Generator/GLHMetamodelGenerator.class.st index aa8593ad..40fa5bc4 100644 --- a/src/GitLabHealth-Model-Generator/GLHMetamodelGenerator.class.st +++ b/src/GitLabHealth-Model-Generator/GLHMetamodelGenerator.class.st @@ -568,7 +568,8 @@ GLHMetamodelGenerator >> noteProperties [ { #category : #notes } GLHMetamodelGenerator >> noteRelations [ - (note property: #position) - (notePosition property: #note). + (note property: #mergeRequest) *- (mergeRequest property: #note). + (note property: #position) - (notePosition property: #note) ] { #category : #pipelines } From e8d8e06b769671d175b4cc843276ef05a73d12cc Mon Sep 17 00:00:00 2001 From: Kilian B <60846047+knowbased@users.noreply.github.com> Date: Tue, 21 Oct 2025 14:27:26 +0200 Subject: [PATCH 04/16] fix: remove duplicate note in metamodel generator --- .../GLHMetamodelGenerator.class.st | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/GitLabHealth-Model-Generator/GLHMetamodelGenerator.class.st b/src/GitLabHealth-Model-Generator/GLHMetamodelGenerator.class.st index 40fa5bc4..2e427181 100644 --- a/src/GitLabHealth-Model-Generator/GLHMetamodelGenerator.class.st +++ b/src/GitLabHealth-Model-Generator/GLHMetamodelGenerator.class.st @@ -177,15 +177,9 @@ GLHMetamodelGenerator >> defineClasses [ comment: 'a note (a diff) proposed in a Merge Request; can be accepted, modified or deleted'. - note := builder - newClassNamed: #Note - comment: - 'a note (a diff) proposed in a Merge Request; can be accepted, modified or deleted'. - notePosition := builder - newClassNamed: #NotePosition - comment: - 'indicate the position of a note'. + newClassNamed: #NotePosition + comment: 'indicate the position of a note'. tag := builder newClassNamed: #Tag From 947dd8886aba184ad8aac9760d4f5108890182c6 Mon Sep 17 00:00:00 2001 From: Kilian B <60846047+knowbased@users.noreply.github.com> Date: Tue, 21 Oct 2025 14:49:25 +0200 Subject: [PATCH 05/16] feat: generate new model --- .../GLHMetamodelGenerator.class.st | 1 - .../GitlabModelImporter.class.st | 17 +++-- src/GitLabHealth-Model/GLHIssue.class.st | 2 +- src/GitLabHealth-Model/GLHJob.class.st | 2 +- src/GitLabHealth-Model/GLHNote.class.st | 5 ++ .../GLHNotePosition.class.st | 67 ++++++++++++++++--- .../GLHTEntityCreator.trait.st | 14 ++++ src/GitLabHealth-Model/GLHUser.class.st | 2 +- 8 files changed, 94 insertions(+), 16 deletions(-) diff --git a/src/GitLabHealth-Model-Generator/GLHMetamodelGenerator.class.st b/src/GitLabHealth-Model-Generator/GLHMetamodelGenerator.class.st index 2e427181..8dc77243 100644 --- a/src/GitLabHealth-Model-Generator/GLHMetamodelGenerator.class.st +++ b/src/GitLabHealth-Model-Generator/GLHMetamodelGenerator.class.st @@ -520,7 +520,6 @@ GLHMetamodelGenerator >> notePositionProperties [ notePosition property: #start_line_type type: #String. notePosition property: #end_line type: #Number. notePosition property: #end_line_type type: #String. - notePosition property: #note type: #Object ] { #category : #notes } diff --git a/src/GitLabHealth-Model-Importer/GitlabModelImporter.class.st b/src/GitLabHealth-Model-Importer/GitlabModelImporter.class.st index 82381683..6df94449 100644 --- a/src/GitLabHealth-Model-Importer/GitlabModelImporter.class.st +++ b/src/GitLabHealth-Model-Importer/GitlabModelImporter.class.st @@ -378,21 +378,20 @@ GitlabModelImporter >> configureReaderForNotePosition: reader [ mapProperty: #new_line getter: [ ] setter: [ :notePosition :newLine | - notePosition start_line: newLine asString. + notePosition start_line: newLine. notePosition start_line_type: 'new' ]. mapping mapProperty: #old_line getter: [ ] setter: [ :notePosition :oldLine | - notePosition start_line: oldLine asString. + notePosition start_line: oldLine. notePosition start_line_type: 'old' ]. mapping mapProperty: #line_range getter: [ ] setter: [ :notePosition :rawLineRange | - rawLineRange ifNotNil: [ | start startType startLine end endType endLine | start := rawLineRange at: #start. @@ -410,7 +409,17 @@ GitlabModelImporter >> configureReaderForNotePosition: reader [ ifTrue: [ end at: #new_line ] ifFalse: [ end at: #old_line ]. notePosition end_line_type: (end at: #type). - notePosition end_line: endLine ] ] ] + notePosition end_line: endLine ]]. + + mapping + mapProperty: #note + getter: [ ] + setter: [ :object :value | + 1 halt. + object cacheAt: #noteID put: (value at: #id) ]. + + ]. + ] { #category : #'private - configure reader' } diff --git a/src/GitLabHealth-Model/GLHIssue.class.st b/src/GitLabHealth-Model/GLHIssue.class.st index 2d6fc7bb..80320c00 100644 --- a/src/GitLabHealth-Model/GLHIssue.class.st +++ b/src/GitLabHealth-Model/GLHIssue.class.st @@ -27,8 +27,8 @@ an Issues help collaboration within a team to plan, track, and deliver work | `description` | `String` | nil | | | `due_date` | `Object` | nil | | | `id` | `Number` | nil | | -| `name` | `String` | nil | Basic name of the entity, not full reference.| | `name` | `String` | nil | | +| `name` | `String` | nil | Basic name of the entity, not full reference.| | `state` | `String` | nil | | | `updated_at` | `Object` | nil | | diff --git a/src/GitLabHealth-Model/GLHJob.class.st b/src/GitLabHealth-Model/GLHJob.class.st index bed62ed5..b50f9f3d 100644 --- a/src/GitLabHealth-Model/GLHJob.class.st +++ b/src/GitLabHealth-Model/GLHJob.class.st @@ -20,8 +20,8 @@ A CI Job | `allow_failure` | `Boolean` | nil | | | `duration` | `Object` | nil | | | `id` | `Number` | nil | | -| `name` | `String` | nil | Basic name of the entity, not full reference.| | `name` | `String` | nil | | +| `name` | `String` | nil | Basic name of the entity, not full reference.| | `ref` | `String` | nil | | | `web_url` | `String` | nil | | diff --git a/src/GitLabHealth-Model/GLHNote.class.st b/src/GitLabHealth-Model/GLHNote.class.st index de2c0445..72864708 100644 --- a/src/GitLabHealth-Model/GLHNote.class.st +++ b/src/GitLabHealth-Model/GLHNote.class.st @@ -8,6 +8,8 @@ a note (a diff) proposed in a Merge Request; can be accepted, modified or delete | Relation | Origin | Opposite | Type | Comment | |---| | `mergeRequest` | `GLHNote` | `note` | `GLHMergeRequest` | | +| `position` | `GLHNote` | `note` | `GLHNotePosition` | | +| `position` | `GLHNote` | `note` | `GLHNotePosition` | | ## Properties @@ -256,13 +258,16 @@ GLHNote >> noteable_type: anObject [ { #category : #accessing } GLHNote >> position [ + "Relation named: #position type: #GLHNotePosition opposite: #note" + ^ position ] { #category : #accessing } GLHNote >> position: anObject [ + position := anObject ] diff --git a/src/GitLabHealth-Model/GLHNotePosition.class.st b/src/GitLabHealth-Model/GLHNotePosition.class.st index 22c09cfe..97078112 100644 --- a/src/GitLabHealth-Model/GLHNotePosition.class.st +++ b/src/GitLabHealth-Model/GLHNotePosition.class.st @@ -1,3 +1,31 @@ +" +indicate the position of a note + +## Relations +====================== + +### Other +| Relation | Origin | Opposite | Type | Comment | +|---| +| `note` | `GLHNotePosition` | `position` | `GLHNote` | | +| `note` | `GLHNotePosition` | `position` | `GLHNote` | | + + +## Properties +====================== + +| Name | Type | Default value | Comment | +|---| +| `end_line` | `Number` | nil | | +| `end_line_type` | `String` | nil | | +| `file_path` | `String` | nil | | +| `name` | `String` | nil | Basic name of the entity, not full reference.| +| `note` | `Object` | nil | | +| `original_file_path` | `String` | nil | | +| `start_line` | `Number` | nil | | +| `start_line_type` | `String` | nil | | + +" Class { #name : #GLHNotePosition, #superclass : #GLHEntity, @@ -10,91 +38,114 @@ Class { '#start_line_type => FMProperty', '#end_line => FMProperty', '#end_line_type => FMProperty', - '#note => FMOne type: #GLHNote opposite: #position' + '#note => FMProperty' ], #category : #'GitLabHealth-Model-Entities' } +{ #category : #meta } +GLHNotePosition class >> annotation [ + + + + + ^ self +] + { #category : #accessing } GLHNotePosition >> end_line [ + + ^ end_line ] { #category : #accessing } GLHNotePosition >> end_line: anObject [ - + end_line := anObject ] { #category : #accessing } GLHNotePosition >> end_line_type [ + + ^ end_line_type ] { #category : #accessing } GLHNotePosition >> end_line_type: anObject [ - + end_line_type := anObject ] { #category : #accessing } GLHNotePosition >> file_path [ + + ^ file_path ] { #category : #accessing } GLHNotePosition >> file_path: anObject [ - + file_path := anObject ] { #category : #accessing } GLHNotePosition >> note [ + + ^ note ] { #category : #accessing } GLHNotePosition >> note: anObject [ - + note := anObject ] { #category : #accessing } GLHNotePosition >> original_file_path [ + + ^ original_file_path ] { #category : #accessing } GLHNotePosition >> original_file_path: anObject [ - + original_file_path := anObject ] { #category : #accessing } GLHNotePosition >> start_line [ + + ^ start_line ] { #category : #accessing } GLHNotePosition >> start_line: anObject [ - + start_line := anObject ] { #category : #accessing } GLHNotePosition >> start_line_type [ + + ^ start_line_type ] { #category : #accessing } GLHNotePosition >> start_line_type: anObject [ - + start_line_type := anObject ] diff --git a/src/GitLabHealth-Model/GLHTEntityCreator.trait.st b/src/GitLabHealth-Model/GLHTEntityCreator.trait.st index f50e3745..34a77674 100644 --- a/src/GitLabHealth-Model/GLHTEntityCreator.trait.st +++ b/src/GitLabHealth-Model/GLHTEntityCreator.trait.st @@ -207,6 +207,20 @@ GLHTEntityCreator >> newNoteNamed: aName [ ^ self add: (GLHNote named: aName) ] +{ #category : #'entity creation' } +GLHTEntityCreator >> newNotePosition [ + + + ^ self add: GLHNotePosition new +] + +{ #category : #'entity creation' } +GLHTEntityCreator >> newNotePositionNamed: aName [ + + + ^ self add: (GLHNotePosition named: aName) +] + { #category : #'entity creation' } GLHTEntityCreator >> newPipeline [ diff --git a/src/GitLabHealth-Model/GLHUser.class.st b/src/GitLabHealth-Model/GLHUser.class.st index d6648af4..20a41c87 100644 --- a/src/GitLabHealth-Model/GLHUser.class.st +++ b/src/GitLabHealth-Model/GLHUser.class.st @@ -51,8 +51,8 @@ A GitLab User | `job_title` | `String` | nil | | | `linkedin` | `String` | nil | | | `location` | `String` | nil | | -| `name` | `String` | nil | Basic name of the entity, not full reference.| | `name` | `String` | nil | | +| `name` | `String` | nil | Basic name of the entity, not full reference.| | `organization` | `String` | nil | | | `pronouns` | `String` | nil | | | `public_email` | `String` | nil | | From 478ef6464b6bc05f2bcdea7070be948fc872890f Mon Sep 17 00:00:00 2001 From: Kilian B <60846047+knowbased@users.noreply.github.com> Date: Tue, 21 Oct 2025 15:13:51 +0200 Subject: [PATCH 06/16] feat: push new model --- .../GitlabModelImporter.class.st | 12 +----------- src/GitLabHealth-Model/GLHCommit.class.st | 2 +- src/GitLabHealth-Model/GLHIssue.class.st | 2 +- src/GitLabHealth-Model/GLHJob.class.st | 2 +- src/GitLabHealth-Model/GLHNotePosition.class.st | 7 ++++--- 5 files changed, 8 insertions(+), 17 deletions(-) diff --git a/src/GitLabHealth-Model-Importer/GitlabModelImporter.class.st b/src/GitLabHealth-Model-Importer/GitlabModelImporter.class.st index 6df94449..bea82c05 100644 --- a/src/GitLabHealth-Model-Importer/GitlabModelImporter.class.st +++ b/src/GitLabHealth-Model-Importer/GitlabModelImporter.class.st @@ -409,17 +409,7 @@ GitlabModelImporter >> configureReaderForNotePosition: reader [ ifTrue: [ end at: #new_line ] ifFalse: [ end at: #old_line ]. notePosition end_line_type: (end at: #type). - notePosition end_line: endLine ]]. - - mapping - mapProperty: #note - getter: [ ] - setter: [ :object :value | - 1 halt. - object cacheAt: #noteID put: (value at: #id) ]. - - ]. - + notePosition end_line: endLine ]]] ] { #category : #'private - configure reader' } diff --git a/src/GitLabHealth-Model/GLHCommit.class.st b/src/GitLabHealth-Model/GLHCommit.class.st index 13d2c100..8e23d671 100644 --- a/src/GitLabHealth-Model/GLHCommit.class.st +++ b/src/GitLabHealth-Model/GLHCommit.class.st @@ -21,8 +21,8 @@ a commit attached to a repository |---| | `branch` | `GLHCommit` | `commits` | `GLHBranch` | | | `childCommits` | `GLHCommit` | `parentCommits` | `GLHCommit` | | -| `commitedMergeRequest` | `GLHCommit` | `mergeRequestCommit` | `GLHMergeRequest` | | | `commitedMergeRequest` | `GLHCommit` | `mergedCommit` | `GLHMergeRequest` | | +| `commitedMergeRequest` | `GLHCommit` | `mergeRequestCommit` | `GLHMergeRequest` | | | `parentCommits` | `GLHCommit` | `childCommits` | `GLHCommit` | | | `squashedMergeRequest` | `GLHCommit` | `squashCommit` | `GLHMergeRequest` | | | `tag` | `GLHCommit` | `commit` | `GLHTag` | | diff --git a/src/GitLabHealth-Model/GLHIssue.class.st b/src/GitLabHealth-Model/GLHIssue.class.st index 80320c00..2d6fc7bb 100644 --- a/src/GitLabHealth-Model/GLHIssue.class.st +++ b/src/GitLabHealth-Model/GLHIssue.class.st @@ -27,8 +27,8 @@ an Issues help collaboration within a team to plan, track, and deliver work | `description` | `String` | nil | | | `due_date` | `Object` | nil | | | `id` | `Number` | nil | | -| `name` | `String` | nil | | | `name` | `String` | nil | Basic name of the entity, not full reference.| +| `name` | `String` | nil | | | `state` | `String` | nil | | | `updated_at` | `Object` | nil | | diff --git a/src/GitLabHealth-Model/GLHJob.class.st b/src/GitLabHealth-Model/GLHJob.class.st index b50f9f3d..bed62ed5 100644 --- a/src/GitLabHealth-Model/GLHJob.class.st +++ b/src/GitLabHealth-Model/GLHJob.class.st @@ -20,8 +20,8 @@ A CI Job | `allow_failure` | `Boolean` | nil | | | `duration` | `Object` | nil | | | `id` | `Number` | nil | | -| `name` | `String` | nil | | | `name` | `String` | nil | Basic name of the entity, not full reference.| +| `name` | `String` | nil | | | `ref` | `String` | nil | | | `web_url` | `String` | nil | | diff --git a/src/GitLabHealth-Model/GLHNotePosition.class.st b/src/GitLabHealth-Model/GLHNotePosition.class.st index 97078112..009ef65c 100644 --- a/src/GitLabHealth-Model/GLHNotePosition.class.st +++ b/src/GitLabHealth-Model/GLHNotePosition.class.st @@ -20,7 +20,6 @@ indicate the position of a note | `end_line_type` | `String` | nil | | | `file_path` | `String` | nil | | | `name` | `String` | nil | Basic name of the entity, not full reference.| -| `note` | `Object` | nil | | | `original_file_path` | `String` | nil | | | `start_line` | `Number` | nil | | | `start_line_type` | `String` | nil | | @@ -38,7 +37,7 @@ Class { '#start_line_type => FMProperty', '#end_line => FMProperty', '#end_line_type => FMProperty', - '#note => FMProperty' + '#note => FMOne type: #GLHNote opposite: #position' ], #category : #'GitLabHealth-Model-Entities' } @@ -96,14 +95,16 @@ GLHNotePosition >> file_path: anObject [ { #category : #accessing } GLHNotePosition >> note [ + "Relation named: #note type: #GLHNote opposite: #position" - + ^ note ] { #category : #accessing } GLHNotePosition >> note: anObject [ + note := anObject ] From ff4183ff23c85be24640878f15f3d43a5d8c0b90 Mon Sep 17 00:00:00 2001 From: Kilian B <60846047+knowbased@users.noreply.github.com> Date: Tue, 21 Oct 2025 15:36:10 +0200 Subject: [PATCH 07/16] feat: add note suggeestion in meta model generator --- .../GLHMetamodelGenerator.class.st | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/GitLabHealth-Model-Generator/GLHMetamodelGenerator.class.st b/src/GitLabHealth-Model-Generator/GLHMetamodelGenerator.class.st index 8dc77243..1b2b28ca 100644 --- a/src/GitLabHealth-Model-Generator/GLHMetamodelGenerator.class.st +++ b/src/GitLabHealth-Model-Generator/GLHMetamodelGenerator.class.st @@ -23,6 +23,7 @@ Class { 'lineOfCode', 'note', 'notePosition', + 'noteSuggestion', 'entity', 'release', 'tag', @@ -181,6 +182,10 @@ GLHMetamodelGenerator >> defineClasses [ newClassNamed: #NotePosition comment: 'indicate the position of a note'. + noteSuggestion := builder + newClassNamed: #NoteSuggestion + comment: 'suggestion of code made in a note'. + tag := builder newClassNamed: #Tag comment: @@ -218,7 +223,8 @@ GLHMetamodelGenerator >> defineHierarchy [ diff --|> #TNamedEntity. job --|> #TNamedEntity. note --|> #TNamedEntity. - notePosition --|> #TNamedEntity. + notePosition --|> #TNamedEntity. + noteSuggestion --|> #TNamedEntity. tRef --|> #TNamedEntity. tRef <|-- commit. @@ -254,6 +260,7 @@ GLHMetamodelGenerator >> defineProperties [ self diffRangeProperties. self noteProperties. self notePositionProperties. + self noteSuggestionProperties. self tagProperties. self releaseProperties. self issueProperties. @@ -295,6 +302,8 @@ GLHMetamodelGenerator >> defineRelations [ self issueRelations. self mergeRequestsRelations. self noteRelations. + self notePositionRelations. + self noteSuggestionProperties. self milestoneRelations. self notePositionRelations ] @@ -565,6 +574,21 @@ GLHMetamodelGenerator >> noteRelations [ (note property: #position) - (notePosition property: #note) ] +{ #category : #notes } +GLHMetamodelGenerator >> noteSuggestionProperties [ + + noteSuggestion property: #from_line type: #Number. + noteSuggestion property: #to_line type: #Number. + noteSuggestion property: #from_content type: #String. + noteSuggestion property: #to_content type: #String. +] + +{ #category : #notes } +GLHMetamodelGenerator >> noteSuggestionRelations [ + + (noteSuggestion property: #note) - (note property: #position) +] + { #category : #pipelines } GLHMetamodelGenerator >> pipelinesProperties [ From 35b518768ab43cff5d9bafe36308d5e0665f1d2f Mon Sep 17 00:00:00 2001 From: Kilian B <60846047+knowbased@users.noreply.github.com> Date: Tue, 21 Oct 2025 15:43:10 +0200 Subject: [PATCH 08/16] feat: new model with suggestion --- .../GLHMetamodelGenerator.class.st | 4 +- .../GitlabModelImporter.class.st | 24 +++-- src/GitLabHealth-Model/GLHJob.class.st | 2 +- src/GitLabHealth-Model/GLHNote.class.st | 1 + .../GLHNotePosition.class.st | 1 + .../GLHNoteSuggestion.class.st | 97 +++++++++++++++++++ .../GLHTEntityCreator.trait.st | 14 +++ 7 files changed, 130 insertions(+), 13 deletions(-) create mode 100644 src/GitLabHealth-Model/GLHNoteSuggestion.class.st diff --git a/src/GitLabHealth-Model-Generator/GLHMetamodelGenerator.class.st b/src/GitLabHealth-Model-Generator/GLHMetamodelGenerator.class.st index 1b2b28ca..7f263cdb 100644 --- a/src/GitLabHealth-Model-Generator/GLHMetamodelGenerator.class.st +++ b/src/GitLabHealth-Model-Generator/GLHMetamodelGenerator.class.st @@ -584,9 +584,9 @@ GLHMetamodelGenerator >> noteSuggestionProperties [ ] { #category : #notes } -GLHMetamodelGenerator >> noteSuggestionRelations [ +GLHMetamodelGenerator >> noteSuggestionRelations [ - (noteSuggestion property: #note) - (note property: #position) + (noteSuggestion property: #note) -* (note property: #suggestions) ] { #category : #pipelines } diff --git a/src/GitLabHealth-Model-Importer/GitlabModelImporter.class.st b/src/GitLabHealth-Model-Importer/GitlabModelImporter.class.st index bea82c05..ceef672b 100644 --- a/src/GitLabHealth-Model-Importer/GitlabModelImporter.class.st +++ b/src/GitLabHealth-Model-Importer/GitlabModelImporter.class.st @@ -1447,21 +1447,25 @@ GitlabModelImporter >> importMergeResquestMerger: aGLPHEMergeRequest [ { #category : #'import - notes' } GitlabModelImporter >> importNotesOfMergeRequest: mergeRequest [ + | results notes | - - results := self repoApi notes allInMergeRequest: mergeRequest iid ofProject: mergeRequest project id. - - notes := results collect: [ :note | - self parseNoteJson: note ]. + results := self repoApi notes + allInMergeRequest: mergeRequest iid + ofProject: mergeRequest project id. + + notes := results collect: [ :note | self parseNoteJson: note ]. "notes := self parseNoteJson: results." - notes do: [ :tabNotes | tabNotes do: [ :note | + notes do: [ :tabNotes | + tabNotes do: [ :note | note author: (self importUser: (note author at: #id)). - note name: note id asString]. ]. + note name: note id asString ] ]. notes := notes flattened. - notes := self glhModel addAll: notes unless: self blockOnIdEquality. - notes := mergeRequest note addAll: notes unless: self blockOnIdEquality. - ^notes + notes := self glhModel addAll: notes unless: self blockOnIdEquality. + notes := mergeRequest note + addAll: notes + unless: self blockOnIdEquality. + ^ notes ] { #category : #'import - commits' } diff --git a/src/GitLabHealth-Model/GLHJob.class.st b/src/GitLabHealth-Model/GLHJob.class.st index bed62ed5..b50f9f3d 100644 --- a/src/GitLabHealth-Model/GLHJob.class.st +++ b/src/GitLabHealth-Model/GLHJob.class.st @@ -20,8 +20,8 @@ A CI Job | `allow_failure` | `Boolean` | nil | | | `duration` | `Object` | nil | | | `id` | `Number` | nil | | -| `name` | `String` | nil | Basic name of the entity, not full reference.| | `name` | `String` | nil | | +| `name` | `String` | nil | Basic name of the entity, not full reference.| | `ref` | `String` | nil | | | `web_url` | `String` | nil | | diff --git a/src/GitLabHealth-Model/GLHNote.class.st b/src/GitLabHealth-Model/GLHNote.class.st index 72864708..b6a810a7 100644 --- a/src/GitLabHealth-Model/GLHNote.class.st +++ b/src/GitLabHealth-Model/GLHNote.class.st @@ -10,6 +10,7 @@ a note (a diff) proposed in a Merge Request; can be accepted, modified or delete | `mergeRequest` | `GLHNote` | `note` | `GLHMergeRequest` | | | `position` | `GLHNote` | `note` | `GLHNotePosition` | | | `position` | `GLHNote` | `note` | `GLHNotePosition` | | +| `position` | `GLHNote` | `note` | `GLHNotePosition` | | ## Properties diff --git a/src/GitLabHealth-Model/GLHNotePosition.class.st b/src/GitLabHealth-Model/GLHNotePosition.class.st index 009ef65c..ee76ee38 100644 --- a/src/GitLabHealth-Model/GLHNotePosition.class.st +++ b/src/GitLabHealth-Model/GLHNotePosition.class.st @@ -9,6 +9,7 @@ indicate the position of a note |---| | `note` | `GLHNotePosition` | `position` | `GLHNote` | | | `note` | `GLHNotePosition` | `position` | `GLHNote` | | +| `note` | `GLHNotePosition` | `position` | `GLHNote` | | ## Properties diff --git a/src/GitLabHealth-Model/GLHNoteSuggestion.class.st b/src/GitLabHealth-Model/GLHNoteSuggestion.class.st new file mode 100644 index 00000000..46dc3c49 --- /dev/null +++ b/src/GitLabHealth-Model/GLHNoteSuggestion.class.st @@ -0,0 +1,97 @@ +" +suggestion of code made in a note + +## Properties +====================== + +| Name | Type | Default value | Comment | +|---| +| `from_content` | `String` | nil | | +| `from_content` | `String` | nil | | +| `from_line` | `Number` | nil | | +| `from_line` | `Number` | nil | | +| `name` | `String` | nil | Basic name of the entity, not full reference.| +| `to_content` | `String` | nil | | +| `to_content` | `String` | nil | | +| `to_line` | `Number` | nil | | +| `to_line` | `Number` | nil | | + +" +Class { + #name : #GLHNoteSuggestion, + #superclass : #GLHEntity, + #traits : 'FamixTNamedEntity', + #classTraits : 'FamixTNamedEntity classTrait', + #instVars : [ + '#from_line => FMProperty', + '#to_line => FMProperty', + '#from_content => FMProperty', + '#to_content => FMProperty' + ], + #category : #'GitLabHealth-Model-Entities' +} + +{ #category : #meta } +GLHNoteSuggestion class >> annotation [ + + + + + ^ self +] + +{ #category : #accessing } +GLHNoteSuggestion >> from_content [ + + + + ^ from_content +] + +{ #category : #accessing } +GLHNoteSuggestion >> from_content: anObject [ + + from_content := anObject +] + +{ #category : #accessing } +GLHNoteSuggestion >> from_line [ + + + + ^ from_line +] + +{ #category : #accessing } +GLHNoteSuggestion >> from_line: anObject [ + + from_line := anObject +] + +{ #category : #accessing } +GLHNoteSuggestion >> to_content [ + + + + ^ to_content +] + +{ #category : #accessing } +GLHNoteSuggestion >> to_content: anObject [ + + to_content := anObject +] + +{ #category : #accessing } +GLHNoteSuggestion >> to_line [ + + + + ^ to_line +] + +{ #category : #accessing } +GLHNoteSuggestion >> to_line: anObject [ + + to_line := anObject +] diff --git a/src/GitLabHealth-Model/GLHTEntityCreator.trait.st b/src/GitLabHealth-Model/GLHTEntityCreator.trait.st index 34a77674..fda34086 100644 --- a/src/GitLabHealth-Model/GLHTEntityCreator.trait.st +++ b/src/GitLabHealth-Model/GLHTEntityCreator.trait.st @@ -221,6 +221,20 @@ GLHTEntityCreator >> newNotePositionNamed: aName [ ^ self add: (GLHNotePosition named: aName) ] +{ #category : #'entity creation' } +GLHTEntityCreator >> newNoteSuggestion [ + + + ^ self add: GLHNoteSuggestion new +] + +{ #category : #'entity creation' } +GLHTEntityCreator >> newNoteSuggestionNamed: aName [ + + + ^ self add: (GLHNoteSuggestion named: aName) +] + { #category : #'entity creation' } GLHTEntityCreator >> newPipeline [ From 034a9122a346f3eb03cdc2fd994c63d938f8b5ad Mon Sep 17 00:00:00 2001 From: Kilian B <60846047+knowbased@users.noreply.github.com> Date: Tue, 21 Oct 2025 15:45:00 +0200 Subject: [PATCH 09/16] fix: add suggestion relation il metamodel --- src/GitLabHealth-Model-Generator/GLHMetamodelGenerator.class.st | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/GitLabHealth-Model-Generator/GLHMetamodelGenerator.class.st b/src/GitLabHealth-Model-Generator/GLHMetamodelGenerator.class.st index 7f263cdb..1bd03601 100644 --- a/src/GitLabHealth-Model-Generator/GLHMetamodelGenerator.class.st +++ b/src/GitLabHealth-Model-Generator/GLHMetamodelGenerator.class.st @@ -303,7 +303,7 @@ GLHMetamodelGenerator >> defineRelations [ self mergeRequestsRelations. self noteRelations. self notePositionRelations. - self noteSuggestionProperties. + self noteSuggestionRelations. self milestoneRelations. self notePositionRelations ] From 51690bea9f7b89d9295b77c757b282152cdc2253 Mon Sep 17 00:00:00 2001 From: Kilian B <60846047+knowbased@users.noreply.github.com> Date: Thu, 23 Oct 2025 14:09:02 +0200 Subject: [PATCH 10/16] feat: add suggestion in gitlab importer --- .../GLHMetamodelGenerator.class.st | 2 +- .../GitlabModelImporterTest.class.st | 150 ++++++++++++++++++ .../GitlabModelImporter.class.st | 105 +++++++++--- src/GitLabHealth-Model/GLHCommit.class.st | 2 +- src/GitLabHealth-Model/GLHIssue.class.st | 2 +- src/GitLabHealth-Model/GLHNote.class.st | 19 ++- .../GLHNoteSuggestion.class.st | 38 ++++- 7 files changed, 288 insertions(+), 30 deletions(-) diff --git a/src/GitLabHealth-Model-Generator/GLHMetamodelGenerator.class.st b/src/GitLabHealth-Model-Generator/GLHMetamodelGenerator.class.st index 1bd03601..479ecc31 100644 --- a/src/GitLabHealth-Model-Generator/GLHMetamodelGenerator.class.st +++ b/src/GitLabHealth-Model-Generator/GLHMetamodelGenerator.class.st @@ -586,7 +586,7 @@ GLHMetamodelGenerator >> noteSuggestionProperties [ { #category : #notes } GLHMetamodelGenerator >> noteSuggestionRelations [ - (noteSuggestion property: #note) -* (note property: #suggestions) + (noteSuggestion property: #note) *- (note property: #suggestions) ] { #category : #pipelines } diff --git a/src/GitLabHealth-Model-Importer-Tests/GitlabModelImporterTest.class.st b/src/GitLabHealth-Model-Importer-Tests/GitlabModelImporterTest.class.st index 1aaa0ef7..06fa479d 100644 --- a/src/GitLabHealth-Model-Importer-Tests/GitlabModelImporterTest.class.st +++ b/src/GitLabHealth-Model-Importer-Tests/GitlabModelImporterTest.class.st @@ -221,6 +221,156 @@ GitlabModelImporterTest >> testCompleteImportsOfRepository [ self assert: element branches anyOne class equals: GLHBranch ] +{ #category : #tests } +GitlabModelImporterTest >> testGetSuggestionsFromNote [ + + | body position glhNote result suggestion | + body := ' + test + ```suggestion:-0+5 + content +```'. + + position := GLHNotePosition new + start_line: 2; + end_line: 2. + glhNote := GLHNote new + body: body; + position: position. + + + result := importer getSuggestionsFromNote: glhNote. + + self assert: result size equals: 1. + + suggestion := result first. + self assert: suggestion from_line equals: 2. + self assert: suggestion to_line equals: 7. + self assert: suggestion to_content trim equals: 'content'. +] + +{ #category : #tests } +GitlabModelImporterTest >> testGetSuggestionsFromNoteWithDifferentStartAndEndLine [ + + | body position glhNote result suggestion | + body := ' + test + ```suggestion:-2+5 + content +```'. + + position := GLHNotePosition new + start_line: 2; + end_line: 5. + glhNote := GLHNote new + body: body; + position: position. + + + result := importer getSuggestionsFromNote: glhNote. + + self assert: result size equals: 1. + + suggestion := result first. + self assert: suggestion from_line equals: 3. + self assert: suggestion to_line equals: 10. + self assert: suggestion to_content trim equals: 'content' +] + +{ #category : #tests } +GitlabModelImporterTest >> testGetSuggestionsFromNoteWithMultipleSuggestions [ + + | body position glhNote result suggestion suggestion2 | + body := ' + test + ```suggestion:-2+5 + content +``` + +```suggestion:-0+0 +```'. + + position := GLHNotePosition new + start_line: 2; + end_line: 5. + glhNote := GLHNote new + body: body; + position: position. + + + result := importer getSuggestionsFromNote: glhNote. + + self assert: result size equals: 2. + + suggestion := result first. + self assert: suggestion from_line equals: 3. + self assert: suggestion to_line equals: 10. + self assert: suggestion to_content trim equals: 'content'. + + suggestion2 := result at: 2. + self assert: suggestion2 from_line equals: 5. + self assert: suggestion2 to_line equals: 5. + self assert: suggestion2 to_content trim equals: '' +] + +{ #category : #tests } +GitlabModelImporterTest >> testGetSuggestionsInfoFromString [ + + | string result suggestion | + string := ' + some content + ```suggestion:-0+2 + test +```'. + + result := importer getSuggestionsInfoFromString: string. + + self assert: result size equals: 1. + suggestion := result first. + self assert: (suggestion at: #minus) equals: 0. + self assert: (suggestion at: #plus) equals: 2. + self assert: (suggestion at: #content) trim equals: 'test' +] + +{ #category : #tests } +GitlabModelImporterTest >> testGetSuggestionsInfoFromStringWithMultipleSuggestion [ + + | string result suggestion suggestion2 | + string := '```suggestion:-0+2 + test +``` + +```suggestion:-2+4 + +oui + +```'. + + result := importer getSuggestionsInfoFromString: string. + + self assert: result size equals: 2. + suggestion := result first. + self assert: (suggestion at: #minus) equals: 0. + self assert: (suggestion at: #plus) equals: 2. + self assert: (suggestion at: #content) trim equals: 'test'. + + suggestion2 := result at: 2. + self assert: (suggestion2 at: #minus) equals: 2. + self assert: (suggestion2 at: #plus) equals: 4. + self assert: (suggestion2 at: #content) trim equals: 'oui' +] + +{ #category : #tests } +GitlabModelImporterTest >> testGetSuggestionsInfoFromStringWithNoSuggestions [ + + | string result | + string := 'a normal comment'. + + result := importer getSuggestionsInfoFromString: string. + + self assert: result size equals: 0. +] + { #category : #'tests - commits' } GitlabModelImporterTest >> testImportCommitsFromTagToTagNoCommits [ diff --git a/src/GitLabHealth-Model-Importer/GitlabModelImporter.class.st b/src/GitLabHealth-Model-Importer/GitlabModelImporter.class.st index ceef672b..0ef59a42 100644 --- a/src/GitLabHealth-Model-Importer/GitlabModelImporter.class.st +++ b/src/GitLabHealth-Model-Importer/GitlabModelImporter.class.st @@ -392,24 +392,26 @@ GitlabModelImporter >> configureReaderForNotePosition: reader [ mapProperty: #line_range getter: [ ] setter: [ :notePosition :rawLineRange | - rawLineRange ifNotNil: [ - | start startType startLine end endType endLine | - start := rawLineRange at: #start. - startType := start at: #type. - startLine := (start at: #type) = 'new' - ifTrue: [ start at: #new_line ] - ifFalse: [ start at: #old_line ]. - notePosition start_line_type: (start at: #type). - notePosition start_line: startLine. - - - end := rawLineRange at: #end. - endType := end at: #type. - endLine := (end at: #type) = 'new' - ifTrue: [ end at: #new_line ] - ifFalse: [ end at: #old_line ]. - notePosition end_line_type: (end at: #type). - notePosition end_line: endLine ]]] + rawLineRange + ifNil: [ notePosition end_line = notePosition start_line ] + ifNotNil: [ + | start startType startLine end endType endLine | + start := rawLineRange at: #start. + startType := start at: #type. + startLine := (start at: #type) = 'new' + ifTrue: [ start at: #new_line ] + ifFalse: [ start at: #old_line ]. + notePosition start_line_type: (start at: #type). + notePosition start_line: startLine. + + + end := rawLineRange at: #end. + endType := end at: #type. + endLine := (end at: #type) = 'new' + ifTrue: [ end at: #new_line ] + ifFalse: [ end at: #old_line ]. + notePosition end_line_type: (end at: #type). + notePosition end_line: endLine ] ] ] ] { #category : #'private - configure reader' } @@ -540,6 +542,61 @@ GitlabModelImporter >> detectEntityType: aType overAttribut: aSelector equalTo: (entity perform: aSelector) = value ] ifNone: [ nil ]. ] +{ #category : #'import - notes' } +GitlabModelImporter >> getSuggestionsFromNote: glhNote [ + + | suggestions suggestion fromLine toLine suggestionsInfo | + glhNote position ifNil: [ ^ { } ]. + suggestions := MooseGroup new. + + suggestionsInfo := self getSuggestionsInfoFromString: glhNote body. + + ^ suggestionsInfo collect: [ :suggestionInfo | + suggestion := GLHNoteSuggestion new. + fromLine := glhNote position end_line - (suggestionInfo at: #minus). + toLine := glhNote position end_line + (suggestionInfo at: #plus). + suggestion from_line: fromLine. + suggestion to_line: toLine. + suggestion to_content: (suggestionInfo at: #content) ]. + +] + +{ #category : #'import - notes' } +GitlabModelImporter >> getSuggestionsInfoFromString: string [ + + | suggestionsInfo regex result regex2 suggestionInfo | + suggestionsInfo := OrderedCollection new. + + regex := '```suggestion' asRegex. + result := regex matchesIn: string. + + result isEmpty ifTrue: [ ^ suggestionsInfo ]. + result size > 1 ifTrue: [ + | start end firstPart secondPart | + start := string findString: '```suggestion'. + end := (string findString: '```' startingAt: start +2) + 2. + + firstPart := string copyFrom: 1 to: end. + secondPart := string copyFrom: end to: string size. + + suggestionsInfo addAll: + (self getSuggestionsInfoFromString: firstPart). + suggestionsInfo addAll: + (self getSuggestionsInfoFromString: secondPart). + ^ suggestionsInfo ]. + + regex2 := '```suggestion\:-(\d+)\+(\d+)(.*)```' asRegex. + regex2 search: string. + + suggestionInfo := { + (#minus -> (regex2 subexpression: 2) asNumber). + (#plus -> (regex2 subexpression: 3) asNumber). + (#content -> (regex2 subexpression: 4)) } + asDictionary. + + ^ { suggestionInfo } +] + { #category : #accessing } GitlabModelImporter >> glhApi [ @@ -1454,17 +1511,23 @@ GitlabModelImporter >> importNotesOfMergeRequest: mergeRequest [ ofProject: mergeRequest project id. notes := results collect: [ :note | self parseNoteJson: note ]. - "notes := self parseNoteJson: results." + notes do: [ :tabNotes | tabNotes do: [ :note | note author: (self importUser: (note author at: #id)). - note name: note id asString ] ]. + note name: note id asString. + + note suggestions: (self getSuggestionsFromNote: note) + + ] ]. notes := notes flattened. notes := self glhModel addAll: notes unless: self blockOnIdEquality. notes := mergeRequest note addAll: notes unless: self blockOnIdEquality. - + + + ^ notes ] diff --git a/src/GitLabHealth-Model/GLHCommit.class.st b/src/GitLabHealth-Model/GLHCommit.class.st index 8e23d671..13d2c100 100644 --- a/src/GitLabHealth-Model/GLHCommit.class.st +++ b/src/GitLabHealth-Model/GLHCommit.class.st @@ -21,8 +21,8 @@ a commit attached to a repository |---| | `branch` | `GLHCommit` | `commits` | `GLHBranch` | | | `childCommits` | `GLHCommit` | `parentCommits` | `GLHCommit` | | -| `commitedMergeRequest` | `GLHCommit` | `mergedCommit` | `GLHMergeRequest` | | | `commitedMergeRequest` | `GLHCommit` | `mergeRequestCommit` | `GLHMergeRequest` | | +| `commitedMergeRequest` | `GLHCommit` | `mergedCommit` | `GLHMergeRequest` | | | `parentCommits` | `GLHCommit` | `childCommits` | `GLHCommit` | | | `squashedMergeRequest` | `GLHCommit` | `squashCommit` | `GLHMergeRequest` | | | `tag` | `GLHCommit` | `commit` | `GLHTag` | | diff --git a/src/GitLabHealth-Model/GLHIssue.class.st b/src/GitLabHealth-Model/GLHIssue.class.st index 2d6fc7bb..80320c00 100644 --- a/src/GitLabHealth-Model/GLHIssue.class.st +++ b/src/GitLabHealth-Model/GLHIssue.class.st @@ -27,8 +27,8 @@ an Issues help collaboration within a team to plan, track, and deliver work | `description` | `String` | nil | | | `due_date` | `Object` | nil | | | `id` | `Number` | nil | | -| `name` | `String` | nil | Basic name of the entity, not full reference.| | `name` | `String` | nil | | +| `name` | `String` | nil | Basic name of the entity, not full reference.| | `state` | `String` | nil | | | `updated_at` | `Object` | nil | | diff --git a/src/GitLabHealth-Model/GLHNote.class.st b/src/GitLabHealth-Model/GLHNote.class.st index b6a810a7..bd1efc57 100644 --- a/src/GitLabHealth-Model/GLHNote.class.st +++ b/src/GitLabHealth-Model/GLHNote.class.st @@ -11,6 +11,7 @@ a note (a diff) proposed in a Merge Request; can be accepted, modified or delete | `position` | `GLHNote` | `note` | `GLHNotePosition` | | | `position` | `GLHNote` | `note` | `GLHNotePosition` | | | `position` | `GLHNote` | `note` | `GLHNotePosition` | | +| `suggestions` | `GLHNote` | `note` | `GLHNoteSuggestion` | | ## Properties @@ -60,7 +61,8 @@ Class { '#imported => FMProperty', '#imported_from => FMProperty', '#mergeRequest => FMOne type: #GLHMergeRequest opposite: #note', - '#position => FMOne type: #GLHNotePosition opposite: #note' + '#position => FMOne type: #GLHNotePosition opposite: #note', + '#suggestions => FMOne type: #GLHNoteSuggestion opposite: #note' ], #category : #'GitLabHealth-Model-Entities' } @@ -300,6 +302,21 @@ GLHNote >> resolvable: anObject [ resolvable := anObject ] +{ #category : #accessing } +GLHNote >> suggestions [ + "Relation named: #suggestions type: #GLHNoteSuggestion opposite: #note" + + + ^ suggestions +] + +{ #category : #accessing } +GLHNote >> suggestions: anObject [ + + + suggestions := anObject +] + { #category : #accessing } GLHNote >> system [ diff --git a/src/GitLabHealth-Model/GLHNoteSuggestion.class.st b/src/GitLabHealth-Model/GLHNoteSuggestion.class.st index 46dc3c49..d913ac71 100644 --- a/src/GitLabHealth-Model/GLHNoteSuggestion.class.st +++ b/src/GitLabHealth-Model/GLHNoteSuggestion.class.st @@ -1,19 +1,24 @@ " suggestion of code made in a note +## Relations +====================== + +### Other +| Relation | Origin | Opposite | Type | Comment | +|---| +| `note` | `GLHNoteSuggestion` | `suggestions` | `GLHNote` | | + + ## Properties ====================== | Name | Type | Default value | Comment | |---| | `from_content` | `String` | nil | | -| `from_content` | `String` | nil | | -| `from_line` | `Number` | nil | | | `from_line` | `Number` | nil | | | `name` | `String` | nil | Basic name of the entity, not full reference.| | `to_content` | `String` | nil | | -| `to_content` | `String` | nil | | -| `to_line` | `Number` | nil | | | `to_line` | `Number` | nil | | " @@ -26,7 +31,8 @@ Class { '#from_line => FMProperty', '#to_line => FMProperty', '#from_content => FMProperty', - '#to_content => FMProperty' + '#to_content => FMProperty', + '#note => FMMany type: #GLHNote opposite: #suggestions' ], #category : #'GitLabHealth-Model-Entities' } @@ -40,6 +46,12 @@ GLHNoteSuggestion class >> annotation [ ^ self ] +{ #category : #adding } +GLHNoteSuggestion >> addNote: anObject [ + + ^ self note add: anObject +] + { #category : #accessing } GLHNoteSuggestion >> from_content [ @@ -68,6 +80,22 @@ GLHNoteSuggestion >> from_line: anObject [ from_line := anObject ] +{ #category : #accessing } +GLHNoteSuggestion >> note [ + "Relation named: #note type: #GLHNote opposite: #suggestions" + + + + ^ note +] + +{ #category : #accessing } +GLHNoteSuggestion >> note: anObject [ + + + note value: anObject +] + { #category : #accessing } GLHNoteSuggestion >> to_content [ From 109c98a7ef9f0c6fb4e6f276a8b62599683b92c6 Mon Sep 17 00:00:00 2001 From: Kilian B <60846047+knowbased@users.noreply.github.com> Date: Thu, 23 Oct 2025 14:19:43 +0200 Subject: [PATCH 11/16] feat: update model to have GLHNoteSuggestion --- .../GitlabModelImporter.class.st | 10 +++++++--- src/GitLabHealth-Model/GLHCommit.class.st | 2 +- src/GitLabHealth-Model/GLHJob.class.st | 2 +- src/GitLabHealth-Model/GLHNote.class.st | 11 +++++++++-- src/GitLabHealth-Model/GLHNoteSuggestion.class.st | 11 ++--------- 5 files changed, 20 insertions(+), 16 deletions(-) diff --git a/src/GitLabHealth-Model-Importer/GitlabModelImporter.class.st b/src/GitLabHealth-Model-Importer/GitlabModelImporter.class.st index 0ef59a42..0ae82664 100644 --- a/src/GitLabHealth-Model-Importer/GitlabModelImporter.class.st +++ b/src/GitLabHealth-Model-Importer/GitlabModelImporter.class.st @@ -379,21 +379,25 @@ GitlabModelImporter >> configureReaderForNotePosition: reader [ getter: [ ] setter: [ :notePosition :newLine | notePosition start_line: newLine. - notePosition start_line_type: 'new' ]. + notePosition start_line_type: 'new'. + notePosition end_line: newLine. + notePosition end_line_type: 'new'. ]. mapping mapProperty: #old_line getter: [ ] setter: [ :notePosition :oldLine | notePosition start_line: oldLine. - notePosition start_line_type: 'old' ]. + notePosition start_line_type: 'old'. + notePosition end_line: oldLine. + notePosition end_line_type: 'old'. + ]. mapping mapProperty: #line_range getter: [ ] setter: [ :notePosition :rawLineRange | rawLineRange - ifNil: [ notePosition end_line = notePosition start_line ] ifNotNil: [ | start startType startLine end endType endLine | start := rawLineRange at: #start. diff --git a/src/GitLabHealth-Model/GLHCommit.class.st b/src/GitLabHealth-Model/GLHCommit.class.st index 13d2c100..8e23d671 100644 --- a/src/GitLabHealth-Model/GLHCommit.class.st +++ b/src/GitLabHealth-Model/GLHCommit.class.st @@ -21,8 +21,8 @@ a commit attached to a repository |---| | `branch` | `GLHCommit` | `commits` | `GLHBranch` | | | `childCommits` | `GLHCommit` | `parentCommits` | `GLHCommit` | | -| `commitedMergeRequest` | `GLHCommit` | `mergeRequestCommit` | `GLHMergeRequest` | | | `commitedMergeRequest` | `GLHCommit` | `mergedCommit` | `GLHMergeRequest` | | +| `commitedMergeRequest` | `GLHCommit` | `mergeRequestCommit` | `GLHMergeRequest` | | | `parentCommits` | `GLHCommit` | `childCommits` | `GLHCommit` | | | `squashedMergeRequest` | `GLHCommit` | `squashCommit` | `GLHMergeRequest` | | | `tag` | `GLHCommit` | `commit` | `GLHTag` | | diff --git a/src/GitLabHealth-Model/GLHJob.class.st b/src/GitLabHealth-Model/GLHJob.class.st index b50f9f3d..bed62ed5 100644 --- a/src/GitLabHealth-Model/GLHJob.class.st +++ b/src/GitLabHealth-Model/GLHJob.class.st @@ -20,8 +20,8 @@ A CI Job | `allow_failure` | `Boolean` | nil | | | `duration` | `Object` | nil | | | `id` | `Number` | nil | | -| `name` | `String` | nil | | | `name` | `String` | nil | Basic name of the entity, not full reference.| +| `name` | `String` | nil | | | `ref` | `String` | nil | | | `web_url` | `String` | nil | | diff --git a/src/GitLabHealth-Model/GLHNote.class.st b/src/GitLabHealth-Model/GLHNote.class.st index bd1efc57..89c1a2bf 100644 --- a/src/GitLabHealth-Model/GLHNote.class.st +++ b/src/GitLabHealth-Model/GLHNote.class.st @@ -62,7 +62,7 @@ Class { '#imported_from => FMProperty', '#mergeRequest => FMOne type: #GLHMergeRequest opposite: #note', '#position => FMOne type: #GLHNotePosition opposite: #note', - '#suggestions => FMOne type: #GLHNoteSuggestion opposite: #note' + '#suggestions => FMMany type: #GLHNoteSuggestion opposite: #note' ], #category : #'GitLabHealth-Model-Entities' } @@ -76,6 +76,12 @@ GLHNote class >> annotation [ ^ self ] +{ #category : #adding } +GLHNote >> addSuggestion: anObject [ + + ^ self suggestions add: anObject +] + { #category : #accessing } GLHNote >> attachment [ @@ -307,6 +313,7 @@ GLHNote >> suggestions [ "Relation named: #suggestions type: #GLHNoteSuggestion opposite: #note" + ^ suggestions ] @@ -314,7 +321,7 @@ GLHNote >> suggestions [ GLHNote >> suggestions: anObject [ - suggestions := anObject + suggestions value: anObject ] { #category : #accessing } diff --git a/src/GitLabHealth-Model/GLHNoteSuggestion.class.st b/src/GitLabHealth-Model/GLHNoteSuggestion.class.st index d913ac71..5f6edc58 100644 --- a/src/GitLabHealth-Model/GLHNoteSuggestion.class.st +++ b/src/GitLabHealth-Model/GLHNoteSuggestion.class.st @@ -32,7 +32,7 @@ Class { '#to_line => FMProperty', '#from_content => FMProperty', '#to_content => FMProperty', - '#note => FMMany type: #GLHNote opposite: #suggestions' + '#note => FMOne type: #GLHNote opposite: #suggestions' ], #category : #'GitLabHealth-Model-Entities' } @@ -46,12 +46,6 @@ GLHNoteSuggestion class >> annotation [ ^ self ] -{ #category : #adding } -GLHNoteSuggestion >> addNote: anObject [ - - ^ self note add: anObject -] - { #category : #accessing } GLHNoteSuggestion >> from_content [ @@ -85,7 +79,6 @@ GLHNoteSuggestion >> note [ "Relation named: #note type: #GLHNote opposite: #suggestions" - ^ note ] @@ -93,7 +86,7 @@ GLHNoteSuggestion >> note [ GLHNoteSuggestion >> note: anObject [ - note value: anObject + note := anObject ] { #category : #accessing } From 5234e1fde6167b004df1a275c42d18ecda559315 Mon Sep 17 00:00:00 2001 From: HLAD Nicolas Date: Thu, 23 Oct 2025 22:14:02 +0200 Subject: [PATCH 12/16] incredibly stupid fix that should get me fired --- .../GitlabModelImporterTest.class.st | 2 +- .../GitlabModelImporter.class.st | 62 +++++++++++++------ 2 files changed, 45 insertions(+), 19 deletions(-) diff --git a/src/GitLabHealth-Model-Importer-Tests/GitlabModelImporterTest.class.st b/src/GitLabHealth-Model-Importer-Tests/GitlabModelImporterTest.class.st index 06fa479d..bad4ad39 100644 --- a/src/GitLabHealth-Model-Importer-Tests/GitlabModelImporterTest.class.st +++ b/src/GitLabHealth-Model-Importer-Tests/GitlabModelImporterTest.class.st @@ -647,7 +647,7 @@ GitlabModelImporterTest >> testParseNote [ "confidential": false, "internal": false }]'. - notesArray := importer parseNoteJson: jsonNote. + notesArray := importer parseNotesResult: jsonNote. note := notesArray first. self assert: notesArray size equals: 1. self assert: note body equals: 'Comment for MR' diff --git a/src/GitLabHealth-Model-Importer/GitlabModelImporter.class.st b/src/GitLabHealth-Model-Importer/GitlabModelImporter.class.st index 0ae82664..c5d3e7f5 100644 --- a/src/GitLabHealth-Model-Importer/GitlabModelImporter.class.st +++ b/src/GitLabHealth-Model-Importer/GitlabModelImporter.class.st @@ -353,12 +353,19 @@ GitlabModelImporter >> configureReaderForMergeRequest: reader [ object cacheAt: #mergeUserID put: (value at: #id) ] ] ] ] -{ #category : #'private - parsing' } +{ #category : #'private - configure reader' } GitlabModelImporter >> configureReaderForNote: reader [ super configureReaderForNote: reader. reader for: GLHNote do: [ :mapping | + + mapping + mapProperty: #author + getter: [ ] + setter: [ :note :rawUser | + note cacheAt: #userID put: (rawUser at: #id) ]. + (mapping mapInstVar: #created_at) valueSchema: DateAndTime. (mapping mapInstVar: #updated_at) valueSchema: DateAndTime. @@ -550,19 +557,22 @@ GitlabModelImporter >> detectEntityType: aType overAttribut: aSelector equalTo: GitlabModelImporter >> getSuggestionsFromNote: glhNote [ | suggestions suggestion fromLine toLine suggestionsInfo | + glhNote position ifNil: [ ^ { } ]. suggestions := MooseGroup new. + suggestionsInfo := self getSuggestionsInfoFromString: glhNote body. ^ suggestionsInfo collect: [ :suggestionInfo | suggestion := GLHNoteSuggestion new. - fromLine := glhNote position end_line - (suggestionInfo at: #minus). + fromLine := glhNote position end_line + - (suggestionInfo at: #minus). toLine := glhNote position end_line + (suggestionInfo at: #plus). suggestion from_line: fromLine. suggestion to_line: toLine. - suggestion to_content: (suggestionInfo at: #content) ]. - + suggestion to_content: (suggestionInfo at: #content). + suggestion ] ] { #category : #'import - notes' } @@ -570,15 +580,15 @@ GitlabModelImporter >> getSuggestionsInfoFromString: string [ | suggestionsInfo regex result regex2 suggestionInfo | suggestionsInfo := OrderedCollection new. - regex := '```suggestion' asRegex. result := regex matchesIn: string. result isEmpty ifTrue: [ ^ suggestionsInfo ]. + result size > 1 ifTrue: [ | start end firstPart secondPart | start := string findString: '```suggestion'. - end := (string findString: '```' startingAt: start +2) + 2. + end := (string findString: '```' startingAt: start + 2) + 2. firstPart := string copyFrom: 1 to: end. secondPart := string copyFrom: end to: string size. @@ -1514,22 +1524,38 @@ GitlabModelImporter >> importNotesOfMergeRequest: mergeRequest [ allInMergeRequest: mergeRequest iid ofProject: mergeRequest project id. - notes := results collect: [ :note | self parseNoteJson: note ]. - - notes do: [ :tabNotes | - tabNotes do: [ :note | - note author: (self importUser: (note author at: #id)). - note name: note id asString. + notes := (results collect: [ :rawNotes | + |items| + + items := self parseNotesResult: rawNotes. + (items select: [:item | item position isNotNil] ) do: [ :item | + |position| - note suggestions: (self getSuggestionsFromNote: note) + position := self glhModel add: item position unless: [ :existing :new | new note isNotNil and: [existing note id = new note id] ]. + position note: item. - ] ]. - notes := notes flattened. - notes := self glhModel addAll: notes unless: self blockOnIdEquality. + ]. + items. + ]) + flattened. + notes := mergeRequest note addAll: notes unless: self blockOnIdEquality. - + notes := self glhModel addAll: notes unless: self blockOnIdEquality. + + notes do: [ :note | + " self haltIf: [ note id = 553666 ]." + note + cacheAt: #userID + ifPresent: [ :id | note author: (self importUser: id) ]. + note name: note id asString. + + note suggestions: (self getSuggestionsFromNote: note) ]. + + + + ^ notes @@ -2041,7 +2067,7 @@ GitlabModelImporter >> parseMergeRequestsResult: result [ ] { #category : #'private - parsing' } -GitlabModelImporter >> parseNoteJson: results [ +GitlabModelImporter >> parseNotesResult: results [ | reader | "Créer un lecteur JSON" From ae9317dd4368fd54086f5e028b34f5a3766c5a25 Mon Sep 17 00:00:00 2001 From: Kilian B <60846047+knowbased@users.noreply.github.com> Date: Fri, 24 Oct 2025 16:24:08 +0200 Subject: [PATCH 13/16] refactor: rename get for import in method name --- .../GitlabModelImporterTest.class.st | 300 +++++++++--------- .../GitlabModelImporter.class.st | 158 +++++---- src/GitLabHealth-Model/GLHCommit.class.st | 2 +- src/GitLabHealth-Model/GLHIssue.class.st | 2 +- src/GitLabHealth-Model/GLHJob.class.st | 2 +- src/GitLabHealth-Model/GLHUser.class.st | 2 +- 6 files changed, 231 insertions(+), 235 deletions(-) diff --git a/src/GitLabHealth-Model-Importer-Tests/GitlabModelImporterTest.class.st b/src/GitLabHealth-Model-Importer-Tests/GitlabModelImporterTest.class.st index bad4ad39..3bd54796 100644 --- a/src/GitLabHealth-Model-Importer-Tests/GitlabModelImporterTest.class.st +++ b/src/GitLabHealth-Model-Importer-Tests/GitlabModelImporterTest.class.st @@ -221,156 +221,6 @@ GitlabModelImporterTest >> testCompleteImportsOfRepository [ self assert: element branches anyOne class equals: GLHBranch ] -{ #category : #tests } -GitlabModelImporterTest >> testGetSuggestionsFromNote [ - - | body position glhNote result suggestion | - body := ' - test - ```suggestion:-0+5 - content -```'. - - position := GLHNotePosition new - start_line: 2; - end_line: 2. - glhNote := GLHNote new - body: body; - position: position. - - - result := importer getSuggestionsFromNote: glhNote. - - self assert: result size equals: 1. - - suggestion := result first. - self assert: suggestion from_line equals: 2. - self assert: suggestion to_line equals: 7. - self assert: suggestion to_content trim equals: 'content'. -] - -{ #category : #tests } -GitlabModelImporterTest >> testGetSuggestionsFromNoteWithDifferentStartAndEndLine [ - - | body position glhNote result suggestion | - body := ' - test - ```suggestion:-2+5 - content -```'. - - position := GLHNotePosition new - start_line: 2; - end_line: 5. - glhNote := GLHNote new - body: body; - position: position. - - - result := importer getSuggestionsFromNote: glhNote. - - self assert: result size equals: 1. - - suggestion := result first. - self assert: suggestion from_line equals: 3. - self assert: suggestion to_line equals: 10. - self assert: suggestion to_content trim equals: 'content' -] - -{ #category : #tests } -GitlabModelImporterTest >> testGetSuggestionsFromNoteWithMultipleSuggestions [ - - | body position glhNote result suggestion suggestion2 | - body := ' - test - ```suggestion:-2+5 - content -``` - -```suggestion:-0+0 -```'. - - position := GLHNotePosition new - start_line: 2; - end_line: 5. - glhNote := GLHNote new - body: body; - position: position. - - - result := importer getSuggestionsFromNote: glhNote. - - self assert: result size equals: 2. - - suggestion := result first. - self assert: suggestion from_line equals: 3. - self assert: suggestion to_line equals: 10. - self assert: suggestion to_content trim equals: 'content'. - - suggestion2 := result at: 2. - self assert: suggestion2 from_line equals: 5. - self assert: suggestion2 to_line equals: 5. - self assert: suggestion2 to_content trim equals: '' -] - -{ #category : #tests } -GitlabModelImporterTest >> testGetSuggestionsInfoFromString [ - - | string result suggestion | - string := ' - some content - ```suggestion:-0+2 - test -```'. - - result := importer getSuggestionsInfoFromString: string. - - self assert: result size equals: 1. - suggestion := result first. - self assert: (suggestion at: #minus) equals: 0. - self assert: (suggestion at: #plus) equals: 2. - self assert: (suggestion at: #content) trim equals: 'test' -] - -{ #category : #tests } -GitlabModelImporterTest >> testGetSuggestionsInfoFromStringWithMultipleSuggestion [ - - | string result suggestion suggestion2 | - string := '```suggestion:-0+2 - test -``` - -```suggestion:-2+4 - -oui - -```'. - - result := importer getSuggestionsInfoFromString: string. - - self assert: result size equals: 2. - suggestion := result first. - self assert: (suggestion at: #minus) equals: 0. - self assert: (suggestion at: #plus) equals: 2. - self assert: (suggestion at: #content) trim equals: 'test'. - - suggestion2 := result at: 2. - self assert: (suggestion2 at: #minus) equals: 2. - self assert: (suggestion2 at: #plus) equals: 4. - self assert: (suggestion2 at: #content) trim equals: 'oui' -] - -{ #category : #tests } -GitlabModelImporterTest >> testGetSuggestionsInfoFromStringWithNoSuggestions [ - - | string result | - string := 'a normal comment'. - - result := importer getSuggestionsInfoFromString: string. - - self assert: result size equals: 0. -] - { #category : #'tests - commits' } GitlabModelImporterTest >> testImportCommitsFromTagToTagNoCommits [ @@ -536,6 +386,156 @@ GitlabModelImporterTest >> testImportProjects [ self assert: element repository isNil. ] +{ #category : #tests } +GitlabModelImporterTest >> testImportSuggestionsFromNote [ + + | body position glhNote result suggestion | + body := ' + test + ```suggestion:-0+5 + content +```'. + + position := GLHNotePosition new + start_line: 2; + end_line: 2. + glhNote := GLHNote new + body: body; + position: position. + + + result := importer importSuggestionsFromNote: glhNote. + + self assert: result size equals: 1. + + suggestion := result first. + self assert: suggestion from_line equals: 2. + self assert: suggestion to_line equals: 7. + self assert: suggestion to_content trim equals: 'content' +] + +{ #category : #tests } +GitlabModelImporterTest >> testImportSuggestionsFromNoteWithDifferentStartAndEndLine [ + + | body position glhNote result suggestion | + body := ' + test + ```suggestion:-2+5 + content +```'. + + position := GLHNotePosition new + start_line: 2; + end_line: 5. + glhNote := GLHNote new + body: body; + position: position. + + + result := importer importSuggestionsFromNote: glhNote. + + self assert: result size equals: 1. + + suggestion := result first. + self assert: suggestion from_line equals: 3. + self assert: suggestion to_line equals: 10. + self assert: suggestion to_content trim equals: 'content' +] + +{ #category : #tests } +GitlabModelImporterTest >> testImportSuggestionsFromNoteWithMultipleSuggestions [ + + | body position glhNote result suggestion suggestion2 | + body := ' + test + ```suggestion:-2+5 + content +``` + +```suggestion:-0+0 +```'. + + position := GLHNotePosition new + start_line: 2; + end_line: 5. + glhNote := GLHNote new + body: body; + position: position. + + + result := importer importSuggestionsFromNote: glhNote. + + self assert: result size equals: 2. + + suggestion := result first. + self assert: suggestion from_line equals: 3. + self assert: suggestion to_line equals: 10. + self assert: suggestion to_content trim equals: 'content'. + + suggestion2 := result at: 2. + self assert: suggestion2 from_line equals: 5. + self assert: suggestion2 to_line equals: 5. + self assert: suggestion2 to_content trim equals: '' +] + +{ #category : #tests } +GitlabModelImporterTest >> testImportSuggestionsInfoFromString [ + + | string result suggestion | + string := ' + some content + ```suggestion:-0+2 + test +```'. + + result := importer importSuggestionsInfoFromString: string. + + self assert: result size equals: 1. + suggestion := result first. + self assert: (suggestion at: #minus) equals: 0. + self assert: (suggestion at: #plus) equals: 2. + self assert: (suggestion at: #content) trim equals: 'test' +] + +{ #category : #tests } +GitlabModelImporterTest >> testImportSuggestionsInfoFromStringWithMultipleSuggestion [ + + | string result suggestion suggestion2 | + string := '```suggestion:-0+2 + test +``` + +```suggestion:-2+4 + +oui + +```'. + + result := importer importSuggestionsInfoFromString: string. + + self assert: result size equals: 2. + suggestion := result first. + self assert: (suggestion at: #minus) equals: 0. + self assert: (suggestion at: #plus) equals: 2. + self assert: (suggestion at: #content) trim equals: 'test'. + + suggestion2 := result at: 2. + self assert: (suggestion2 at: #minus) equals: 2. + self assert: (suggestion2 at: #plus) equals: 4. + self assert: (suggestion2 at: #content) trim equals: 'oui' +] + +{ #category : #tests } +GitlabModelImporterTest >> testImportSuggestionsInfoFromStringWithNoSuggestions [ + + | string result | + string := 'a normal comment'. + + result := importer importSuggestionsInfoFromString: string. + + self assert: result size equals: 0. +] + { #category : #'tests - tags' } GitlabModelImporterTest >> testImportTagsForProject [ diff --git a/src/GitLabHealth-Model-Importer/GitlabModelImporter.class.st b/src/GitLabHealth-Model-Importer/GitlabModelImporter.class.st index c5d3e7f5..9f8e7e4a 100644 --- a/src/GitLabHealth-Model-Importer/GitlabModelImporter.class.st +++ b/src/GitLabHealth-Model-Importer/GitlabModelImporter.class.st @@ -553,64 +553,6 @@ GitlabModelImporter >> detectEntityType: aType overAttribut: aSelector equalTo: (entity perform: aSelector) = value ] ifNone: [ nil ]. ] -{ #category : #'import - notes' } -GitlabModelImporter >> getSuggestionsFromNote: glhNote [ - - | suggestions suggestion fromLine toLine suggestionsInfo | - - glhNote position ifNil: [ ^ { } ]. - suggestions := MooseGroup new. - - - suggestionsInfo := self getSuggestionsInfoFromString: glhNote body. - - ^ suggestionsInfo collect: [ :suggestionInfo | - suggestion := GLHNoteSuggestion new. - fromLine := glhNote position end_line - - (suggestionInfo at: #minus). - toLine := glhNote position end_line + (suggestionInfo at: #plus). - suggestion from_line: fromLine. - suggestion to_line: toLine. - suggestion to_content: (suggestionInfo at: #content). - suggestion ] -] - -{ #category : #'import - notes' } -GitlabModelImporter >> getSuggestionsInfoFromString: string [ - - | suggestionsInfo regex result regex2 suggestionInfo | - suggestionsInfo := OrderedCollection new. - regex := '```suggestion' asRegex. - result := regex matchesIn: string. - - result isEmpty ifTrue: [ ^ suggestionsInfo ]. - - result size > 1 ifTrue: [ - | start end firstPart secondPart | - start := string findString: '```suggestion'. - end := (string findString: '```' startingAt: start + 2) + 2. - - firstPart := string copyFrom: 1 to: end. - secondPart := string copyFrom: end to: string size. - - suggestionsInfo addAll: - (self getSuggestionsInfoFromString: firstPart). - suggestionsInfo addAll: - (self getSuggestionsInfoFromString: secondPart). - ^ suggestionsInfo ]. - - regex2 := '```suggestion\:-(\d+)\+(\d+)(.*)```' asRegex. - regex2 search: string. - - suggestionInfo := { - (#minus -> (regex2 subexpression: 2) asNumber). - (#plus -> (regex2 subexpression: 3) asNumber). - (#content -> (regex2 subexpression: 4)) } - asDictionary. - - ^ { suggestionInfo } -] - { #category : #accessing } GitlabModelImporter >> glhApi [ @@ -1524,39 +1466,32 @@ GitlabModelImporter >> importNotesOfMergeRequest: mergeRequest [ allInMergeRequest: mergeRequest iid ofProject: mergeRequest project id. - notes := (results collect: [ :rawNotes | - |items| - - items := self parseNotesResult: rawNotes. - (items select: [:item | item position isNotNil] ) do: [ :item | - |position| - - position := self glhModel add: item position unless: [ :existing :new | new note isNotNil and: [existing note id = new note id] ]. - position note: item. - - ]. - items. - ]) - flattened. - + notes := (results collect: [ :rawNotes | + | items | + items := self parseNotesResult: rawNotes. + (items select: [ :item | item position isNotNil ]) do: [ + :item | + | position | + position := self glhModel + add: item position + unless: [ :existing :new | + new note isNotNil and: [ + existing note id = new note id ] ]. + position note: item ]. + items ]) flattened. + notes := mergeRequest note addAll: notes unless: self blockOnIdEquality. notes := self glhModel addAll: notes unless: self blockOnIdEquality. - notes do: [ :note | - " self haltIf: [ note id = 553666 ]." + notes do: [ :note | " self haltIf: [ note id = 553666 ]." note cacheAt: #userID ifPresent: [ :id | note author: (self importUser: id) ]. note name: note id asString. - note suggestions: (self getSuggestionsFromNote: note) ]. - - - - - + note suggestions: (self importSuggestionsFromNote: note) ]. ^ notes ] @@ -1762,6 +1697,67 @@ GitlabModelImporter >> importSZZFromCommit: aCommit [ ^ szzCommits ] +{ #category : #'import - notes' } +GitlabModelImporter >> importSuggestionsFromNote: glhNote [ + + | suggestions suggestion fromLine toLine suggestionsInfo | + glhNote position ifNil: [ ^ { } ]. + suggestions := MooseGroup new. + + + suggestionsInfo := self importSuggestionsInfoFromString: glhNote body. + + suggestions := suggestionsInfo collect: [ :suggestionInfo | + suggestion := GLHNoteSuggestion new. + fromLine := glhNote position end_line + - (suggestionInfo at: #minus). + toLine := glhNote position end_line + (suggestionInfo at: #plus). + suggestion from_line: fromLine. + suggestion to_line: toLine. + suggestion to_content: (suggestionInfo at: #content). + suggestion ]. + + ^self glhModel addAll: suggestions unless: self blockOnIdEquality. + + +] + +{ #category : #'import - notes' } +GitlabModelImporter >> importSuggestionsInfoFromString: string [ + + | suggestionsInfo regex result regex2 suggestionInfo | + suggestionsInfo := OrderedCollection new. + regex := '```suggestion' asRegex. + result := regex matchesIn: string. + + result isEmpty ifTrue: [ ^ suggestionsInfo ]. + + result size > 1 ifTrue: [ + | start end firstPart secondPart | + start := string findString: '```suggestion'. + end := (string findString: '```' startingAt: start + 2) + 2. + + firstPart := string copyFrom: 1 to: end. + secondPart := string copyFrom: end to: string size. + + suggestionsInfo addAll: + (self importSuggestionsInfoFromString: firstPart). + suggestionsInfo addAll: + (self importSuggestionsInfoFromString: secondPart). + ^ suggestionsInfo ]. + + regex2 := '```suggestion\:-(\d+)\+(\d+)(.*)```' asRegex. + regex2 search: string. + + suggestionInfo := { + (#minus -> (regex2 subexpression: 2) asNumber). + (#plus -> (regex2 subexpression: 3) asNumber). + (#content -> (regex2 subexpression: 4)) } + asDictionary. + + ^ { suggestionInfo } +] + { #category : #'import - tags' } GitlabModelImporter >> importTagsForProject: aProject [ |results tags | diff --git a/src/GitLabHealth-Model/GLHCommit.class.st b/src/GitLabHealth-Model/GLHCommit.class.st index 8e23d671..13d2c100 100644 --- a/src/GitLabHealth-Model/GLHCommit.class.st +++ b/src/GitLabHealth-Model/GLHCommit.class.st @@ -21,8 +21,8 @@ a commit attached to a repository |---| | `branch` | `GLHCommit` | `commits` | `GLHBranch` | | | `childCommits` | `GLHCommit` | `parentCommits` | `GLHCommit` | | -| `commitedMergeRequest` | `GLHCommit` | `mergedCommit` | `GLHMergeRequest` | | | `commitedMergeRequest` | `GLHCommit` | `mergeRequestCommit` | `GLHMergeRequest` | | +| `commitedMergeRequest` | `GLHCommit` | `mergedCommit` | `GLHMergeRequest` | | | `parentCommits` | `GLHCommit` | `childCommits` | `GLHCommit` | | | `squashedMergeRequest` | `GLHCommit` | `squashCommit` | `GLHMergeRequest` | | | `tag` | `GLHCommit` | `commit` | `GLHTag` | | diff --git a/src/GitLabHealth-Model/GLHIssue.class.st b/src/GitLabHealth-Model/GLHIssue.class.st index 80320c00..2d6fc7bb 100644 --- a/src/GitLabHealth-Model/GLHIssue.class.st +++ b/src/GitLabHealth-Model/GLHIssue.class.st @@ -27,8 +27,8 @@ an Issues help collaboration within a team to plan, track, and deliver work | `description` | `String` | nil | | | `due_date` | `Object` | nil | | | `id` | `Number` | nil | | -| `name` | `String` | nil | | | `name` | `String` | nil | Basic name of the entity, not full reference.| +| `name` | `String` | nil | | | `state` | `String` | nil | | | `updated_at` | `Object` | nil | | diff --git a/src/GitLabHealth-Model/GLHJob.class.st b/src/GitLabHealth-Model/GLHJob.class.st index bed62ed5..b50f9f3d 100644 --- a/src/GitLabHealth-Model/GLHJob.class.st +++ b/src/GitLabHealth-Model/GLHJob.class.st @@ -20,8 +20,8 @@ A CI Job | `allow_failure` | `Boolean` | nil | | | `duration` | `Object` | nil | | | `id` | `Number` | nil | | -| `name` | `String` | nil | Basic name of the entity, not full reference.| | `name` | `String` | nil | | +| `name` | `String` | nil | Basic name of the entity, not full reference.| | `ref` | `String` | nil | | | `web_url` | `String` | nil | | diff --git a/src/GitLabHealth-Model/GLHUser.class.st b/src/GitLabHealth-Model/GLHUser.class.st index 20a41c87..d6648af4 100644 --- a/src/GitLabHealth-Model/GLHUser.class.st +++ b/src/GitLabHealth-Model/GLHUser.class.st @@ -51,8 +51,8 @@ A GitLab User | `job_title` | `String` | nil | | | `linkedin` | `String` | nil | | | `location` | `String` | nil | | -| `name` | `String` | nil | | | `name` | `String` | nil | Basic name of the entity, not full reference.| +| `name` | `String` | nil | | | `organization` | `String` | nil | | | `pronouns` | `String` | nil | | | `public_email` | `String` | nil | | From a45470552c0574a88d917ed15eb65e61b707a88f Mon Sep 17 00:00:00 2001 From: Kilian B <60846047+knowbased@users.noreply.github.com> Date: Mon, 27 Oct 2025 10:02:49 +0100 Subject: [PATCH 14/16] fix: error in import suggestion --- .../GitlabModelImporter.class.st | 23 +++++++++---------- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/src/GitLabHealth-Model-Importer/GitlabModelImporter.class.st b/src/GitLabHealth-Model-Importer/GitlabModelImporter.class.st index 9f8e7e4a..cf78cb76 100644 --- a/src/GitLabHealth-Model-Importer/GitlabModelImporter.class.st +++ b/src/GitLabHealth-Model-Importer/GitlabModelImporter.class.st @@ -1708,18 +1708,17 @@ GitlabModelImporter >> importSuggestionsFromNote: glhNote [ suggestionsInfo := self importSuggestionsInfoFromString: glhNote body. suggestions := suggestionsInfo collect: [ :suggestionInfo | - suggestion := GLHNoteSuggestion new. - fromLine := glhNote position end_line - - (suggestionInfo at: #minus). - toLine := glhNote position end_line + (suggestionInfo at: #plus). - suggestion from_line: fromLine. - suggestion to_line: toLine. - suggestion to_content: (suggestionInfo at: #content). - suggestion ]. - - ^self glhModel addAll: suggestions unless: self blockOnIdEquality. - - + suggestion := GLHNoteSuggestion new. + fromLine := glhNote position end_line + - (suggestionInfo at: #minus). + toLine := glhNote position end_line + + (suggestionInfo at: #plus). + suggestion from_line: fromLine. + suggestion to_line: toLine. + suggestion to_content: (suggestionInfo at: #content). + suggestion ]. + + ^ suggestions ] { #category : #'import - notes' } From 51586ed0ccedfe33fe80cab778076f9ea3453c86 Mon Sep 17 00:00:00 2001 From: Kilian B <60846047+knowbased@users.noreply.github.com> Date: Mon, 27 Oct 2025 15:19:32 +0100 Subject: [PATCH 15/16] refactor: add block equality for suggestion --- .../GitlabModelImporter.class.st | 6 +++++- .../GitModelImporter.class.st | 14 ++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/GitLabHealth-Model-Importer/GitlabModelImporter.class.st b/src/GitLabHealth-Model-Importer/GitlabModelImporter.class.st index cf78cb76..3245c1e5 100644 --- a/src/GitLabHealth-Model-Importer/GitlabModelImporter.class.st +++ b/src/GitLabHealth-Model-Importer/GitlabModelImporter.class.st @@ -1717,8 +1717,12 @@ GitlabModelImporter >> importSuggestionsFromNote: glhNote [ suggestion to_line: toLine. suggestion to_content: (suggestionInfo at: #content). suggestion ]. + + 1 halt. - ^ suggestions + ^ glhModel + addAll: suggestions + unless: self blockForNoteSuggestionEquality ] { #category : #'import - notes' } diff --git a/src/GitProjectHealth-Model-Importer/GitModelImporter.class.st b/src/GitProjectHealth-Model-Importer/GitModelImporter.class.st index 636decfd..e0e2bfaf 100644 --- a/src/GitProjectHealth-Model-Importer/GitModelImporter.class.st +++ b/src/GitProjectHealth-Model-Importer/GitModelImporter.class.st @@ -159,6 +159,20 @@ GitModelImporter >> blockForDiffRangeEquality [ existing newLineRange = new newLineRange ] ] ] ] +{ #category : #equality } +GitModelImporter >> blockForNoteSuggestionEquality [ + + +^ [ :existing :new | + | sameLine sameNote sameContent | + sameLine := existing to_line = new to_line. + sameNote := existing note id = new note id. + sameContent := existing to_content = new to_content. + sameLine and: (sameNote and: sameContent) + + ] +] + { #category : #equality } GitModelImporter >> blockOnIdEquality [ From 3a11924c3bb911aa1397211d55092ee5ad3b9b5c Mon Sep 17 00:00:00 2001 From: Kilian B <60846047+knowbased@users.noreply.github.com> Date: Mon, 27 Oct 2025 15:29:03 +0100 Subject: [PATCH 16/16] refactor: change import note --- .../GitlabModelImporter.class.st | 6 +----- src/GitLabHealth-Model/GLHIssue.class.st | 2 +- src/GitLabHealth-Model/GLHJob.class.st | 2 +- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/GitLabHealth-Model-Importer/GitlabModelImporter.class.st b/src/GitLabHealth-Model-Importer/GitlabModelImporter.class.st index 3245c1e5..cf78cb76 100644 --- a/src/GitLabHealth-Model-Importer/GitlabModelImporter.class.st +++ b/src/GitLabHealth-Model-Importer/GitlabModelImporter.class.st @@ -1717,12 +1717,8 @@ GitlabModelImporter >> importSuggestionsFromNote: glhNote [ suggestion to_line: toLine. suggestion to_content: (suggestionInfo at: #content). suggestion ]. - - 1 halt. - ^ glhModel - addAll: suggestions - unless: self blockForNoteSuggestionEquality + ^ suggestions ] { #category : #'import - notes' } diff --git a/src/GitLabHealth-Model/GLHIssue.class.st b/src/GitLabHealth-Model/GLHIssue.class.st index 2d6fc7bb..80320c00 100644 --- a/src/GitLabHealth-Model/GLHIssue.class.st +++ b/src/GitLabHealth-Model/GLHIssue.class.st @@ -27,8 +27,8 @@ an Issues help collaboration within a team to plan, track, and deliver work | `description` | `String` | nil | | | `due_date` | `Object` | nil | | | `id` | `Number` | nil | | -| `name` | `String` | nil | Basic name of the entity, not full reference.| | `name` | `String` | nil | | +| `name` | `String` | nil | Basic name of the entity, not full reference.| | `state` | `String` | nil | | | `updated_at` | `Object` | nil | | diff --git a/src/GitLabHealth-Model/GLHJob.class.st b/src/GitLabHealth-Model/GLHJob.class.st index b50f9f3d..bed62ed5 100644 --- a/src/GitLabHealth-Model/GLHJob.class.st +++ b/src/GitLabHealth-Model/GLHJob.class.st @@ -20,8 +20,8 @@ A CI Job | `allow_failure` | `Boolean` | nil | | | `duration` | `Object` | nil | | | `id` | `Number` | nil | | -| `name` | `String` | nil | | | `name` | `String` | nil | Basic name of the entity, not full reference.| +| `name` | `String` | nil | | | `ref` | `String` | nil | | | `web_url` | `String` | nil | |