badge router
This commit is contained in:
57
routers/badge.py
Normal file
57
routers/badge.py
Normal file
@@ -0,0 +1,57 @@
|
||||
from fastapi import APIRouter, Query, HTTPException
|
||||
from fastapi.responses import JSONResponse
|
||||
from pathlib import Path
|
||||
import xml.etree.ElementTree as ET
|
||||
|
||||
router = APIRouter(prefix="/badge", tags=["coverage", "badge"])
|
||||
|
||||
|
||||
# ---------- Helper functions ----------
|
||||
|
||||
def parse_coverage_percentage(coverage_file: Path) -> float:
|
||||
"""Parse the overall coverage percentage from coverage.xml."""
|
||||
tree = ET.parse(coverage_file)
|
||||
root = tree.getroot()
|
||||
line_rate = float(root.attrib.get("line-rate", 0))
|
||||
return round(line_rate * 100, 2)
|
||||
|
||||
|
||||
def get_color(pct: float) -> str:
|
||||
"""Return badge color based on coverage."""
|
||||
if pct >= 90:
|
||||
return "brightgreen"
|
||||
if pct >= 75:
|
||||
return "green"
|
||||
if pct >= 60:
|
||||
return "yellow"
|
||||
if pct >= 40:
|
||||
return "orange"
|
||||
return "red"
|
||||
|
||||
|
||||
# ---------- Route ----------
|
||||
@router.get("/{project}", response_class=JSONResponse)
|
||||
async def get_coverage_badge(project: str):
|
||||
"""
|
||||
Return a Shields.io-compatible badge JSON for the given project's coverage.
|
||||
|
||||
Example:
|
||||
/coverage/badge?project=mongo-ops
|
||||
|
||||
Use with Shields.io:
|
||||
https://img.shields.io/endpoint?url=https://api.aetoskia.com/coverage/mongo-ops/badge
|
||||
"""
|
||||
project_dir = Path.cwd() / project
|
||||
coverage_file = project_dir / "coverage.xml"
|
||||
|
||||
if not coverage_file.exists():
|
||||
raise HTTPException(status_code=404, detail=f"No coverage.xml found in '{project}'")
|
||||
|
||||
pct = parse_coverage_percentage(coverage_file)
|
||||
|
||||
return {
|
||||
"schemaVersion": 1,
|
||||
"label": f"{project} coverage",
|
||||
"message": f"{pct}%",
|
||||
"color": get_color(pct),
|
||||
}
|
||||
Reference in New Issue
Block a user