""" 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)