1- import os
2- import subprocess
3- from pathlib import Path
4- import sys
5- from typing import TYPE_CHECKING , Any
1+ Import ("env" )
62
7- if TYPE_CHECKING :
8- def Import (* names : str ) -> tuple [Any , ...]:
9- ...
10-
11- def _project_root ():
12- return Path (__file__ ).resolve ().parent .parent
13-
14-
15- def _native_build_dir ():
16- return _project_root () / ".pio" / "build" / "native"
17-
18-
19- def _has_coverage_data ():
20- return any (_native_build_dir ().rglob ("*.gcda" ))
21-
22-
23- def ensure_gcovr_installed (build_env ):
24- """Checks if gcovr is installed, and installs it via pip if not."""
25- try :
26- import gcovr
27- except ImportError :
28- print ("gcovr not found! Installing it into the PlatformIO environment..." )
29- # $PYTHONEXE ensures we use PlatformIO's isolated Python environment, not the system OS Python
30- build_env .Execute ("$PYTHONEXE -m pip install gcovr" )
31-
32-
33- def generateCoverageInfo ():
34- if not _has_coverage_data ():
35- print ("Skipping coverage report generation because no .gcda files were produced." )
36- return
37-
38- print ("Generating code coverage report..." )
39- gcovr_cmd = ["gcovr" ]
40- report_dir = _project_root ()
41- # Adjust this path if you are testing multiple specific folders
42- subprocess .run (gcovr_cmd + ["--html-details" , ".pio/coverage.html" , "--filter" , "src/" ], check = True , cwd = report_dir )
43- print (f"Coverage report generated at: .pio/coverage.html" )
44- subprocess .run (gcovr_cmd + ["--markdown" , ".pio/coverage.md" , "--filter" , "src/" ], check = True , cwd = report_dir )
45- print (f"Coverage report generated at: .pio/coverage.md" )
46-
47-
48- def configure_build ():
49- Import ("env" )
50- build_env = globals ()["env" ]
51- build_env .Append (LINKFLAGS = ["--coverage" ])
52- ensure_gcovr_installed (build_env )
53-
54-
55- def main (argv ):
56- if not argv :
57- print ("Usage: test-coverage.py <test-program> [args...]" , file = sys .stderr )
58- return 2
59-
60- completed = subprocess .run (argv , cwd = _project_root (), env = os .environ .copy (), check = False )
61- generateCoverageInfo ()
62- return completed .returncode
63-
64-
65- if __name__ == "__main__" :
66- raise SystemExit (main (sys .argv [1 :]))
67-
68- configure_build ()
3+ # Ensure coverage flags reach the linker so .gcda files are produced.
4+ env .Append (LINKFLAGS = ["--coverage" ])
0 commit comments