按时间统计GitLab所有用户代码提交量
逻辑实现
- 首先遍历所有项目
- 然后遍历所有项目下拥有的所有分支
- 遍历所有分支下每个用户提交的代码量
- 时间区间限制
- 数据去重相加,格式化输出
- 复制生成的个人访问令牌到脚本的
private_token
中,再将url
改为你的 GitLab 地址,最后修改起-止时间
执行脚本即可 - 脚本,基于 GitLab 官方 API,注意
Git用户名
是提交工具上配置的名字,不是 GitLab 用户名
#!/usr/bin/python3
# coding=utf8
# @Desc : GitLab 按时间查看各用户代码提交量官方API版
import json
import requests
from dateutil.parser import parse
gitlab_url = "http://gitlab.xxxx" # GitLab 地址
private_token = "token" # GitLab Access Tokens(管理员权限)
info = []
headers = {
'Connection': 'close',
}
# UTC时间转时间戳
def utc_time(time):
dt = parse(time)
return int(dt.timestamp())
# 输出格式化
def str_format(txt):
lenTxt = len(txt)
lenTxt_utf8 = len(txt.encode('utf-8'))
size = int((lenTxt_utf8 - lenTxt) / 2 + lenTxt)
length = 20 - size
return length
# 获取 GitLab 上的所有项目
def gitlab_projects():
project_ids = []
page = 1
while True:
url = gitlab_url + "api/v4/projects/?private_token=" + private_token + "&page=" + str(page) + "&per_page=20"
while True:
try:
res = requests.get(url, headers=headers, timeout=10)
break
except Exception as e:
print(e)
continue
projects = json.loads(res.text)
if len(projects) == 0:
break
else:
for project in projects:
project_ids.append(project["id"])
page += 1
return project_ids
# 获取 GitLab 上的项目 id 中的分支
def project_branches(project_id):
branch_names = []
page = 1
while True:
url = gitlab_url + "api/v4/projects/" + str(
project_id) + "/repository/branches?private_token=" + private_token + "&page=" + str(page) + "&per_page=20"
while True:
try:
res = requests.get(url, headers=headers, timeout=10)
break
except Exception as e:
print(e)
continue
branches = json.loads(res.text)
'''Debug
print(url)
print('--' * 10)
print(branches)
print('*' * 10)
'''
if len(branches) == 0:
break
else:
for branch in branches:
branch_names.append(branch["name"])
page += 1
return branch_names
# 获取 GitLab 上的项目分支中的 commits,当 title 或 message 首单词为 Merge 时,表示合并操作,剔除此代码量
def project_commits(project_id, branch, start_time, end_time):
commit_ids = []
page = 1
while True:
url = gitlab_url + "api/v4/projects/" + str(
project_id) + "/repository/commits?ref_name=" + branch + "&private_token=" + private_token + "&page=" + str(
page) + "&per_page=20"
while True:
try:
res = requests.get(url, headers=headers, timeout=10)
break
except Exception as e:
print(e)
continue
commits = json.loads(res.text)
if len(commits) == 0:
break
else:
for commit in commits:
if "Merge" in commit["title"] or "Merge" in commit["message"] or "合并" in commit["title"] or "合并" in \
commit["message"]: # 不统计合并操作
continue
elif utc_time(commit["authored_date"]) < utc_time(start_time) or utc_time(
commit["authored_date"]) > utc_time(end_time): # 不满足时间区间
continue
else:
commit_ids.append(commit["id"])
page += 1
return commit_ids
# 根据 commits 的 id 获取代码量
def commit_code(project_id, commit_id):
global info
url = gitlab_url + "api/v4/projects/" + str(
project_id) + "/repository/commits/" + commit_id + "?private_token=" + private_token
while True:
try:
res = requests.get(url, headers=headers, timeout=10)
break
except Exception as e:
print(e)
continue
data = json.loads(res.text)
temp = {"name": data["author_name"], "additions": data["stats"]["additions"],
"deletions": data["stats"]["deletions"], "total": data["stats"]["total"]} # Git工具用户名,新增代码数,删除代码数,总计代码数
info.append(temp)
# GitLab 数据查询
def gitlab_info(start_time, end_time):
for project_id in gitlab_projects(): # 遍历所有项目ID
for branche_name in project_branches(project_id): # 遍历每个项目中的分支
for commit_id in project_commits(project_id, branche_name, start_time, end_time): # 遍历每个分支中的 commit id
commit_code(project_id, commit_id) # 获取代码提交量
if __name__ == "__main__":
print("正在统计数据,请耐心等待,这将花费不少时间~")
gitlab_info('2020-12-01 00:00:00', '2020-12-01 23:59:59') # 起-止时间
name = [] # Git工具用户名
additions = [] # 新增代码数
deletions = [] # 删除代码数
total = [] # 总计代码数
res = {}
# 生成元组
for i in info:
for key, value in i.items():
if key == "name":
name.append(value)
if key == "additions":
additions.append(value)
if key == "deletions":
deletions.append(value)
if key == "total":
total.append(value)
data = list(zip(name, additions, deletions, total))
# print(data)
# 去重累加
for j in data:
name = j[0]
additions = j[1]
deletions = j[2]
total = j[3]
if name in res.keys():
res[name][0] += additions
res[name][1] += deletions
res[name][2] += total
else:
res.update({name: [additions, deletions, total]})
# 打印结果
print("Git用户名 新增代码数 删除代码数 总计代码数")
for k in res.keys():
print(k + " " * str_format(k) + str(res[k][0]) + " " * str_format(str(res[k][0])) + str(
res[k][1]) + " " * str_format(str(res[k][1])) + str(res[k][2]))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
上次更新: 2024/11/08, 12:33:03
← 制品库集成