Created
August 14, 2025 20:19
-
-
Save bbengfort/8e8ec1a7472b5b7f90a4a72c452ef167 to your computer and use it in GitHub Desktop.
Tabulate and pretty print a coverage table from go test -cover output.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env python3 | |
| # Runs go coverage tools and generates a table of coverage per package. | |
| import os | |
| import argparse | |
| import subprocess | |
| from itertools import groupby | |
| from tabulate import tabulate | |
| def gotest(package="./...", profile="coverage.out"): | |
| cmd = [ | |
| "go", "test", "-covermode=count", | |
| "-coverprofile=" + profile, | |
| package | |
| ] | |
| subprocess.run(cmd) | |
| def read_coverage(profile="coverage.out"): | |
| with open(profile, "r") as f: | |
| for line in f: | |
| if line.startswith("mode:"): | |
| continue | |
| parts = line.split() | |
| parts[0] = os.path.dirname(parts[0].split(":")[0]) | |
| parts[1] = int(parts[1]) | |
| parts[2] = int(parts[2]) | |
| yield parts | |
| def coverage(profile="coverage.out"): | |
| for pkg, group in groupby(read_coverage(profile), key=lambda x: x[0]): | |
| group = list(group) | |
| total = sum(x[1] for x in group) | |
| covered = sum(x[1] for x in group if x[2] > 0) | |
| yield ( | |
| pkg, | |
| covered, | |
| total, | |
| f"{covered / total if total > 0 else 0:0.2%}", | |
| ) | |
| def main(args): | |
| # run go test | |
| gotest() | |
| # run go tool cover | |
| cov = list(coverage()) | |
| print(tabulate(cov, headers=["Package", "Covered", "Statements", "Coverage"], tablefmt="markdown")) # noqa | |
| # cleanup | |
| os.remove("coverage.out") | |
| if __name__ == "__main__": | |
| opts = {} | |
| parser = argparse.ArgumentParser( | |
| description="runs go coverage tools and gernerates a package coverage table", # noqa | |
| epilog="yeh, this should really be a golang program ... le sigh" | |
| ) | |
| for pargs, kwargs in opts.items(): | |
| if isinstance(pargs, str): | |
| pargs = (pargs,) | |
| parser.add_argument(*pargs, **kwargs) | |
| args = parser.parse_args() | |
| main(args) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment