1.思路
1)获取全量代码覆盖率报告;
2)指定两个版本对比,得到增量代码;
3)通过增量代码获取到增量包名、类、方法、新增行数组成的字典;
4)通过全量覆盖率文件获取到文件增量代码行、增量代码行数、覆盖行、覆盖行数;
5)循环读取,更改各个目录下的index.html和类名.html文件;显示新增行数、覆盖行数和覆盖率;
6)循环读取,更改类名.java.html文件,在新增行数前加上蓝色的钻石标记;
2.实现
diff_processor.py 执行增量筛选操作
class DiffProcessor():
def __init__(self, diffpath,code_path,coco_path):
'''
:param diffpath:gitdiff代码文件路径
:param code_path: 源码路径
:param coco_path: jacoco全量覆盖率报告路径
'''
self.diffpath = diffpath
self.code_path = code_path
self.coco_path = coco_path
2.1 get_diff方法:
1)循环读取gitdiff文件,如果当前行是以"diff --git"开头的,获取完整文件名,如:src/main/webapp/WEB-INF/default/jsp/tlfund/management/fund_transfer_record_list.jsp;
2)如果当前行中包含"@@XXX @@"字样的,获取classname;
3)如果当前行是以“-”开头的,跳过;
4)过滤方法名:如果当前行不是以"+//"、“//”开头的,包含"private"或"public"和"(",且"function"、“=”、“if(”、"if ("、"for "、“for(”、“catch”、"logger."、“.”不在行内,且不是以";"结尾的,获取当前行并过滤出方法名;如果方法名不是"if"、"for"且"{"、"}"、"."、"+"、"@"不在行内的;将方法名添加到字典中,如果方法名已存在,将当前行添加到方法名的列表中;
5)如果当前行是以"+"开头的,添加到对应的方法名列表中;
6)最终返回{"文件名":{"diff_voids":{ {方法名:[新增行]},'diff_lines':[所有新增行]}}的字典;
def get_diff(self):
"""获取diff详情"""
with open(self.diffpath, 'r+') as e:
data = e.read()
diff = data.split("\n")
ret = {}
void_dics = {}
diff_lines = []
file_name = ""
line_void = ""
current_line = 0
for line in diff:
if line.startswith('diff --git'):
# 进入新的block
if file_name != "":
ret[file_name] = {}
ret[file_name]["diff_lines"] = diff_lines
ret[file_name]['diff_voids'] = void_dics
file_name = re.findall('b/(\S+)$', line)[0]
diff_lines = []
void_dics = {}
current_line = 0
classname = ""
elif re.match('@@ -\d+,\d+ \+(\d+),\d+ @@', line):
match = re.match('@@ -\d+,\d+ \+(\d+),\d+ @@', line)
current_line = int(match.group(1)) - 1
if "class" in line:
classname = line.split("class")[-1].split(" ")[1]
if classname and classname not in void_dics.keys():
void_dics[classname]=[]
line_void = ""
elif classname in void_dics:
line_void = ""
elif line.startswith("-"):
continue
elif not line.startswith("+//") and not line.startswith("//") and ("public" in line or "private" in line) and "(" in line and "function" not in line and "=" not in line \
and "if(" not in line and "if (" not in line and "for " not in line and "for(" not in line and "catch" not in line and "logger." not in line and not line.strip("\t").endswith(";") \
and "." not in line:
current_line += 1
line_void = line.split("(")[0].split(" ")[-1].strip("//").strip("\t")
if line_void and line_void != "if" and line_vo