pyWebLayout/scripts/run_coverage.py
2025-11-12 12:03:27 +00:00

127 lines
4.0 KiB
Python

#!/usr/bin/env python3
"""
Local coverage runner script.
Runs test and documentation coverage locally and generates badges.
"""
import subprocess
import os
def run_command(cmd, description):
"""Run a command and handle errors."""
print(f"\n{'='*50}")
print(f"Running: {description}")
print(f"Command: {cmd}")
print(f"{'='*50}")
try:
result = subprocess.run(cmd, shell=True, check=True, capture_output=True, text=True)
print(result.stdout)
if result.stderr:
print("STDERR:", result.stderr)
return True
except subprocess.CalledProcessError as e:
print(f"Error running {description}:")
print(f"Return code: {e.returncode}")
print(f"STDOUT: {e.stdout}")
print(f"STDERR: {e.stderr}")
return False
def main():
"""Run full coverage analysis locally."""
print("Local Coverage Analysis for pyWebLayout")
print("=" * 60)
# Change to project root if running from scripts directory
if os.path.basename(os.getcwd()) == "scripts":
os.chdir("..")
# Install required packages
print("\n1. Installing required packages...")
packages = [
"pytest pytest-cov",
"coverage-badge",
"interrogate"
]
for package in packages:
if not run_command(f"pip install {package}", f"Installing {package}"):
print(f"Failed to install {package}, continuing...")
# Run tests with coverage
print("\n2. Running tests with coverage...")
test_cmd = (
"python -m pytest tests/ -v --cov=pyWebLayout "
"--cov-report=term-missing --cov-report=json --cov-report=html --cov-report=xml"
)
run_command(test_cmd, "Running tests with coverage")
# Generate test coverage badge
print("\n3. Generating test coverage badge...")
run_command("coverage-badge -o coverage.svg -f", "Generating test coverage badge")
# Check documentation coverage
print("\n4. Checking documentation coverage...")
docs_cmd = (
"interrogate -v --ignore-init-method --ignore-init-module --ignore-magic "
"--ignore-private --ignore-property-decorators --ignore-semiprivate "
"--fail-under=80 --generate-badge coverage-docs.svg pyWebLayout/"
)
run_command(docs_cmd, "Checking documentation coverage")
# Generate coverage summary
print("\n5. Generating coverage summary...")
# Write a temporary script to avoid shell quoting issues
summary_script_content = '''import json
import os
if os.path.exists("coverage.json"):
with open("coverage.json", "r") as f:
coverage_data = json.load(f)
total_coverage = round(coverage_data["totals"]["percent_covered"], 1)
covered_lines = coverage_data["totals"]["covered_lines"]
total_lines = coverage_data["totals"]["num_statements"]
with open("coverage-summary.txt", "w") as f:
f.write(f"{total_coverage}%")
print(f"Test Coverage: {total_coverage}%")
print(f"Lines Covered: {covered_lines}/{total_lines}")
else:
print("No coverage data found")
'''
# Write and execute temporary script
with open('temp_coverage_summary.py', 'w') as f:
f.write(summary_script_content)
run_command("python temp_coverage_summary.py", "Generating coverage summary")
# Clean up temporary script
if os.path.exists('temp_coverage_summary.py'):
os.remove('temp_coverage_summary.py')
# List generated files
print("\n6. Generated files:")
files = ["coverage.svg", "coverage-docs.svg", "coverage-summary.txt", "htmlcov/", "coverage.json", "coverage.xml"]
for file in files:
if os.path.exists(file):
print(f"{file}")
else:
print(f"{file} (not found)")
print("\n" + "="*60)
print("Coverage analysis complete!")
print("To update your README with badges, run:")
print(" python scripts/update_coverage_badges.py")
print("\nTo view detailed HTML coverage report:")
print(" open htmlcov/index.html")
if __name__ == "__main__":
main()