def get_revisions_list(checker_name, offset, count, search): if checker_mgr.get_checker(checker_name) is None: printer.aprint('找不到该检查机:{0}'.format(checker_name)) return {} code_checker = checker_mgr.get_checker(checker_name) rev_list = code_checker.get_result(offset, count, search) return rev_list
def check(self, changed_files) -> int: # 生成要检查源码文件集合的xml文件 printer.aprint('准备文件中...') max_rev = self.__gen_src_filters(changed_files) # 生成检查结果plog格式 printer.aprint(self.get_name() + '生成plog...') # 返回有错误的最小版本号 return self.__gen_plog(max_rev)
def auto_check(): global thread_lock, checker_thread with thread_lock: if checker_thread is None: printer.aprint('定时检查开始\n') socketio.emit('checker_state', 1) print("定时启动\n") checker_thread = socketio.start_background_task( target=background_thread_check) else: printer.aprint('正在自检\n')
def do_check(rev_start, rev_end, checker_name) -> int: global source_controller, checker_mgr if checker_name == "": return 0 progressbar.set_total(1) # 获取版本变化文件集合 printer.aprint('获取区间版本r{0}至r{1}的差异文件...'.format(rev_start, rev_end)) changed_files = source_controller.get_versions_changed(rev_start, rev_end) progressbar.add(1) printer.aprint('获取区间版本r{0}至r{1}的差异文件完成'.format(rev_start, rev_end)) ignore_files = [] excluded_paths = "/ThirdParty/;/libProto/;/ProtoCommon/".split(';') for file_name in changed_files: for excluded_path in excluded_paths: if excluded_path in file_name: ignore_files.append(file_name) for ignore_file in ignore_files: if ignore_file in changed_files: changed_files.pop(ignore_file) # 检查代码 printer.aprint('检查r{0}至r{1}代码中...'.format(rev_start, rev_end)) checker = checker_mgr.get_checker(checker_name) min_error_rev = checker.check(changed_files) printer.aprint('{0}检查结束...'.format(checker.get_name())) return min_error_rev
def do_auto_check(dic_min_rev): dic_min_rev_error = {} rev_start = config.get_check_revision_start() rev_end = 'head' check_names = get_checker_name_list() progressbar.set_total(1) # 更新代码 printer.aprint('更新代码...') rev_end = source_controller.updateTo(rev_end) progressbar.add(1) printer.aprint('已更新代码至r{0}'.format(rev_end)) for check_name in check_names: if check_name in dic_min_rev: rev_start = dic_min_rev[check_name] min_rev_error = do_check(rev_start, rev_end, check_name) dic_min_rev_error[check_name] = min_rev_error printer.aprint('全部检查完毕.') return dic_min_rev_error
def check(self, changed_files) -> None: self.__gen_src_filters(changed_files) printer.aprint(self.get_name() + '生成xml...') self.__gen_res()
def __gen_plog(self, max_rev): # 最早一个拥有错误的版本,用来以后检查的起始点 min_rev_has_error = max_rev os.system("if not exist {0} mkdir {0}".format( config.get_dir_pvs_plogs())) db = EasySqlite('rfp.db') for parent, dirnames, filenames in os.walk("temp", followlinks=True): progressbar.set_total(len(filenames)) for file in filenames: file_path = os.path.join(parent, file) filename = os.path.splitext(file)[0] output_file_path = "{0}\\{1}.plog".format( config.get_dir_pvs_plogs(), filename) if os.path.exists(output_file_path): os.remove(output_file_path) xmlRoot = etree.parse(file_path) pathEle = xmlRoot.find('./SourceFiles/Path') src_path = pathEle.text printer.aprint(self.get_name() + '文件{0}检查开始'.format(src_path)) cmd = 'pvs-studio_cmd.exe --target "{0}" --output "{1}" --platform "x64" --configuration "Release" --sourceFiles "{2}" --settings "{3}" --excludeProjects {4} 2>>pvs_err.log'.format( config.get_dir_sln(), output_file_path, file_path, config.get_path_pvs_setting(), config.get_exclude_projects()) ret = os.system(cmd) if (ret & 1) / 1 == 1: printer.errprint( "PVS-Studio: error (crash) during analysis of some source file(s)" ) if (ret & 2) / 2 == 1: printer.errprint("PVS-Studio: GeneralExeption") if (ret & 4) / 4 == 1: printer.errprint( "PVS-Studio: some of the command line arguments passed to the tool were incorrect" ) if (ret & 8) / 8 == 1: printer.errprint( "PVS-Studio: specified project, solution or analyzer settings file were not found" ) if (ret & 16) / 16 == 1: printer.errprint( "PVS-Studio: specified configuration and (or) platform were not found in a solution file" ) if (ret & 32) / 32 == 1: printer.errprint( "PVS-Studio: solution file or project is not supported or contains errors" ) if (ret & 64) / 64 == 1: printer.errprint( "PVS-Studio: incorrect extension of analyzed project or solution" ) if (ret & 128) / 128 == 1: printer.errprint( "PVS-Studio: incorrect or out-of-date analyzer license" ) if (ret & 256) / 256 == 1: has_error = True printer.warnprint( "PVS-Studio: some issues were found in the source code" ) if (ret & 512) / 512 == 1: printer.errprint( "PVS-Studio: some issues were encountered while performing analyzer message suppression" ) if (ret & 1024) / 1024 == 1: printer.errprint( "PVS-Studio: indicates that analyzer license will expire in less than a month" ) if ret == 0: has_error = False print("pvs-studio ret: " + str(ret)) cur_file_max_rev = 0 logs_json = [] logsRoot = xmlRoot.find('logs') for log in logsRoot.iter('log'): log_json = { "rev": log.attrib["rev"], "author": log.attrib["author"], "msg": log.attrib["msg"] } logs_json.append(log_json) revision = int(log.attrib["rev"]) if cur_file_max_rev < revision: cur_file_max_rev = revision db.execute( "delete from " + self.CONST_TABLE_NAME + " where file_path = ?", [src_path], False, True) db.execute( "delete from " + self.CONST_TABLE_NAME + "_fts where file_path = ?", [src_path], False, True) # 更新进度条用 progressbar.add(1) if has_error: plogXmlRoot = etree.parse(output_file_path) analysisLogs = plogXmlRoot.findall( 'PVS-Studio_Analysis_Log') ignoreCnt = 0 for analysisLog in analysisLogs: errCode = analysisLog.find('ErrorCode').text if errCode is None: continue if errCode.lower() in (code.lower() for code in self.excludedCodes): plogXmlRoot.getroot().remove(analysisLog) ignoreCnt = ignoreCnt + 1 if len(analysisLogs) == ignoreCnt: os.remove(output_file_path) continue plogXmlRoot.write(output_file_path) project = analysisLogs[0].find('Project').text filename = analysisLogs[0].find('ShortFile').text log_str = json.dumps(log_json) res_ignore = db.execute( "select * from " + self.CONST_TABLE_NAME + "_ignore" + " where rev=? and project=? and file=?", (cur_file_max_rev, project, filename), False, False) if filename == 'Dump.cpp': if len(res_ignore) == 0: print("Dump cannot find", cur_file_max_rev, project, filename) if len(res_ignore) != 0: os.remove(output_file_path) continue if min_rev_has_error < cur_file_max_rev: min_rev_has_error = cur_file_max_rev db.execute( "insert into " + self.CONST_TABLE_NAME + " values (?, ?, ?, current_timestamp, ?, ?);", (project, filename, src_path, output_file_path, log_str), False, True) body_str = '{0} {1} {2}'.format(project, filename, log_str) db.execute( "insert into " + self.CONST_TABLE_NAME + "_fts values (?, ?);", (src_path, body_str), False, True) printer.aprint(self.get_name() + '生成 {0} 的网页报告...'.format(src_path)) self.__convert_to_html(output_file_path) printer.aprint(self.get_name() + '文件{0}检查结束'.format(src_path)) return min_rev_has_error