1+ #! /usr/bin/env bash
2+ set -euo pipefail
3+
4+ # Script to format Go coverage output as a markdown table
5+ # Usage: ./format-coverage.sh coverage.out [current-coverage] [main-coverage]
6+
7+ COVERAGE_FILE=" ${1:- coverage.out} "
8+ CURRENT_COVERAGE=" ${2:- } "
9+ MAIN_COVERAGE=" ${3:- } "
10+
11+ if [ ! -f " $COVERAGE_FILE " ]; then
12+ echo " Error: Coverage file '$COVERAGE_FILE ' not found"
13+ exit 1
14+ fi
15+
16+ # Start markdown output
17+ echo " ## 📊 Test Coverage Report"
18+ echo " "
19+
20+ # Show current and main coverage if provided
21+ if [ -n " $CURRENT_COVERAGE " ]; then
22+ echo " **Current Coverage:** \` $CURRENT_COVERAGE \` "
23+
24+ if [ -n " $MAIN_COVERAGE " ]; then
25+ echo " **Main Branch Coverage:** \` $MAIN_COVERAGE \` "
26+ echo " "
27+
28+ # Calculate difference
29+ CURRENT_NUM=$( echo " $CURRENT_COVERAGE " | sed ' s/%//' )
30+ MAIN_NUM=$( echo " $MAIN_COVERAGE " | sed ' s/%//' )
31+
32+ if [ -n " $CURRENT_NUM " ] && [ -n " $MAIN_NUM " ]; then
33+ DIFF=$( echo " $CURRENT_NUM - $MAIN_NUM " | bc -l 2> /dev/null || echo " 0" )
34+
35+ if [ " $( echo " $DIFF > 0" | bc -l 2> /dev/null || echo " 0" ) " = " 1" ]; then
36+ echo " **Coverage Change:** 📈 +${DIFF} % (improved)"
37+ elif [ " $( echo " $DIFF < 0" | bc -l 2> /dev/null || echo " 0" ) " = " 1" ]; then
38+ DIFF_ABS=$( echo " $DIFF * -1" | bc -l 2> /dev/null || echo " ${DIFF# -} " )
39+ echo " **Coverage Change:** 📉 -${DIFF_ABS} % (decreased)"
40+ else
41+ echo " **Coverage Change:** ✅ No change"
42+ fi
43+ fi
44+ fi
45+ fi
46+
47+ echo " "
48+ echo " ### Coverage by Package"
49+ echo " "
50+
51+ # Create table header
52+ echo " | Package | Coverage |"
53+ echo " |---------|----------|"
54+
55+ # Parse coverage and group by package
56+ go tool cover -func=" $COVERAGE_FILE " | grep -E ' \.go:[0-9]+:' | \
57+ awk -F: ' {
58+ # Extract package path from filename
59+ split($1, parts, "/");
60+ pkg = "";
61+ for(i=1; i<length(parts); i++) {
62+ if(pkg != "") pkg = pkg "/";
63+ pkg = pkg parts[i];
64+ }
65+
66+ # Extract coverage percentage from the last field
67+ split($0, line, /[[:space:]]+/);
68+ coverage = line[length(line)];
69+
70+ # Store coverage by package
71+ if(pkg in packages) {
72+ packages[pkg] = packages[pkg] "," coverage;
73+ } else {
74+ packages[pkg] = coverage;
75+ }
76+ }
77+ END {
78+ for(pkg in packages) {
79+ # Calculate average coverage for package
80+ split(packages[pkg], covs, ",");
81+ sum = 0;
82+ count = 0;
83+ for(i in covs) {
84+ gsub(/%/, "", covs[i]);
85+ sum += covs[i];
86+ count++;
87+ }
88+ avg = (count > 0) ? sum/count : 0;
89+
90+ # Format package name (remove common prefix)
91+ display_pkg = pkg;
92+ gsub(/github\.com\/speakeasy-api\/openapi\//, "", display_pkg);
93+
94+ # Add emoji indicators based on coverage level
95+ emoji = "🔴";
96+ if(avg >= 90) emoji = "🟢";
97+ else if(avg >= 75) emoji = "🟡";
98+ else if(avg >= 50) emoji = "🟠";
99+
100+ # Output with coverage value for sorting
101+ printf "%.1f|`%s`|%s\n", avg, display_pkg, emoji;
102+ }
103+ }' | sort -n | awk -F' |' ' {
104+ # Re-format after sorting by coverage
105+ printf "| %s | %s %.1f%% |\n", $2, $3, $1;
106+ }'
107+
108+ echo " "
109+ echo " <details>"
110+ echo " <summary>📋 Detailed Coverage by Function (click to expand)</summary>"
111+ echo " "
112+ echo " \`\`\` "
113+ go tool cover -func=" $COVERAGE_FILE "
114+ echo " \`\`\` "
115+ echo " </details>"
116+ echo " "
117+ echo " - 🧪 All tests passed"
118+ echo " - 📈 Full coverage report available in workflow artifacts"
119+ echo " "
120+ echo " _Generated by GitHub Actions_"
0 commit comments