@@ -61,12 +61,37 @@ def gather_(self, cachedContributors=[]):
61
61
"""
62
62
contributors = []
63
63
scores = []
64
-
64
+ ### execute git commands to identify line contributions for each contributor
65
+ ### per file under git version control
65
66
fileContributions = self .execGit ()
67
+ ### iterate through all cointributions and separate contributors from files
68
+ uniqueFileContributions = {}
66
69
for filename , fileContributorDict in fileContributions .items ():
67
- print ("%s" % filename )
68
- self .printFileContributorDict (fileContributorDict )
69
-
70
+ self .log ("%s" % filename )
71
+ ### extract and log necessary contributor data for the file
72
+ contributorData = self .processFileContributorDict (fileContributorDict )
73
+ ### sum up all contributions from each user in our final
74
+ ### dict (contributon = lines of code)
75
+ for author , count in contributorData .items ():
76
+ if author in uniqueFileContributions :
77
+ uniqueFileContributions [author ] += count
78
+ else :
79
+ uniqueFileContributions [author ] = count
80
+ ### extract contributors and scores list from summed up file contribution data
81
+ blob = [* uniqueFileContributions .items ()]
82
+ contributors , linesOfCode = ([c for c , s in blob ], [s for c , s in blob ])
83
+ ### convert linesOfCode to score
84
+ ### we need to use given metrics for that
85
+ ### our action was initialized with a metric, we have to use that instead of
86
+ ### doing something random here
87
+ ###
88
+ ### in this simple example, each line of code represents 0.25 score points
89
+ ### -- this is bad, but it works for now as a reference
90
+ ### -- this cannot be a magic number, has to be configurable later
91
+ scores = [0.25 * loc for loc in linesOfCode ]
92
+ ### done, return our data so that it can be used inside the CDE to
93
+ ### weight the contributions made
94
+ self .log (contributors )
70
95
return contributors , scores
71
96
72
97
### Start User Methods
@@ -101,20 +126,28 @@ def execGit(self):
101
126
lines = blame .split ("\n " )
102
127
filename = lines [0 ]
103
128
lines = lines [1 :]
104
- #print("Blame > %s [%s]" % (filename, len(lines)))
105
129
### put lines through blameParser
106
130
fileContributorDict = self .parseBlame (lines )
131
+ ### filter out unwanted users, for example the one git blame adds
132
+ ### in case there are uncommitted changes
133
+ ### "<not.committed.yet>", "Not Committed Yet"
134
+ if "not.committed.yet" in fileContributorDict :
135
+ del fileContributorDict ["not.committed.yet" ]
107
136
fileContributions [filename ] = fileContributorDict
108
137
return fileContributions
109
138
110
- def printFileContributorDict (self , fcDict ):
139
+ def processFileContributorDict (self , fcDict ):
140
+ fileContributions = {}
111
141
for author , data in fcDict .items ():
112
- print (" %s [%s]" % (author , data ["count" ]))
142
+ contributionCount = data ["count" ]
143
+ self .log (" %s [%s]" % (author , contributionCount ))
113
144
for stamp , count in data ["stamps" ].items ():
114
145
datetimeStr = datetime .fromtimestamp (float (stamp )).strftime (
115
146
"%Y-%m-%d/%H:%M:%S"
116
147
)
117
- print (" -- %s [%s]" % (datetimeStr , count ))
148
+ self .log (" -- %s [%s]" % (datetimeStr , count ))
149
+ fileContributions [author ] = contributionCount
150
+ return fileContributions
118
151
119
152
def parseBlame (self , lines ):
120
153
lineDescriptions = []
@@ -124,7 +157,6 @@ def parseBlame(self, lines):
124
157
newEntry = True
125
158
for line in lines :
126
159
if newEntry :
127
- # print("######################################")
128
160
newEntry = False
129
161
### commit hash extraction
130
162
key = "commit"
@@ -148,10 +180,12 @@ def parseBlame(self, lines):
148
180
149
181
fileContributions = {}
150
182
for d in lineDescriptions :
151
- author = d ["author-mail" ]
183
+ author_mail = d ["author-mail" ][1 :- 1 ] ### strip leading and ending "<>"
184
+ author_user = d ["author" ]
152
185
timestamp = d ["committer-time" ]
153
- key = author
154
- dd = fileContributions .get (author , None )
186
+ # key = (author_mail, author_user)
187
+ key = author_mail
188
+ dd = fileContributions .get (key , None )
155
189
if dd :
156
190
c = dd ["count" ]
157
191
stamps = dd ["stamps" ]
@@ -176,6 +210,7 @@ def test():
176
210
### define our input configuration (action) which normally comes from .yml configuration
177
211
d = {
178
212
"contributions_to_code" : {
213
+ "debug" : True ,
179
214
"type" : "git_file_contribution_action" , ### type of action (also the name of the plugin _alias_ used!)
180
215
"applies_to" : [
181
216
"*.md" ,
@@ -199,10 +234,15 @@ def test():
199
234
init = action .initialize_ ()
200
235
if init :
201
236
### let us do our work
202
- data = action .gather_ ()
203
- ### visualize and evaluate test data
204
- print (data )
205
- success = True
237
+ contributors , scores = action .gather_ ()
238
+ ### visualize and finalize gathered data
239
+ print ("Result:" )
240
+ print ("contributors:\n %s" % contributors )
241
+ print ("scores:\n %s" % scores )
242
+ ### evaluate test data
243
+ if len (contributors ) == len (scores ):
244
+ success = True
245
+ ### Done
206
246
return success
207
247
208
248
0 commit comments