jeuko's picture
Sync from GitHub (main)
8018595 verified
"""
Convert pytest coverage output to markdown table format.
"""
import re
import sys
def coverage_to_markdown(output_file: str) -> None:
"""Convert pytest coverage output to markdown table.
Args:
output_file: Path to the pytest coverage text report.
Returns:
None: The function prints the markdown table to stdout.
"""
try:
with open(output_file) as f:
content = f.read()
except FileNotFoundError:
print("| Error | Coverage output file not found | - | - | - |")
return
# Find the coverage section
lines = content.split("\n")
in_coverage_section = False
coverage_lines = []
total_line = ""
for line in lines:
if "Name" in line and "Stmts" in line and "Miss" in line and "Cover" in line:
in_coverage_section = True
continue
elif in_coverage_section:
if line.strip() == "" or line.startswith("="):
continue
elif line.startswith("TOTAL"):
total_line = line.strip()
break
elif line.strip():
coverage_lines.append(line.strip())
# Print markdown table header
print("| File | Statements | Missing | Coverage | Missing Lines |")
print("|------|------------|---------|----------|---------------|")
# Parse each coverage line
for line in coverage_lines:
# Match pattern: filename.py 123 45 67% 12, 34-56, 78
match = re.match(r"^([^\s]+\.py)\s+(\d+)\s+(\d+)\s+(\d+)%\s*(.*)$", line)
if match:
filename = match.group(1)
statements = int(match.group(2))
missing = int(match.group(3))
coverage_pct = int(match.group(4))
missing_details = match.group(5).strip()
# Clean up filename (remove src/ prefix if present)
clean_filename = filename.replace("src/", "")
# Format missing lines
if missing_details and missing_details != "-":
# Limit the missing details to avoid overly long tables
if len(missing_details) > 40:
missing_details = missing_details[:37] + "..."
missing_cell = f"`{missing_details}`"
else:
missing_cell = "None"
print(
f"| {clean_filename} | {statements} | {missing} | {coverage_pct}% | {missing_cell} |"
)
# Add total row
if total_line:
match = re.match(r"^TOTAL\s+(\d+)\s+(\d+)\s+(\d+)%", total_line)
if match:
statements = int(match.group(1))
missing = int(match.group(2))
coverage_pct = int(match.group(3))
print(
f"| **TOTAL** | **{statements}** | **{missing}** | **{coverage_pct}%** | - |"
)
if __name__ == "__main__":
output_file = sys.argv[1] if len(sys.argv) > 1 else "pytest-output.txt"
coverage_to_markdown(output_file)