脚本之家,脚本语言编程技术及教程分享平台!
分类导航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服务器之家 - 脚本之家 - Python - python实现代码审查自动回复消息

python实现代码审查自动回复消息

2021-08-31 00:54freephp Python

这篇文章主要介绍了python实现代码审查回复消息生成的示例,帮助大家更好的理解和学习python,感兴趣的朋友可以了解下

在一个规范化的研发流程中,一般遵循如下流程:

  1. 开发阶段:研发功能或者修复bug,在本地自测。
  2. 代码审核阶段:提交代码,并请求团队内人员做code review。
  3. 测试环境测试阶段:部署到测试环境并请求测试。
  4. 发布线上待测阶段:测试环境通过测试发布到线上进行测试。
  5. 验收完成任务:线上验证成功,关闭这个任务。

实际上这只是一种最理想化的过程,因为我们默认每次状态流转都是顺利的,开发没有毛病,测试一次就通过,现实中的研发

流程的情况更复杂,如图所示。

python实现代码审查自动回复消息

整个过程一气呵成,环环相扣。而其中可以被自动化的正好是第二步:请求他人进行code review的时候的反馈消息。

根据实践的经验,比较好的内容格式如下(包含markdown格式,因为跟踪任务的系统支持这种格式):

?
1
2
3
4
5
6
**changes has been committed to feature/xxx-xxx**
 
- https://git.xxx.com/xxxx/ddaf18f9be4613c31363d4c92b8bafc3sdfdsf
 
**details**
remove invalid logic for admin pannel

由于每次走到code review的步骤的时候都需要写类似的回复在任务管理系统中,所以考虑使用python脚本去自动生成这段文字,简化工作。

根据样例回复进行分析,需要获取项目的分支名(任务目标分支),项目最后一次提交的commit id去组装第二行的git commit的链接,然后details的内容可以从git log中的提交信息里面提取。

第一步:获取分支名称。

为了简化过程,默认项目的当前分支就是我们需要的分支,那么问题简化为获取当前分支名。可以利用git的相关命令实现,如下:

?
1
git branch | sed -n '/\* /s///p'

第二步:获取commit id。

而获取commit id也非常简单,只需要如下命令:

?
1
git rev-parse head

第三步:获取提交信息。

还需要获取提交信息,利用git log的命令进行过滤也能得到:

?
1
git log --pretty=format:"%s" -1

git log --pretty=format命令很强大,除了获得提交信息外,还有如下参数可以使用。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
%h 提交对象(commit)的完整哈希字串
%h 提交对象的简短哈希字串
%t 树对象(tree)的完整哈希字串
%t 树对象的简短哈希字串
%p 父对象(parent)的完整哈希字串
%p 父对象的简短哈希字串
%an 作者(author)的名字
%ae 作者的电子邮件地址
%ad 作者修订日期(可以用 -date= 选项定制格式)
%ar 作者修订日期,按多久以前的方式显示
%cn 提交者(committer)的名字
%ce 提交者的电子邮件地址
%cd 提交日期
%cr 提交日期,按多久以前的方式显示
%s 提交说明

所以第二步也可以使用git log命令实现,如下所示:

?
1
git log --pretty=format:"%h" -1

当然还需要在后面加一点人性化的感谢的话,毕竟是麻烦其他人来对你代码进行审核,说一些感谢的话吧,这里我就用一个list来装一些感谢的话,然后随机获取一段贴到最后。
如果是以面向过程的方式去编写,那么可以编写如下代码:

?
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
#coding=utf-8
#!/usr/bin/python
 
import os, subprocess
import random
 
# use subprocess to get the current branch name from output
def get_branch_name(cd_path):
 os.chdir(cd_path)
 status, branch_name = subprocess.getstatusoutput("git branch | sed -n '/\* /s///p'")
 # print(output)
 # exit(0)
 return branch_name
 
def get_latest_git_log(cd_path):
 """
 docstring
 """
 os.chdir(cd_path)
 status, log_info = subprocess.getstatusoutput("git log --pretty=format:\"%s\" -1")
 return log_info
 
def get_latest_commit_id(cd_path):
 os.chdir(cd_path)
 status, commit_id = subprocess.getstatusoutput("git rev-parse head")
 return commit_id
 
def get_reviewer_by_random(reviewers):
 return random.choice(reviewers)
 
def get_thanks_words_by_random(thanks_words):
 return random.choice(thanks_words)
 
def create_comment(reviewers, branch_name, log_info, commit_id, thanks_words):
 print(get_reviewer_by_random(reviewers))
 print("*changes made has been committed to " + branch_name + "*")
 print("- https://git.xxxxx.com/someproject/subname/-/commit/" + commit_id)
 print("*details*")
 print("-" + log_info)
 print(get_thanks_words_by_random(thanks_words))
 
branch_name = get_branch_name('/users/tony/www/autowork')
log_info = get_latest_git_log('/users/tony/www/autowork')
commit_id = get_latest_commit_id('/users/tony/www/autowork')
 
reviewers = [
 '[~harry]',
 '[~tom]'
]
 
random_thanks_words = [
 'review it please, thanks.',
 'actually, i am glad to see you have time to review it, thanks a lot.',
 'please check it if you have free time, thanks.',
 'check it please.'
 'waiting for your code review, thank you.'
]
 
create_comment(reviewers, branch_name, log_info, commit_id, random_thanks_words)

由于python脚本和项目没有放在一个目录下面,所以每次在执行git相关命令之前都需要先cd到目标项目目录下。而分别执行git命令的时候使用subprocess.getstatusoutput()来执行,方便获取标准化输出的结果。这里之所以不使用os.system来执行命令,是因为os.system运行命令的返回值里面包括两个部分,第一部分是命令的结果输出,第二部分是结果是否成功的标识符。

例如执行os.system("git branch | sed -n '/* /s///p'")会返回如下内容:

?
1
2
feature/st-247
0

第一行是我们获取到的分支名,第二行是成功的标识符,0表示命令没有任何问题。

所以我考虑使用subprocess.getstatusoutput来运行命令,这个函数会分别返回结果标识和输出,方便得到想要的执行输出结果。

虽然代码还可以进一步优化,但是已经能满足我的需求了,运行这个脚本就能得到如下的输出结果:

?
1
2
3
4
5
6
[~harry]
*changes made has been committed to feature/st-247*
- https://git.xxxxx.com/someproject/subname/-/commit/d21033057677e6d49d9cea07c64c49e35529545dx
*details*
- remove some invalid logic
please check it if you have free time, thanks.

如果改写成面向对象的方式会更好,调用更简单,传递参数也更少,采用python3语法编写的代码如下所示:

?
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
#coding=utf-8
#!/usr/bin/python
import os
import subprocess
import random
 
class commitcomment:
 def __init__(self, project_path: str, reviewers: list, thanks_words: list):
  self.project_path = project_path
  self.reviewers = reviewers
  self.thanks_words = thanks_words
 # use subprocess to get the current branch name from output
 def get_branch_name(self) -> str:
  os.chdir(self.project_path)
  status, branch_name = subprocess.getstatusoutput("git branch | sed -n '/\* /s///p'")
  return branch_name
 # use subprocess to get the latest commit message from git log
 def get_latest_git_log(self) -> str:
  os.chdir(self.project_path)
  status, log_info = subprocess.getstatusoutput("git log --pretty=format:\"%s\" -1")
  return log_info
 
 # use subprocess to get the latest commit id from git log
 def get_latest_commit_id(self) -> str:
  os.chdir(self.project_path)
  status, commit_id = subprocess.getstatusoutput("git rev-parse head")
  return commit_id
 
 def get_reviewer_by_random(self) -> str:
  return random.choice(self.reviewers)
 
 def get_thanks_words_by_random(self) -> str:
  return random.choice(self.thanks_words)
 
 def create_comment(self):
  print(self.get_reviewer_by_random())
  print("*changes has been committed to " + self.get_branch_name() + "*")
  print("- https://git.xxxx.com/myproject/projectname/-/commit/" + self.get_latest_commit_id())
  print("*details*")
  print("-" + self.get_latest_git_log())
  print(self.get_thanks_words_by_random())
 
 
thanks_words = [
  'review it please, thanks.',
  'actually, i am glad to see you have time to review it, thanks a lot.',
  'please check it if you have free time, thanks.',
  'check it please.'
  'waiting for your code review, thank you.'
 ]
reviewers = [
'[~harry]',
'[~tom]'
]
 
comment = commitcomment('/users/tony/www/autowork', reviewers, thanks_words)
 
comment.create_comment() # will print out the complete comment

thanks_words列表可以在增加多一点,这样随机获取之下重复的概率会更少。当然最后一段也可以自己每次diy,毕竟感谢要发自内心的最好。

这种简化工作流的脚本本质是减少重复性劳动,特别是一天完成了很多个任务的时候。但是反思本身是无法被简化的,不做工作的奴隶,而是工作的主人。
抛砖引玉,希望对自己和未来的自己也是一个还原镜像。

todo:

1.可以每天定时执行这个脚本去生成回复消息。
2.通过脚本传参来动态选择需要被处理的项目目录。在这个案例代码中是hard code的,默认是选择了autowork这个项目。
3.还可以考虑接入语料库(thanks words),这样感谢的话永不重复,还能学点新单词。:)

以上就是python实现代码审查回复消息生成的详细内容,更多关于python 回复消息生成的资料请关注服务器之家其它相关文章!

原文链接:https://www.cnblogs.com/freephp/p/14353791.html

延伸 · 阅读

精彩推荐