Skip to content

Commit

Permalink
Merge pull request #6 from moosetechnology/GLPH-importer-new-changes
Browse files Browse the repository at this point in the history
Lot of changes comming from analysis code of Berger-Levrault
  • Loading branch information
badetitou authored Jun 14, 2024
2 parents 10a839f + efdf48a commit 80d7638
Show file tree
Hide file tree
Showing 47 changed files with 4,255 additions and 227 deletions.
29 changes: 29 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Use the official smalltalkci image from Docker Hub
FROM hpiswa/smalltalkci

# Set environment variables
ENV ORIGIN_IMAGE_NAME=Moose64-11
ENV IMAGE_NAME=PharoServer

# Set the working directory
WORKDIR /usr/src/app

# Copy your Smalltalk project files into the container
COPY . .

# Run the CI script commands
RUN smalltalkci -s "${ORIGIN_IMAGE_NAME}" .smalltalk.ston
RUN mkdir ${IMAGE_NAME}
RUN mv /root/smalltalkCI-master/_builds/* ./${IMAGE_NAME}
RUN mv ./${IMAGE_NAME}/*/* ./${IMAGE_NAME}
RUN mv ${IMAGE_NAME}/TravisCI.changes ${IMAGE_NAME}/${IMAGE_NAME}.changes
RUN mv ${IMAGE_NAME}/TravisCI.image ${IMAGE_NAME}/${IMAGE_NAME}.image
RUN rm ${IMAGE_NAME}/build_status.txt
RUN rm -rf ${IMAGE_NAME}/vm

# Expose any ports the application might need (if applicable)
# EXPOSE 8080

# Set the command to run your Smalltalk application
CMD ["/root/smalltalkCI-master/_cache/vms/Moose64-11/pharo", "--headless", "PharoServer/PharoServer.image", "st", "./launchAnalyze.st"]
# the output csv files will be under /root/*.csv
94 changes: 94 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,100 @@ Here is the metamodel used in this project

![GitProject meta-model png](https://raw.githubusercontent.com/moosetechnology/GitProjectHealth/v1/doc/gitproject.png)



## Contributor

This work has been first developed by the [research department of Berger-Levrault](https://www.research-bl.com/)


## Running metrics with docker

### running locally
```smalltalk
|glphModel glphApi glhImporter beforeExp duringExp usersWithProjects gme|
"This example set up and run a GitProjectHealth metrics over two period of time of a given set of users and their projects.
It ouputs a csv files containing : churn code, commits frequencies, code addition and deletion, comments added (e.g. // # /**/ ), avg delay before first churn and merge request duration.
"
"load githealth project into your image"
Metacello new
repository: 'github://moosetechnology/GitProjectHealth:GLPH-importer-new-changes/src';
baseline: 'GitLabHealth';
onConflict: [ :ex | ex useIncoming ];
onUpgrade: [ :ex | ex useIncoming ];
onDowngrade: [ :ex | ex useLoaded ];
ignoreImage;
load.
"set up a log at your root"
TinyLogger default
addFileLoggerNamed: 'pharo-code-churn.log'.
"new model instance"
glphModel := GLPHEModel new.
"new API class instance"
glphApi := GLPHApi new
privateToken: '<YOUR_TOKEN_KEY>';
baseAPIUrl:'https://gitlab.com/api/v4';
yourself.
"new importer instance"
glhImporter := GLPHModelImporter new
glhApi: glphApi;
glhModel: glphModel;
withFiles: false;
withCommitDiffs: true.
"setting up the period to compare (e.g. before a experience and during an experience)"
beforeExp := {
#since -> ('1 march 2023' asDate).
#until -> ('24 may 2023' asDate).
} asDictionary .
duringExp := {
#since -> ('1 march 2024' asDate).
#until -> ('24 may 2024' asDate).
} asDictionary .
usersWithProjects := {
" 'dev nameA' -> { projectID1 . projectID2 }."
" 'dev nameB' -> { projectID3 . projectID2 }."
'John Do' -> { 14 . 543 . 2455 }.
} asDictionary.
gme := GitMetricExporter new glhImporter: glhImporter;
initEntitiesFromUserProjects: usersWithProjects;
beforeDic: beforeExp; duringDic: duringExp; label: 'GitLabHealth'.
"select among the following calendar class (at least one) "
gme exportOver: { Date . Week . Month . Year .}.
"the output files are located at 'FileLocator home/*.csv' "
Smalltalk snapshot: true andQuit: true.
```

### deploying with docker


```bash
git clone https://github.com/moosetechnology/GitProjectHealth.git
cd GitProjectHealth
git checkout GLPH-importer-new-changes

sudo docker build -t code-churn-pharo .
sudo docker run code-churn-pharo &
```
locate and retrieve csv output files:
```bash
sudo docker ps
sudo docker exec -it <container-id> find / -type f -name 'IA4Code*.csv' 2>/dev/null
```





62 changes: 62 additions & 0 deletions launchAnalyze.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
|glphModel glphApi glhImporter beforeExp duringExp usersWithProjects gme|

"This example set up and run a GitProjectHealth metrics over two period of time of a given set of users and their projects.
It ouputs a csv files containing : churn code, commits frequencies, code addition and deletion, comments added (e.g. // # /**/ ), avg delay before first churn and merge request duration.
"

"load githealth project into your image"
Metacello new
repository: 'github://moosetechnology/GitProjectHealth:GLPH-importer-new-changes/src';
baseline: 'GitLabHealth';
onConflict: [ :ex | ex useIncoming ];
onUpgrade: [ :ex | ex useIncoming ];
onDowngrade: [ :ex | ex useLoaded ];
ignoreImage;
load.

"set up a log at your root"
TinyLogger default
addFileLoggerNamed: 'pharo-code-churn.log'.

"new model instance"
glphModel := GLPHEModel new.

"new API class instance"
glphApi := GLPHApi new
privateToken: '<YOUR_TOKEN_KEY>';
baseAPIUrl:'https://gitlab.com/api/v4';
yourself.

"new importer instance"
glhImporter := GLPHModelImporter new
glhApi: glphApi;
glhModel: glphModel;
withFiles: false;
withCommitDiffs: true.

"setting up the period to compare (e.g. before a experience and during an experience)"
beforeExp := {
#since -> ('1 march 2023' asDate).
#until -> ('24 may 2023' asDate).
} asDictionary .
duringExp := {
#since -> ('1 march 2024' asDate).
#until -> ('24 may 2024' asDate).
} asDictionary .

usersWithProjects := {
" 'dev nameA' -> { projectID1 . projectID2 }."
" 'dev nameB' -> { projectID3 . projectID2 }."
'John Do' -> { 14 . 543 . 2455 }.
} asDictionary.


gme := GitMetricExporter new glhImporter: glhImporter;
initEntitiesFromUserProjects: usersWithProjects;
beforeDic: beforeExp; duringDic: duringExp; label: 'GitLabHealth'.

"select among the following calendar class (at least one) "
gme exportOver: { Date . Week . Month . Year .}.

"the output files are located at 'FileLocator home/*.csv' "
Smalltalk snapshot: true andQuit: true.
21 changes: 19 additions & 2 deletions src/BaselineOfGitLabHealth/BaselineOfGitLabHealth.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,23 @@ BaselineOfGitLabHealth >> definePackages: spec [
with: [ spec requires: #( 'NeoJSON' 'MoreLogger' ) ];
package: 'GitHubHealth-Model-Importer'
with: [ spec requires: #( 'NeoJSON' 'MoreLogger' ) ];
package: 'GitLabHealth-Model-Importer-Tests'
with: [ spec requires: #( 'GitLabHealth-Model-Importer' 'GitHubHealth-Model-Importer' ) ]
package: 'GitLabHealth-Model-Importer-Tests' with: [
spec requires:
#( 'GitLabHealth-Model-Importer' 'GitHubHealth-Model-Importer' ) ].

"model extension"
spec
package: 'GLPHExtended-Model' with: [
spec requires:
#( 'GitLabHealth-Model' 'GitLabHealth-Model-Extension' ) ];
package: 'GLPHExtended-Model-Extension'
with: [ spec requires: #( 'GLPHExtended-Model' 'GitLabHealth-Model' 'GitLabHealth-Model-Extension' ) ];
package: 'GitLabHealth-Model-Analysis';
package: 'GitLabHealth-Model-Analysis-Tests'
with: [ spec requires: #( 'GitLabHealth-Model-Analysis' ) ];
package: 'GitLabHealth-Visualization';
package: 'GitLabProjectHealth-ExtendModel-Generator';
package: 'GitLabProjectHealth-Model-Importer';
package: 'GitLabProjectHealth-Model-Importer-Tests'
with: [ spec requires: #( 'GitLabProjectHealth-Model-Importer' ) ]
]
13 changes: 13 additions & 0 deletions src/GLPHExtended-Model-Extension/GLPHEAddition.extension.st
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Extension { #name : #GLPHEAddition }

{ #category : #'*GLPHExtended-Model-Extension' }
GLPHEAddition >> isAddition [
^ true

]

{ #category : #'*GLPHExtended-Model-Extension' }
GLPHEAddition >> isDeletion [

^ false
]
53 changes: 53 additions & 0 deletions src/GLPHExtended-Model-Extension/GLPHEChange.extension.st
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
Extension { #name : #GLPHEChange }

{ #category : #'*GLPHExtended-Model-Extension' }
GLPHEChange class >> createFrom: aDiffLine [
"Factory a Change from a loc"

| aChange |
aChange := nil.
(aDiffLine beginsWith: #'@@') ifTrue: [
| infos |
aChange := GLPHELineOfCode newFromLoCRange: aDiffLine.

infos := (aDiffLine splitOn: '@@') copyWithoutFirst.
infos := aDiffLine splitOn: ' ' ].
^ aChange
]

{ #category : #'*GLPHExtended-Model-Extension' }
GLPHEChange >> isAddition [

^ false
]

{ #category : #'*GLPHExtended-Model-Extension' }
GLPHEChange >> isDeletion [

^ false
]

{ #category : #'*GLPHExtended-Model-Extension' }
GLPHEChange >> name [

^ sourceCode
]

{ #category : #'*GLPHExtended-Model-Extension' }
GLPHEChange class >> newFrom: aDiffLine [
"Factory a Change from a loc"

| aChange code|
aChange := GLPHELineOfCode new.

code := aDiffLine.
(aDiffLine beginsWith: #'@@') ifTrue: [
code := (aDiffLine splitOn: '@@') copyWithoutFirst second.
].
(aDiffLine trim beginsWith: #+) ifTrue: [ aChange := GLPHEAddition new. ].
(aDiffLine trim beginsWith: #-) ifTrue: [ aChange := GLPHEDeletion new. ].

aChange sourceCode: code.

^ aChange
]
11 changes: 11 additions & 0 deletions src/GLPHExtended-Model-Extension/GLPHEDeletion.extension.st
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
Extension { #name : #GLPHEDeletion }

{ #category : #'*GLPHExtended-Model-Extension' }
GLPHEDeletion >> isAddition [
^ false
]

{ #category : #'*GLPHExtended-Model-Extension' }
GLPHEDeletion >> isDeletion [
^ true.
]
19 changes: 19 additions & 0 deletions src/GLPHExtended-Model-Extension/GLPHEDiffRange.extension.st
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
Extension { #name : #GLPHEDiffRange }

{ #category : #'*GLPHExtended-Model-Extension' }
GLPHEDiffRange >> name [

^ '[ OG: ' , originalLineRange , ' | NEW: ' , newLineRange , ']'
]

{ #category : #'*GLPHExtended-Model-Extension' }
GLPHEDiffRange class >> newFrom: aLine [
|range infos rangesInfo |
range := GLPHEDiffRange new.
infos := (aLine splitOn: '@@') copyWithoutFirst.
rangesInfo := infos first trim splitOn: ' '.
range originalLineRange: rangesInfo first.
range newLineRange: rangesInfo second .

^ range.
]
22 changes: 22 additions & 0 deletions src/GLPHExtended-Model-Extension/GLPHELineOfCode.extension.st
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
Extension { #name : #GLPHELineOfCode }

{ #category : #'*GLPHExtended-Model-Extension' }
GLPHELineOfCode class >> newFrom: aDiffLine [

| aLoC infos ranges |
infos := (aDiffLine splitOn: '@@') copyWithoutFirst.
aLoC := GLPHELineOfCode new.
aLoC sourceCode: infos second.
^ aLoC.
]

{ #category : #'*GLPHExtended-Model-Extension' }
GLPHELineOfCode class >> newFromLoCRange: aDiffLine [
|aLoC infos ranges|
infos := (aDiffLine splitOn: '@@') copyWithoutFirst.
ranges := infos first splitOn: ','.
aLoC := GLPHELineOfCode new.
aLoC originalLineRange: ranges first.
aLoC newLineRange: 1.
aLoC lineOfCode: infos second.
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Extension { #name : #GLPHEMergeRequest }

{ #category : #'*GLPHExtended-Model-Extension' }
GLPHEMergeRequest >> name [

<FMProperty: #name type: #String>
<FMComment: 'Basic name of the entity, not full reference.'>
^ title
]
1 change: 1 addition & 0 deletions src/GLPHExtended-Model-Extension/package.st
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Package { #name : #'GLPHExtended-Model-Extension' }
8 changes: 4 additions & 4 deletions src/GLPHExtended-Model/GLHCommit.extension.st
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ Extension { #name : #GLHCommit }

{ #category : #'*GLPHExtended-Model-accessing' }
GLHCommit >> commitedMergeRequest [
"Relation named: #commitedMergeRequest type: #GLPHEMergeRequest opposite: #mergeCommit"
"Relation named: #commitedMergeRequest type: #GLPHEMergeRequest opposite: #mergedCommit"

<generated>
<derived>
<FMProperty: #commitedMergeRequest type: #GLPHEMergeRequest opposite: #mergeCommit>
<FMProperty: #commitedMergeRequest type: #GLPHEMergeRequest opposite: #mergedCommit>
<package: #'GLPHExtended-Model'>
^ self attributeAt: #commitedMergeRequest ifAbsent: [ nil ]
]
Expand All @@ -19,10 +19,10 @@ GLHCommit >> commitedMergeRequest: anObject [
anObject ifNil: [ | otherSide |
otherSide := self commitedMergeRequest.
self attributeAt: #commitedMergeRequest put: anObject.
otherSide mergeCommit: nil ]
otherSide mergedCommit: nil ]
ifNotNil: [
self attributeAt: #commitedMergeRequest put: anObject.
anObject mergeCommit: self ]
anObject mergedCommit: self ]
]

{ #category : #'*GLPHExtended-Model-accessing' }
Expand Down
Loading

0 comments on commit 80d7638

Please sign in to comment.