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


Posted in Python onFebruary 01, 2021

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

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

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

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

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

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

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

**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的相关命令实现,如下:

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

第二步:获取commit id。

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

git rev-parse HEAD

第三步:获取提交信息。

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

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

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

%H 提交对象(commit)的完整哈希字串 
%h 提交对象的简短哈希字串 
%T 树对象(tree)的完整哈希字串 
%t 树对象的简短哈希字串 
%P 父对象(parent)的完整哈希字串 
%p 父对象的简短哈希字串 
%an 作者(author)的名字 
%ae 作者的电子邮件地址 
%ad 作者修订日期(可以用 -date= 选项定制格式) 
%ar 作者修订日期,按多久以前的方式显示 
%cn 提交者(committer)的名字 
%ce 提交者的电子邮件地址 
%cd 提交日期 
%cr 提交日期,按多久以前的方式显示 
%s 提交说明

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

git log --pretty=format:"%H" -1

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

#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'")会返回如下内容:

feature/ST-247
0

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

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

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

[~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语法编写的代码如下所示:

#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 回复消息生成的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
python logging类库使用例子
Nov 22 Python
Python urllib、urllib2、httplib抓取网页代码实例
May 09 Python
Python实现加载及解析properties配置文件的方法
Mar 29 Python
python基础教程项目五之虚拟茶话会
Apr 02 Python
pandas.DataFrame 根据条件新建列并赋值的方法
Apr 08 Python
python 对类的成员函数开启线程的方法
Jan 22 Python
Python中的类与类型示例详解
Jul 10 Python
python实现多进程通信实例分析
Sep 01 Python
python如何操作mysql
Aug 17 Python
python 实现图片批量压缩的示例
Dec 18 Python
Python读写Excel表格的方法
Mar 02 Python
python之基数排序的实现
Jul 26 Python
anaconda安装pytorch1.7.1和torchvision0.8.2的方法(亲测可用)
Feb 01 #Python
python 列表推导和生成器表达式的使用
Feb 01 #Python
matplotlib部件之矩形选区(RectangleSelector)的实现
Feb 01 #Python
深入理解Python变量的数据类型和存储
Feb 01 #Python
selenium3.0+python之环境搭建的方法步骤
Feb 01 #Python
Pytorch 图像变换函数集合小结
Feb 01 #Python
Scrapy+Selenium自动获取cookie爬取网易云音乐个人喜爱歌单
Feb 01 #Python
You might like
分享几种好用的PHP自定义加密函数(可逆/不可逆)
2020/09/15 PHP
用JavaScript显示随机图像或引用
2009/04/21 Javascript
jquery插件实现鼠标经过图片右侧显示大图的效果(类似淘宝)
2013/02/04 Javascript
基于jquery的文字向上跑动类似跑马灯的效果
2014/09/22 Javascript
js进行表单验证实例分析
2015/02/10 Javascript
深入解析JavaScript中函数的Currying柯里化
2016/03/19 Javascript
jQuery Ajax Post 回调函数不执行问题的解决方法
2016/08/15 Javascript
解析利用javascript如何判断一个数为素数
2016/12/08 Javascript
js处理层级数据结构的方法小结
2017/01/17 Javascript
JavaScript验证知识整理
2017/03/24 Javascript
微信小程序实现tab页面切换功能
2018/07/13 Javascript
jQuery ajax仿Google自动提示SearchSuggess功能示例
2019/03/28 jQuery
判断JavaScript中的两个变量是否相等的操作符
2019/12/21 Javascript
JS面向对象编程基础篇(三) 继承操作实例详解
2020/03/03 Javascript
Openlayers3实现车辆轨迹回放功能
2020/09/29 Javascript
使用python实现接口的方法
2017/07/07 Python
PyCharm代码整体缩进,反向缩进的方法
2018/06/25 Python
pandas.DataFrame选取/排除特定行的方法
2018/07/03 Python
Python迭代器与生成器基本用法分析
2018/07/26 Python
PyQt5 QListWidget选择多项并返回的实例
2019/06/17 Python
python射线法判断检测点是否位于区域外接矩形内
2019/06/28 Python
利用python-pypcap抓取带VLAN标签的数据包方法
2019/07/23 Python
python将图片转base64,实现前端显示
2020/01/09 Python
python使用正则表达式去除中文文本多余空格,保留英文之间空格方法详解
2020/02/11 Python
Python在线和离线安装第三方库的方法
2020/10/31 Python
Python之字符串的遍历的4种方式
2020/12/08 Python
JD Sports意大利:英国篮球和运动时尚的领导者
2017/10/29 全球购物
美国亚马逊旗下时尚女装网店:SHOPBOP(支持中文)
2020/10/17 全球购物
法人代表任命书范本
2014/06/05 职场文书
2014年学校财务工作总结
2014/12/06 职场文书
质量整改通知单
2015/04/21 职场文书
祝寿主持词
2015/07/02 职场文书
四十年同学聚会致辞
2015/07/28 职场文书
python元组打包和解包过程详解
2021/08/02 Python
JavaScript实现简单拖拽效果
2021/09/15 Javascript
Moment的feature导致线上bug解决分析
2022/09/23 Javascript