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类继承与子类实例初始化用法分析
Apr 17 Python
python返回昨天日期的方法
May 13 Python
Python脚本实现自动将数据库备份到 Dropbox
Feb 06 Python
Python利用turtle库绘制彩虹代码示例
Dec 20 Python
python flask中静态文件的管理方法
Mar 20 Python
Python3利用Dlib19.7实现摄像头人脸识别的方法
May 11 Python
pyinstaller打包单个exe后无法执行错误的解决方法
Jun 21 Python
解决Pycharm后台indexing导致不能run的问题
Jun 27 Python
python+opencv像素的加减和加权操作的实现
Jul 14 Python
python初步实现word2vec操作
Jun 09 Python
pycharm无法导入lxml的解决办法
Mar 31 Python
Python实现学生管理系统(面向对象版)
Jun 24 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强制下载类型的实现代码
2011/04/21 PHP
php和html的区别点详细总结
2019/09/24 PHP
javascript对象的property和prototype是这样一种关系
2007/03/24 Javascript
jQuery EasyUI API 中文文档 - ValidateBox验证框
2011/10/06 Javascript
JavaScript 基础篇之对象、数组使用介绍(三)
2012/04/07 Javascript
jQuery判断密码强度实现思路及代码
2013/04/24 Javascript
JS判断不能为空实例代码
2013/11/26 Javascript
js 判断浏览器使用的语言示例代码
2014/03/22 Javascript
JavaScript中几种排序算法的简单实现
2015/07/29 Javascript
浅谈js获取ModelAndView值的问题
2018/03/28 Javascript
Vue-cli3项目配置Vue.config.js实战记录
2018/07/29 Javascript
ES6小技巧之代替lodash
2019/06/07 Javascript
使用webpack将ES6转化ES5的实现方法
2019/10/13 Javascript
vue中组件通信详解(父子组件, 爷孙组件, 兄弟组件)
2020/07/27 Javascript
Python 异常处理实例详解
2014/03/12 Python
剖析Python的Tornado框架中session支持的实现代码
2015/08/21 Python
Python爬虫辅助利器PyQuery模块的安装使用攻略
2016/04/24 Python
python3调用R的示例代码
2018/02/23 Python
Python实现计算圆周率π的值到任意位的方法示例
2018/05/08 Python
python读取一个目录下所有txt里面的内容方法
2018/06/23 Python
python3实现字符串操作的实例代码
2019/04/16 Python
python中的RSA加密与解密实例解析
2019/11/18 Python
使用python实现微信小程序自动签到功能
2020/04/27 Python
Html5移动端获奖无缝滚动动画实现示例
2018/06/25 HTML / CSS
加拿大票务网站:Ticketmaster加拿大
2017/07/17 全球购物
vue+django实现下载文件的示例
2021/03/24 Vue.js
咖啡书吧创业计划书
2014/01/13 职场文书
采购类个人求职的自我评价
2014/02/18 职场文书
七匹狼男装广告词
2014/03/21 职场文书
幼儿园六一儿童节主持节目串词
2014/03/21 职场文书
春节联欢晚会主持词范文
2014/03/24 职场文书
销售提升方案
2014/06/07 职场文书
少年雷锋观后感
2015/06/10 职场文书
工作感言一句话
2015/08/01 职场文书
2016机关干部作风建设心得体会
2016/01/21 职场文书
Java Spring Boot请求方式与请求映射过程分析
2022/06/25 Java/Android