Skip to content

Commit 8f51731

Browse files
BurnzZaignas
andauthored
fix(coverage): missing files in the coverage report if they have no tests (#2607)
This ensures that un-executed files _(i.e. files that aren't tested)_ are included in the coverage report. The current behavior is that coverage.py excludes them by default. This PR configures source files via the auto-generated `.coveragerc` file. See https://coverage.readthedocs.io/en/7.6.10/source.html#execution: > If the source option is specified, only code in those locations will be measured. Specifying the source option also enables coverage.py to report on un-executed files, since it can search the source tree for files that haven’t been measured at all. Closes #2599 Closes #2597 Fixes #2575 --------- Co-authored-by: Ignas Anikevicius <[email protected]>
1 parent 4cb8412 commit 8f51731

File tree

4 files changed

+22
-2
lines changed

4 files changed

+22
-2
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ Unreleased changes template.
7070
([#1169](https://github.com/bazelbuild/rules_python/issues/1169)).
7171
* (gazelle) Don't collapse depsets to a list or into args when generating the modules mapping file.
7272
Support spilling modules mapping args into a params file.
73+
* (coverage) Fix missing files in the coverage report if they have no tests.
7374
* (pypi) From now on `python` invocations in repository and module extension
7475
evaluation contexts will invoke Python interpreter with `-B` to avoid
7576
creating `.pyc` files.

examples/bzlmod/.python_version

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
3.9

python/private/python_bootstrap_template.txt

+10-1
Original file line numberDiff line numberDiff line change
@@ -425,12 +425,21 @@ def _RunForCoverage(python_program, main_filename, args, env,
425425
directory under the runfiles tree, and will recursively delete the
426426
runfiles directory if set.
427427
"""
428+
instrumented_files = [abs_path for abs_path, _ in InstrumentedFilePaths()]
429+
unique_dirs = {os.path.dirname(file) for file in instrumented_files}
430+
source = "\n\t".join(unique_dirs)
431+
432+
PrintVerboseCoverage("[coveragepy] Instrumented Files:\n" + "\n".join(instrumented_files))
433+
PrintVerboseCoverage("[coveragepy] Sources:\n" + "\n".join(unique_dirs))
434+
428435
# We need for coveragepy to use relative paths. This can only be configured
429436
unique_id = uuid.uuid4()
430437
rcfile_name = os.path.join(os.environ['COVERAGE_DIR'], ".coveragerc_{}".format(unique_id))
431438
with open(rcfile_name, "w") as rcfile:
432-
rcfile.write('''[run]
439+
rcfile.write(f'''[run]
433440
relative_files = True
441+
source =
442+
\t{source}
434443
''')
435444
PrintVerboseCoverage('Coverage entrypoint:', coverage_entrypoint)
436445
# First run the target Python file via coveragepy to create a .coverage

python/private/stage2_bootstrap_template.py

+10-1
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,13 @@ def _maybe_collect_coverage(enable):
276276
yield
277277
return
278278

279+
instrumented_files = [abs_path for abs_path, _ in instrumented_file_paths()]
280+
unique_dirs = {os.path.dirname(file) for file in instrumented_files}
281+
source = "\n\t".join(unique_dirs)
282+
283+
print_verbose_coverage("Instrumented Files:\n" + "\n".join(instrumented_files))
284+
print_verbose_coverage("Sources:\n" + "\n".join(unique_dirs))
285+
279286
import uuid
280287

281288
import coverage
@@ -289,8 +296,10 @@ def _maybe_collect_coverage(enable):
289296
print_verbose_coverage("coveragerc file:", rcfile_name)
290297
with open(rcfile_name, "w") as rcfile:
291298
rcfile.write(
292-
"""[run]
299+
f"""[run]
293300
relative_files = True
301+
source =
302+
\t{source}
294303
"""
295304
)
296305
try:

0 commit comments

Comments
 (0)