Skip to content

Commit a47dea0

Browse files
author
quanbisen
committed
fix: merge branch statistic_code_modify conflicts
2 parents f0dd907 + 3c16148 commit a47dea0

File tree

6 files changed

+128
-19
lines changed

6 files changed

+128
-19
lines changed

biz/entity/review_entity.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
class MergeRequestReviewEntity:
22
def __init__(self, project_name: str, author: str, source_branch: str, target_branch: str, updated_at: int,
3-
commits: list, score: float, url: str, review_result: str, url_slug: str, webhook_data: dict):
3+
commits: list, score: float, url: str, review_result: str, url_slug: str, webhook_data: dict,
4+
additions: int, deletions: int):
45
self.project_name = project_name
56
self.author = author
67
self.source_branch = source_branch
@@ -12,6 +13,8 @@ def __init__(self, project_name: str, author: str, source_branch: str, target_br
1213
self.review_result = review_result
1314
self.url_slug = url_slug
1415
self.webhook_data = webhook_data
16+
self.additions = additions
17+
self.deletions = deletions
1518

1619
@property
1720
def commit_messages(self):
@@ -21,7 +24,7 @@ def commit_messages(self):
2124

2225
class PushReviewEntity:
2326
def __init__(self, project_name: str, author: str, branch: str, updated_at: int, commits: list, score: float,
24-
review_result: str, url_slug: str, webhook_data: dict):
27+
review_result: str, url_slug: str, webhook_data: dict, additions: int, deletions: int):
2528
self.project_name = project_name
2629
self.author = author
2730
self.branch = branch
@@ -31,6 +34,8 @@ def __init__(self, project_name: str, author: str, branch: str, updated_at: int,
3134
self.review_result = review_result
3235
self.url_slug = url_slug
3336
self.webhook_data = webhook_data
37+
self.additions = additions
38+
self.deletions = deletions
3439

3540
@property
3641
def commit_messages(self):

biz/github/webhook_handler.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,9 @@ def filter_changes(changes: list):
4444
filtered_changes = [
4545
{
4646
'diff': item.get('diff', ''),
47-
'new_path': item['new_path']
47+
'new_path': item['new_path'],
48+
'additions': item.get('additions', 0),
49+
'deletions': item.get('deletions', 0),
4850
}
4951
for item in not_deleted_changes
5052
if any(item.get('new_path', '').endswith(ext) for ext in supported_extensions)
@@ -105,7 +107,9 @@ def get_pull_request_changes(self) -> list:
105107
change = {
106108
'old_path': file.get('filename'),
107109
'new_path': file.get('filename'),
108-
'diff': file.get('patch', '')
110+
'diff': file.get('patch', ''),
111+
'additions': file.get('additions', 0),
112+
'deletions': file.get('deletions', 0)
109113
}
110114
changes.append(change)
111115
return changes
@@ -311,7 +315,9 @@ def repository_compare(self, base: str, head: str):
311315
'old_path': file.get('filename'),
312316
'new_path': file.get('filename'),
313317
'diff': file.get('patch', ''),
314-
'status': file.get('status', '')
318+
'status': file.get('status', ''),
319+
'additions': file.get('additions', 0),
320+
'deletions': file.get('deletions', 0),
315321
}
316322
diffs.append(diff)
317323
return diffs

biz/gitlab/webhook_handler.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ def filter_changes(changes: list):
2121
filtered_changes = [
2222
{
2323
'diff': item.get('diff', ''),
24-
'new_path': item['new_path']
24+
'new_path': item['new_path'],
25+
'additions': len(re.findall(r'^\+(?!\+\+)', item.get('diff', ''), re.MULTILINE)),
26+
'deletions': len(re.findall(r'^-(?!--)', item.get('diff', ''), re.MULTILINE))
2527
}
2628
for item in filter_deleted_files_changes
2729
if any(item.get('new_path', '').endswith(ext) for ext in supported_extensions)

biz/queue/worker.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ def handle_push_event(webhook_data: dict, gitlab_token: str, gitlab_url: str, gi
2424

2525
review_result = None
2626
score = 0
27+
additions = 0
28+
deletions = 0
2729
if push_review_enabled:
2830
# 获取PUSH的changes
2931
changes = handler.get_push_changes()
@@ -37,6 +39,9 @@ def handle_push_event(webhook_data: dict, gitlab_token: str, gitlab_url: str, gi
3739
commits_text = ';'.join(commit.get('message', '').strip() for commit in commits)
3840
review_result = CodeReviewer().review_and_strip_code(str(changes), commits_text)
3941
score = CodeReviewer.parse_review_score(review_text=review_result)
42+
for item in changes:
43+
additions += item['additions']
44+
deletions += item['deletions']
4045
# 将review结果提交到Gitlab的 notes
4146
handler.add_push_notes(f'Auto Review Result: \n{review_result}')
4247

@@ -50,6 +55,8 @@ def handle_push_event(webhook_data: dict, gitlab_token: str, gitlab_url: str, gi
5055
review_result=review_result,
5156
url_slug=gitlab_url_slug,
5257
webhook_data=webhook_data,
58+
additions=additions,
59+
deletions=deletions,
5360
))
5461

5562
except Exception as e:
@@ -89,6 +96,12 @@ def handle_merge_request_event(webhook_data: dict, gitlab_token: str, gitlab_url
8996
if not changes:
9097
logger.info('未检测到有关代码的修改,修改文件可能不满足SUPPORTED_EXTENSIONS。')
9198
return
99+
# 统计本次新增、删除的代码总数
100+
additions = 0
101+
deletions = 0
102+
for item in changes:
103+
additions += item.get('additions', 0)
104+
deletions += item.get('deletions', 0)
92105

93106
# 获取Merge Request的commits
94107
commits = handler.get_merge_request_commits()
@@ -117,6 +130,8 @@ def handle_merge_request_event(webhook_data: dict, gitlab_token: str, gitlab_url
117130
review_result=review_result,
118131
url_slug=gitlab_url_slug,
119132
webhook_data=webhook_data,
133+
additions=additions,
134+
deletions=deletions,
120135
)
121136
)
122137

@@ -137,6 +152,8 @@ def handle_github_push_event(webhook_data: dict, github_token: str, github_url:
137152

138153
review_result = None
139154
score = 0
155+
additions = 0
156+
deletions = 0
140157
if push_review_enabled:
141158
# 获取PUSH的changes
142159
changes = handler.get_push_changes()
@@ -150,6 +167,9 @@ def handle_github_push_event(webhook_data: dict, github_token: str, github_url:
150167
commits_text = ';'.join(commit.get('message', '').strip() for commit in commits)
151168
review_result = CodeReviewer().review_and_strip_code(str(changes), commits_text)
152169
score = CodeReviewer.parse_review_score(review_text=review_result)
170+
for item in changes:
171+
additions += item.get('additions', 0)
172+
deletions += item.get('deletions', 0)
153173
# 将review结果提交到GitHub的 notes
154174
handler.add_push_notes(f'Auto Review Result: \n{review_result}')
155175

@@ -163,6 +183,8 @@ def handle_github_push_event(webhook_data: dict, github_token: str, github_url:
163183
review_result=review_result,
164184
url_slug=github_url_slug,
165185
webhook_data=webhook_data,
186+
additions=additions,
187+
deletions=deletions,
166188
))
167189

168190
except Exception as e:
@@ -202,6 +224,12 @@ def handle_github_pull_request_event(webhook_data: dict, github_token: str, gith
202224
if not changes:
203225
logger.info('未检测到有关代码的修改,修改文件可能不满足SUPPORTED_EXTENSIONS。')
204226
return
227+
# 统计本次新增、删除的代码总数
228+
additions = 0
229+
deletions = 0
230+
for item in changes:
231+
additions += item.get('additions', 0)
232+
deletions += item.get('deletions', 0)
205233

206234
# 获取Pull Request的commits
207235
commits = handler.get_pull_request_commits()
@@ -230,6 +258,8 @@ def handle_github_pull_request_event(webhook_data: dict, github_token: str, gith
230258
review_result=review_result,
231259
url_slug=github_url_slug,
232260
webhook_data=webhook_data,
261+
additions=additions,
262+
deletions=deletions,
233263
))
234264

235265
except Exception as e:

biz/service/review_service.py

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@ def init_db():
2525
commit_messages TEXT,
2626
score INTEGER,
2727
url TEXT,
28-
review_result TEXT
28+
review_result TEXT,
29+
additions INTEGER DEFAULT 0,
30+
deletions INTEGER DEFAULT 0
2931
)
3032
''')
3133
cursor.execute('''
@@ -37,9 +39,20 @@ def init_db():
3739
updated_at INTEGER,
3840
commit_messages TEXT,
3941
score INTEGER,
40-
review_result TEXT
42+
review_result TEXT,
43+
additions INTEGER DEFAULT 0,
44+
deletions INTEGER DEFAULT 0
4145
)
4246
''')
47+
# 确保旧版本的mr_review_log、push_review_log表添加additions、deletions列
48+
tables = ["mr_review_log", "push_review_log"]
49+
columns = ["additions", "deletions"]
50+
for table in tables:
51+
cursor.execute(f"PRAGMA table_info({table})")
52+
current_columns = [col[1] for col in cursor.fetchall()]
53+
for column in columns:
54+
if column not in current_columns:
55+
cursor.execute(f"ALTER TABLE {table} ADD COLUMN {column} INTEGER DEFAULT 0")
4356
conn.commit()
4457
except sqlite3.DatabaseError as e:
4558
print(f"Database initialization failed: {e}")
@@ -51,13 +64,13 @@ def insert_mr_review_log(entity: MergeRequestReviewEntity):
5164
with sqlite3.connect(ReviewService.DB_FILE) as conn:
5265
cursor = conn.cursor()
5366
cursor.execute('''
54-
INSERT INTO mr_review_log (project_name,author, source_branch, target_branch, updated_at, commit_messages, score, url,review_result)
55-
VALUES (?,?, ?, ?, ?, ?, ?, ?, ?)
67+
INSERT INTO mr_review_log (project_name,author, source_branch, target_branch, updated_at, commit_messages, score, url,review_result, additions, deletions)
68+
VALUES (?,?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
5669
''',
5770
(entity.project_name, entity.author, entity.source_branch,
5871
entity.target_branch,
5972
entity.updated_at, entity.commit_messages, entity.score,
60-
entity.url, entity.review_result))
73+
entity.url, entity.review_result, entity.additions, entity.deletions))
6174
conn.commit()
6275
except sqlite3.DatabaseError as e:
6376
print(f"Error inserting review log: {e}")
@@ -69,7 +82,7 @@ def get_mr_review_logs(authors: list = None, project_names: list = None, updated
6982
try:
7083
with sqlite3.connect(ReviewService.DB_FILE) as conn:
7184
query = """
72-
SELECT project_name, author, source_branch, target_branch, updated_at, commit_messages, score, url, review_result
85+
SELECT project_name, author, source_branch, target_branch, updated_at, commit_messages, score, url, review_result, additions, deletions
7386
FROM mr_review_log
7487
WHERE 1=1
7588
"""
@@ -106,12 +119,12 @@ def insert_push_review_log(entity: PushReviewEntity):
106119
with sqlite3.connect(ReviewService.DB_FILE) as conn:
107120
cursor = conn.cursor()
108121
cursor.execute('''
109-
INSERT INTO push_review_log (project_name,author, branch, updated_at, commit_messages, score,review_result)
110-
VALUES (?, ?, ?, ?, ?, ?, ?)
122+
INSERT INTO push_review_log (project_name,author, branch, updated_at, commit_messages, score,review_result, additions, deletions)
123+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
111124
''',
112125
(entity.project_name, entity.author, entity.branch,
113126
entity.updated_at, entity.commit_messages, entity.score,
114-
entity.review_result))
127+
entity.review_result, entity.additions, entity.deletions))
115128
conn.commit()
116129
except sqlite3.DatabaseError as e:
117130
print(f"Error inserting review log: {e}")
@@ -124,7 +137,7 @@ def get_push_review_logs(authors: list = None, project_names: list = None, updat
124137
with sqlite3.connect(ReviewService.DB_FILE) as conn:
125138
# 基础查询
126139
query = """
127-
SELECT project_name, author, branch, updated_at, commit_messages, score, review_result
140+
SELECT project_name, author, branch, updated_at, commit_messages, score, review_result, additions, deletions
128141
FROM push_review_log
129142
WHERE 1=1
130143
"""

ui.py

Lines changed: 56 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import datetime
2+
import math
23
import os
34

45
import pandas as pd
@@ -36,6 +37,16 @@ def get_data(service_func, authors=None, project_names=None, updated_at_gte=None
3637
if isinstance(ts, (int, float)) else ts
3738
)
3839

40+
def format_delta(row):
41+
if (row['additions'] and not math.isnan(row['additions'])
42+
and row['deletions'] and not math.isnan(row['deletions'])):
43+
return f"+{int(row['additions'])} -{int(row['deletions'])}"
44+
else:
45+
return ""
46+
if "additions" in df.columns and "deletions" in df.columns:
47+
df["delta"] = df.apply(format_delta, axis=1)
48+
else:
49+
df["delta"] = ""
3950
data = df[columns]
4051
return data
4152

@@ -171,6 +182,34 @@ def generate_author_score_chart(df):
171182
st.pyplot(fig2)
172183

173184

185+
def generate_author_code_line_chart(df):
186+
if df.empty:
187+
st.info("没有数据可供展示")
188+
return
189+
190+
# 检查必要的列是否存在
191+
if 'additions' not in df.columns or 'deletions' not in df.columns:
192+
st.warning("无法生成代码行数图表:缺少必要的数据列")
193+
return
194+
195+
# 计算每个人员的代码行数(additions + deletions)
196+
df['total_lines'] = df['additions'] + df['deletions']
197+
author_code_lines = df.groupby('author')['total_lines'].sum().reset_index()
198+
author_code_lines.columns = ['author', 'code_lines']
199+
200+
# 显示代码行数柱状图
201+
fig3, ax3 = plt.subplots(figsize=(10, 6))
202+
colors = plt.colormaps['Set3'].resampled(len(author_code_lines))
203+
ax3.bar(
204+
author_code_lines['author'],
205+
author_code_lines['code_lines'],
206+
color=[colors(i) for i in range(len(author_code_lines))]
207+
)
208+
plt.xticks(rotation=45, ha='right', fontsize=26)
209+
plt.tight_layout()
210+
st.pyplot(fig3)
211+
212+
174213
# 主要内容
175214
def main_page():
176215
st.markdown("#### 审查日志")
@@ -223,6 +262,7 @@ def display_data(tab, service_func, columns, column_config):
223262
average_score = df["score"].mean() if not df.empty else 0
224263
st.markdown(f"**总记录数:** {total_records},**平均分:** {average_score:.2f}")
225264

265+
226266
# 创建2x2网格布局展示四个图表
227267
row1, row2, row3, row4 = st.columns(4)
228268
with row1:
@@ -238,9 +278,18 @@ def display_data(tab, service_func, columns, column_config):
238278
st.markdown("<div style='text-align: center;'><b>人员平均分数</b></div>", unsafe_allow_html=True)
239279
generate_author_score_chart(df)
240280

281+
row5, row6, row7, row8 = st.columns(4)
282+
with row5:
283+
st.markdown("<div style='text-align: center;'><b>人员代码变更总行数(增加+删除)</b></div>", unsafe_allow_html=True)
284+
# 只有当 additions 和 deletions 列都存在时才显示代码行数图表
285+
if 'additions' in df.columns and 'deletions' in df.columns:
286+
generate_author_code_line_chart(df)
287+
else:
288+
st.info("无法显示代码行数图表:缺少必要的数据列")
289+
241290
# Merge Request 数据展示
242-
mr_columns = ["project_name", "author", "source_branch", "target_branch", "updated_at", "commit_messages", "score",
243-
"url"]
291+
mr_columns = ["project_name", "author", "source_branch", "target_branch", "updated_at", "commit_messages", "delta",
292+
"score", "url", "additions", "deletions"]
244293

245294
mr_column_config = {
246295
"score": st.column_config.ProgressColumn(
@@ -252,20 +301,24 @@ def display_data(tab, service_func, columns, column_config):
252301
max_chars=100,
253302
display_text=r"查看"
254303
),
304+
"additions": None,
305+
"deletions": None,
255306
}
256307

257308
display_data(mr_tab, ReviewService().get_mr_review_logs, mr_columns, mr_column_config)
258309

259310
# Push 数据展示
260311
if show_push_tab:
261-
push_columns = ["project_name", "author", "branch", "updated_at", "commit_messages", "score"]
312+
push_columns = ["project_name", "author", "branch", "updated_at", "commit_messages", "delta", "score", "additions", "deletions"]
262313

263314
push_column_config = {
264315
"score": st.column_config.ProgressColumn(
265316
format="%f",
266317
min_value=0,
267318
max_value=100,
268319
),
320+
"additions": None,
321+
"deletions": None,
269322
}
270323

271324
display_data(push_tab, ReviewService().get_push_review_logs, push_columns, push_column_config)

0 commit comments

Comments
 (0)