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中用Descriptor实现类级属性(Property)详解
Sep 18 Python
浅谈插入排序算法在Python程序中的实现及简单改进
May 04 Python
深入理解Python中的*重复运算符
Oct 28 Python
通过python+selenium3实现浏览器刷简书文章阅读量
Dec 26 Python
python利用插值法对折线进行平滑曲线处理
Dec 25 Python
python random从集合中随机选择元素的方法
Jan 23 Python
Python hashlib模块加密过程解析
Nov 05 Python
Python脚本操作Excel实现批量替换功能
Nov 20 Python
python装饰器原理与用法深入详解
Dec 19 Python
pytorch三层全连接层实现手写字母识别方式
Jan 14 Python
基于Python实现全自动下载抖音视频
Nov 06 Python
基于Python绘制子图及子图刻度的变换等的问题
May 23 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操作SVN版本服务器类代码
2011/11/27 PHP
php cli模式学习(PHP命令行模式)
2013/06/03 PHP
十个PHP高级应用技巧果断收藏
2015/09/25 PHP
PHP 将数组打乱 shuffle函数的用法及简单实例
2016/06/17 PHP
PHPCMS2008广告模板SQL注入漏洞修复
2016/10/11 PHP
php递归函数怎么用才有效
2018/02/24 PHP
js中格式化日期时间型数据函数代码
2010/11/08 Javascript
jQuery参数列表集合
2011/04/06 Javascript
日期处理的js库(迷你版)--自建js库总结
2011/11/21 Javascript
node.js中的http.response.write方法使用说明
2014/12/14 Javascript
node.js解决获取图片真实文件类型的问题
2014/12/20 Javascript
基于JavaScript实现移动端TAB触屏切换效果
2015/10/20 Javascript
js点击按钮实现带遮罩层的弹出视频效果
2015/12/19 Javascript
AngularJS身份验证的方法
2016/02/17 Javascript
AngularJS 路由和模板实例及路由地址简化方法(必看)
2016/06/24 Javascript
轻松玩转BootstrapTable(后端使用SpringMVC+Hibernate)
2017/09/06 Javascript
vue 动态绑定背景图片的方法
2018/08/10 Javascript
Python正则表达式介绍
2012/08/06 Python
在Python中使用pngquant压缩png图片的教程
2015/04/09 Python
python机器学习理论与实战(一)K近邻法
2021/01/28 Python
Python zip()函数用法实例分析
2018/03/17 Python
解决Python3 被PHP程序调用执行返回乱码的问题
2019/02/16 Python
Python配置文件处理的方法教程
2019/08/29 Python
python模块如何查看
2020/06/16 Python
Python打印不合法的文件名
2020/07/31 Python
德国汽车零件和汽车配件网上商店:kfzteile24
2018/11/14 全球购物
英国排名第一的宠物店:PetPlanet
2020/02/02 全球购物
物业管理毕业生的自我评价
2014/02/17 职场文书
烹饪自我鉴定
2014/03/01 职场文书
2014年底工作总结
2014/12/15 职场文书
副总经理岗位职责范本
2015/04/08 职场文书
2015年公务员转正工作总结
2015/04/24 职场文书
浪漫的婚礼主持词
2015/06/30 职场文书
Python超简单容易上手的画图工具库推荐
2021/05/10 Python
Windows环境下实现批量执行Sql文件
2021/10/05 SQL Server
「女孩的钓鱼慢活」全新版权绘公布
2022/03/21 日漫