Public Access
CI / build (push) Successful in 9m9s
scripts/coverage.sh builds the host tests with coverage counters and reports with gcovr: 94.6% of the 3,193 lines of lib/ today (lib/SD and src/ have no host tests and aren't counted). CI runs it on every push, puts the figure in the job's summary, and on main publishes a coverage badge and a latest-release badge to the branch 'badges'. The README shows them next to Gitea's own badge for the workflow. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT
47 lines
2.5 KiB
Python
Executable File
47 lines
2.5 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""Draws the README's coverage badge from gcovr's summary.
|
|
|
|
Usage: scripts/coverage_badge.py <summary.json> <out.svg>
|
|
scripts/coverage_badge.py --plain <label> <value> <out.svg> any other badge, in blue
|
|
Also prints one line, and appends a short table to $GITHUB_STEP_SUMMARY when CI sets it.
|
|
"""
|
|
import json
|
|
import os
|
|
import sys
|
|
|
|
|
|
def badge(label, value, color, title):
|
|
left, right = 6 * len(label) + 12, 7 * len(value) + 12
|
|
return f'''<svg xmlns="http://www.w3.org/2000/svg" width="{left + right}" height="20" role="img" aria-label="{label}: {value}">
|
|
<title>{title}</title>
|
|
<linearGradient id="s" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient>
|
|
<clipPath id="r"><rect width="{left + right}" height="20" rx="3" fill="#fff"/></clipPath>
|
|
<g clip-path="url(#r)"><rect width="{left}" height="20" fill="#555"/><rect x="{left}" width="{right}" height="20" fill="{color}"/><rect width="{left + right}" height="20" fill="url(#s)"/></g>
|
|
<g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" font-size="11">
|
|
<text x="{left / 2}" y="14">{label}</text><text x="{left + right / 2}" y="14">{value}</text></g></svg>
|
|
'''
|
|
|
|
|
|
def main():
|
|
if sys.argv[1] == "--plain": # any other badge: --plain <label> <value> <out.svg>
|
|
label, value, out = sys.argv[2:5]
|
|
open(out, "w").write(badge(label, value, "#007ec6", f"{label}: {value}"))
|
|
return
|
|
summary = json.load(open(sys.argv[1]))
|
|
lines, branches = summary["line_percent"], summary["branch_percent"]
|
|
label, value = "lib coverage", f"{lines:.0f}%"
|
|
color = "#4c1" if lines >= 90 else "#a4a61d" if lines >= 75 else "#dfb317" if lines >= 60 else "#e05d44"
|
|
svg = badge(label, value, color, f"{label}: {value} of the lines of lib/ are run by the host tests")
|
|
open(sys.argv[2], "w").write(svg)
|
|
print(f"coverage of lib/: {lines:.1f}% of {summary['line_total']} lines, {branches:.1f}% of branches, {len(summary['files'])} files")
|
|
step = os.environ.get("GITHUB_STEP_SUMMARY")
|
|
if step:
|
|
worst = sorted((f["line_percent"], f["filename"]) for f in summary["files"] if f["line_total"] >= 10)[:5]
|
|
with open(step, "a") as out:
|
|
out.write(f"### Coverage of `lib/` by the host tests\n\n**{lines:.1f}%** of {summary['line_total']} lines, {branches:.1f}% of branches.\n\n")
|
|
out.write("| Least covered | Lines |\n|---|---|\n" + "".join(f"| `{name}` | {pct:.0f}% |\n" for pct, name in worst))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|