From 928b4934f46dce4214095e0f92e8640743e02c05 Mon Sep 17 00:00:00 2001 From: Sven Van Caekenberghe Date: Tue, 5 Nov 2024 15:59:17 +0100 Subject: [PATCH] Add PureGitMethodVersions [feenkcom/gtoolkit#4147] --- .../PureGitMethodVersions.class.st | 100 ++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 src/Iceberg-Git-CLI/PureGitMethodVersions.class.st diff --git a/src/Iceberg-Git-CLI/PureGitMethodVersions.class.st b/src/Iceberg-Git-CLI/PureGitMethodVersions.class.st new file mode 100644 index 0000000..052bad3 --- /dev/null +++ b/src/Iceberg-Git-CLI/PureGitMethodVersions.class.st @@ -0,0 +1,100 @@ +" +I hold all modifications to a specific method in a git repository +" +Class { + #name : #PureGitMethodVersions, + #superclass : #PureGitRepositoryObject, + #instVars : [ + 'method', + 'versions' + ], + #category : #'Iceberg-Git-CLI-Pure' +} + +{ #category : #'instance creation' } +PureGitMethodVersions class >> with: aCompiledMethod [ + ^ self new + method: aCompiledMethod; + yourself +] + +{ #category : #private } +PureGitMethodVersions >> computeVersions [ + | packageName organization className selector classPath gitFile snapshots definitions uniqueDefinitions previous | + packageName := method package name. + organization := MCOrganizationDefinition categories: {packageName}. + className := method origin instanceSide name. + selector := method selector. + classPath := packageName , '/' , className , self tonelMethodClassExtension. + gitFile := repository resolveFilePath: repository srcPath , '/' , classPath. + snapshots := gitFile logReverse collect: [ :commit | | snapshot commitDefinitions | + commitDefinitions := TonelParser parseString: commit contentsByFilesystem. + commitDefinitions do: [ :definition | + definition isMethodDefinition ifTrue: [ definition setTimeStamp: commit ] ]. + snapshot := MCSnapshot fromDefinitions: commitDefinitions , { organization }. + snapshot ]. + definitions := snapshots toArray wait + flatCollect: [ :snapshot | + snapshot definitions + select: [ :definition | + definition isMethodDefinition + and: [ definition className = className + and: [ definition selector = selector ] ] ] ]. + uniqueDefinitions := OrderedCollection new. + definitions do: [ :each | uniqueDefinitions addIfNotPresent: each ]. + previous := nil. + ^ uniqueDefinitions collect: [ :definition | | diff | + diff := GtDiffBuilder + computeDifferencesFrom: (previous ifNil: [ String empty ] ifNotNil: [previous diffSource ]) + to: definition diffSource + using: GtSmaCCDiffSplitter forPharo. + previous := definition. + definition -> diff ] +] + +{ #category : #private } +PureGitMethodVersions >> findMethodRepository [ + | iceRepository | + iceRepository := IceRepository registeredRepositoryIncludingPackage: method package. + iceRepository + ifNil: [ ^ NotFound signal: ('Cannot find the git repository {1} belongs to' format: { method }) ]. + ^ PureGitCodeRepository on: iceRepository location +] + +{ #category : #accessing } +PureGitMethodVersions >> method [ + ^ method +] + +{ #category : #accessing } +PureGitMethodVersions >> method: aCompiledMethod [ + method := aCompiledMethod +] + +{ #category : #printing } +PureGitMethodVersions >> printOn: aStream [ + super printOn: aStream. + aStream nextPut: $(; print: method; nextPut: $) +] + +{ #category : #accessing } +PureGitMethodVersions >> repository [ + ^ repository ifNil: [ repository := self findMethodRepository ] +] + +{ #category : #private } +PureGitMethodVersions >> tonelMethodClassExtension [ + method isExtension ifTrue: [ ^ '.extension.st' ]. + method isFromTrait ifTrue: [ ^ '.trait.set' ]. + ^ '.class.st' +] + +{ #category : #accessing } +PureGitMethodVersions >> versions [ + ^ versions ifNil: [ versions := self computeVersions ] +] + +{ #category : #accessing } +PureGitMethodVersions >> versions: aCollection [ + versions := aCollection +]