in bot/code_coverage_bot/zero_coverage.py [0:0]
def generate(self, artifacts, hgrev, out_dir="."):
report = grcov.report(
artifacts, out_format="coveralls+", source_dir=self.repo_dir
)
report = json.loads(report)
zero_coverage_files = set()
zero_coverage_functions = {}
for sf in report["source_files"]:
name = sf["name"]
# For C/C++ source files, we can consider a file as being uncovered
# when all its source lines are uncovered.
all_lines_uncovered = all(c is None or c == 0 for c in sf["coverage"])
# For JavaScript files, we can't do the same, as the top-level is always
# executed, even if it just contains declarations. So, we need to check if
# all its functions, except the top-level, are uncovered.
all_functions_uncovered = True
for f in sf["functions"]:
f_name = f["name"]
if f_name == "top-level":
continue
if not f["exec"]:
if name in zero_coverage_functions:
zero_coverage_functions[name].append(f["name"])
else:
zero_coverage_functions[name] = [f["name"]]
else:
all_functions_uncovered = False
if all_lines_uncovered or (
len(sf["functions"]) > 1 and all_functions_uncovered
):
zero_coverage_files.add(name)
os.makedirs(os.path.join(out_dir, "zero_coverage_functions"), exist_ok=True)
filesinfo = self.get_fileinfo(zero_coverage_functions.keys())
zero_coverage_info = []
for fname, functions in zero_coverage_functions.items():
info = filesinfo[fname]
info.update(
{
"name": fname,
"funcs": len(functions),
"uncovered": fname in zero_coverage_files,
}
)
zero_coverage_info.append(info)
zero_coverage_report = {"hg_revision": hgrev, "files": zero_coverage_info}
with open(os.path.join(out_dir, "zero_coverage_report.json"), "w") as f:
json.dump(zero_coverage_report, f)