File size: 4,494 Bytes
05b45a5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
import re
import subprocess
from pathlib import Path

import tomli


def extract_dependency_info():
    """Extract version for kokoro and misaki from pyproject.toml"""
    with open("pyproject.toml", "rb") as f:
        pyproject = tomli.load(f)

    deps = pyproject["project"]["dependencies"]
    info = {}
    kokoro_found = False
    misaki_found = False

    for dep in deps:
        # Match kokoro==version
        kokoro_match = re.match(r"^kokoro==(.+)$", dep)
        if kokoro_match:
            info["kokoro"] = {"version": kokoro_match.group(1)}
            kokoro_found = True

        # Match misaki[...] ==version or misaki==version
        misaki_match = re.match(r"^misaki(?:\[.*?\])?==(.+)$", dep)
        if misaki_match:
            info["misaki"] = {"version": misaki_match.group(1)}
            misaki_found = True

        # Stop if both found
        if kokoro_found and misaki_found:
            break

    if not kokoro_found:
        raise ValueError("Kokoro version not found in pyproject.toml dependencies")
    if not misaki_found:
        raise ValueError("Misaki version not found in pyproject.toml dependencies")

    return info


def run_pytest_with_coverage():
    """Run pytest with coverage and return the results"""
    try:
        # Run pytest with coverage
        result = subprocess.run(
            ["pytest", "--cov=api", "-v"], capture_output=True, text=True, check=True
        )

        # Extract test results
        test_output = result.stdout
        passed_tests = len(re.findall(r"PASSED", test_output))

        # Extract coverage from .coverage file
        coverage_output = subprocess.run(
            ["coverage", "report"], capture_output=True, text=True, check=True
        ).stdout

        # Extract total coverage percentage
        coverage_match = re.search(r"TOTAL\s+\d+\s+\d+\s+(\d+)%", coverage_output)
        coverage_percentage = coverage_match.group(1) if coverage_match else "0"

        return passed_tests, coverage_percentage
    except subprocess.CalledProcessError as e:
        print(f"Error running tests: {e}")
        print(f"Output: {e.output}")
        return 0, "0"


def update_readme_badges(passed_tests, coverage_percentage, dep_info):
    """Update the badges in the README file"""
    readme_path = Path("README.md")
    if not readme_path.exists():
        print("README.md not found")
        return False

    content = readme_path.read_text()

    # Update tests badge
    content = re.sub(
        r"!\[Tests\]\(https://img\.shields\.io/badge/tests-\d+%20passed-[a-zA-Z]+\)",
        f"![Tests](https://img.shields.io/badge/tests-{passed_tests}%20passed-darkgreen)",
        content,
    )

    # Update coverage badge
    content = re.sub(
        r"!\[Coverage\]\(https://img\.shields\.io/badge/coverage-\d+%25-[a-zA-Z]+\)",
        f"![Coverage](https://img.shields.io/badge/coverage-{coverage_percentage}%25-tan)",
        content,
    )

    # Update kokoro badge
    if "kokoro" in dep_info:
        # Find badge like kokoro-v0.9.2::abcdefg-BB5420 or kokoro-v0.9.2-BB5420
        kokoro_version = dep_info["kokoro"]["version"]
        content = re.sub(
            r"(!\[Kokoro\]\(https://img\.shields\.io/badge/kokoro-)[^)-]+(-BB5420\))",
            lambda m: f"{m.group(1)}{kokoro_version}{m.group(2)}",
            content,
        )

    # Update misaki badge
    if "misaki" in dep_info:
        # Find badge like misaki-v0.9.3::abcdefg-B8860B or misaki-v0.9.3-B8860B
        misaki_version = dep_info["misaki"]["version"]
        content = re.sub(
            r"(!\[Misaki\]\(https://img\.shields\.io/badge/misaki-)[^)-]+(-B8860B\))",
            lambda m: f"{m.group(1)}{misaki_version}{m.group(2)}",
            content,
        )

    readme_path.write_text(content)
    return True


def main():
    # Get dependency info
    dep_info = extract_dependency_info()

    # Run tests and get coverage
    passed_tests, coverage_percentage = run_pytest_with_coverage()

    # Update badges
    if update_readme_badges(passed_tests, coverage_percentage, dep_info):
        print(f"Updated badges:")
        print(f"- Tests: {passed_tests} passed")
        print(f"- Coverage: {coverage_percentage}%")
        if "kokoro" in dep_info:
            print(f"- Kokoro: {dep_info['kokoro']['version']}")
        if "misaki" in dep_info:
            print(f"- Misaki: {dep_info['misaki']['version']}")
    else:
        print("Failed to update badges")


if __name__ == "__main__":
    main()