diff --git a/src/updater.py b/src/updater.py index a2e47ef98..61eab4e22 100644 --- a/src/updater.py +++ b/src/updater.py @@ -22,6 +22,13 @@ COMMIT_ACTIVITY_PENDING = 'pending' COMMIT_ACTIVITY_FAILED = 'failed' GITHUB_REPO_STEP_TIMEOUT = 90 +COVERAGE_BADGE_COLOR_THRESHOLDS = ( + (90, 'brightgreen'), + (70, 'green'), + (50, 'yellowgreen'), + (30, 'yellow'), + (10, 'orange'), +) def update_aur(aur_repos: list): @@ -86,6 +93,30 @@ def fetch_coverage_trend_for_repo(base_url: str, repo_name: str, headers: dict) return coverage_trend_data +def _coverage_badge_color(coverage: float) -> str: + for minimum, color in COVERAGE_BADGE_COLOR_THRESHOLDS: + if coverage >= minimum: + return color + return 'red' + + +def _get_codecov_coverage(data: dict) -> float: + try: + return float((data.get('totals') or {}).get('coverage', 0) or 0) + except (TypeError, ValueError): + return 0.0 + + +def _build_codecov_shields_badge(data: dict) -> dict: + coverage = _get_codecov_coverage(data) + return { + 'schemaVersion': 1, + 'label': 'codecov', + 'message': f'{coverage:g}%', + 'color': _coverage_badge_color(coverage), + } + + def update_codecov(): """ Get code coverage data from Codecov API. @@ -135,6 +166,9 @@ def update_codecov(): file_path = os.path.join(BASE_DIR, 'codecov', repo['name']) helpers.write_json_files(file_path=file_path, data=data) + badge_path = os.path.join(BASE_DIR, 'shields', 'codecov', repo['name']) + helpers.write_json_files(file_path=badge_path, data=_build_codecov_shields_badge(data)) + # Get coverage trend data coverage_trend_data = fetch_coverage_trend_for_repo(base_url, repo["name"], headers) diff --git a/tests/unit/test_updater.py b/tests/unit/test_updater.py index 4ad90beb2..866c3a8be 100644 --- a/tests/unit/test_updater.py +++ b/tests/unit/test_updater.py @@ -151,6 +151,39 @@ def fake_get(url, headers, params): assert calls == [1, 2] +@pytest.mark.parametrize(('coverage', 'color'), [ + (100, 'brightgreen'), + (90, 'brightgreen'), + (89.9, 'green'), + (70, 'green'), + (69.9, 'yellowgreen'), + (50, 'yellowgreen'), + (49.9, 'yellow'), + (30, 'yellow'), + (29.9, 'orange'), + (10, 'orange'), + (9.9, 'red'), +]) +def test_coverage_badge_color(coverage, color): + assert updater._coverage_badge_color(coverage) == color + + +def test_build_codecov_shields_badge(): + assert updater._build_codecov_shields_badge({'totals': {'coverage': 81.5}}) == { + 'schemaVersion': 1, + 'label': 'codecov', + 'message': '81.5%', + 'color': 'green', + } + + assert updater._build_codecov_shields_badge({'totals': {'coverage': 'bad'}}) == { + 'schemaVersion': 1, + 'label': 'codecov', + 'message': '0%', + 'color': 'red', + } + + def test_update_codecov_success(monkeypatch, tmp_path): base = tmp_path / 'gh-pages' repos_file = base / 'github' / 'repos.json' @@ -176,6 +209,7 @@ def fake_get(url, headers): assert any('active-repo' in path for path, _ in writes) assert not any('archived-repo' in path for path, _ in writes) + assert any(path.endswith(('shields\\codecov\\active-repo', 'shields/codecov/active-repo')) for path, _ in writes) assert any(path.endswith('active-repo_coverage_trend') for path, _ in writes)