一个自动code review的Python例子
1.背景
经常性遇到要review一堆commit,这里写了一个能够自动搜索需要自己review的change,然后review +2的方法,当然也可以自定一下,实现其他操作。
2.代码
#! /usr/bin/python import re import urllib import requests import codecs import os import sys import json import collections UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36" GerritAccount = "" # f12 -> Network -> XHR XSRF_TOKEN = "" # f12 -> Network -> XHR Cookie = 'GERRIT_UI=POLYGERRIT; GerritAccount=%s; XSRF_TOKEN=%s'%(GerritAccount, XSRF_TOKEN) get_headers = { 'Host': '192.168.1.2', 'Connection': 'keep-alive', 'User-Agent':UserAgent, 'Accept': '*/*', 'Sec-Fetch-Site': 'same-origin', 'Sec-Fetch-Mode': 'cors', 'Sec-Fetch-Dest': 'empty', 'Accept-Encoding': 'gzip, deflate, br', 'Accept-Language': 'en-US,en;q=0.9,zh-HK;q=0.8,zh;q=0.7,zh-CN;q=0.6', 'Cookie': Cookie } post_headers = { 'Host': '192.168.1.2', 'Connection': 'keep-alive', 'Content-Length': '76', 'x-gerrit-auth': XSRF_TOKEN, 'User-Agent':UserAgent, 'content-type': 'application/json', 'Accept': '*/*', 'Sec-Fetch-Site': 'same-origin', 'Sec-Fetch-Mode': 'cors', 'Sec-Fetch-Dest': 'empty', 'Accept-Encoding': 'gzip, deflate, br', 'Accept-Language': 'en-US,en;q=0.9,zh-HK;q=0.8,zh;q=0.7,zh-CN;q=0.6', 'Cookie': Cookie } query_string = collections.OrderedDict() query_string['O'] = 881 query_string['S'] = 0 query_string['q0']= 'has:draft limit:10' query_string['q1']= 'assignee:self (-is:wip OR owner:self OR assignee:self) is:open -is:ignored limit:25' query_string['q2']= 'is:open owner:self is:wip limit:25' query_string['q3']= 'is:open owner:self -is:wip -is:ignored limit:25' query_string['q4']= 'is:open -owner:self -is:wip -is:ignored (reviewer:self OR assignee:self) limit:25' query_string['q5']= 'is:open -is:ignored cc:self limit:10' query_string['q6']= 'is:closed -is:ignored (-is:wip OR owner:self) (owner:self OR reviewer:self OR assignee:self OR cc:self) -age:4w limit:10' query_string['q7']= 'owner:self limit:1' def search_gerrit(ws): global get_headers url = 'https://192.168.1.2/changes/?q=change:%s'%ws # print url data = requests.get(url, headers=get_headers).text.decode('UTF-8') remove = re.compile('\)\]\}\'') textdata = re.sub(remove, "", data) data_json = json.loads(textdata) return data_json def commit_detail(commit_json): global get_headers url = 'https://192.168.1.2/changes/%s~%s/detail?O=916314'%(commit_json[0]['project'].replace('/',"%2F"),commit_json[0]['_number']) detail_data = requests.get(url, headers=get_headers).text.decode('UTF-8') remove = re.compile('\)\]\}\'') textdata = re.sub(remove, "", detail_data) detail_json = json.loads(textdata) print ("Commit : %s"%(detail_json['_number'])) print ("Subject: %s"%(detail_json['subject'])) print ("Project: %s"%(detail_json['project'])) print ("Owner : %s\t%s"%(detail_json['owner']['name'], detail_json['owner']['email'])) return detail_json def parser_query_data(): global query_string query_url = "https://192.168.1.2/changes/" for i in query_string: if (i == 'S'): query_url = query_url + '&%s='%i + urllib.quote(str(query_string[i])) elif (i == 'O'): query_url = query_url + '?%s='%i + urllib.quote(str(query_string[i])) else: query_url = query_url + '&q='%i + urllib.quote(str(query_string[i])) return query_string def get_self_commit(): url = parser_query_data() self_data = requests.get(url, headers=get_headers).text remove = re.compile('\)\]\}\'') textdata = re.sub(remove, "", self_data) self_json = json.loads(textdata) return self_json def review_commit(commit_json, detail_json): review_data = {"drafts":"PUBLISH_ALL_REVISIONS","labels":{"Code-Review":2},"reviewers":[]} url = 'https://192.168.1.2/changes/%s~%s/revisions/%d/review'%(commit_json[0]['project'].replace('/',"%2F"),commit_json[0]['_number'], len(detail_json['revisions'])) # print url post_jsondata = json.dumps(review_data) r = requests.post(url, headers=post_headers, data=post_jsondata) print r.text def auto_reviwer(self_json, max_cnt): cnt = 0 print "auto reviwer changes total %d"%max_cnt for i in range(len(self_json)): for j in range(len(self_json[i])): # print self_json[i][j] if self_json[i][j].has_key('reviewers') == False: continue if self_json[i][j]['reviewers'].has_key('REVIEWER') == False: continue if self_json[i][j]['owner']['email'] == "your_mail@mail.com": continue if self_json[i][j].has_key('status') == True: # print (self_json[i][j]['status']) if self_json[i][j]['status'] != "NEW": continue reviewers = self_json[i][j]['reviewers']['REVIEWER'] for k in range(len(reviewers)): if reviewers[k].has_key('email') == False: continue if reviewers[k]['email'] == "your_mail@mail.com": # input my email commit_json = search_gerrit(self_json[i][j]['_number']) detail_json = commit_detail(commit_json) review_commit(commit_json, detail_json) print self_json[i][j]['_number'], self_json[i][j]['subject'], print "\t\t\033[1;35m", print 'Reviwer OK.', print "\033[0m\n\n" cnt = cnt + 1 if cnt >= max_cnt: return 0 return 0 if __name__ == '__main__': if (len(sys.argv) < 2): print ("Use: %s commit"%(sys.argv[0])) if sys.argv[1] == "autoreviwer": self_json = get_self_commit() print type(self_json), len(self_json) if (len(sys.argv) >= 3): auto_reviwer(self_json, int(sys.argv[2])) else: auto_reviwer(self_json, 0) else: commit_json = search_gerrit(sys.argv[1]) detail_json = commit_detail(commit_json) review_commit(commit_json, detail_json)