Option for `coverage lcov` to ignore empty database
Is your feature request related to a problem? Please describe.
See https://github.com/bazel-contrib/rules_python/issues/2762 for some context.
Due to the way Bazel and rules_python is set up, it can happen that coverage run is invoked so that it generates an empty .coverage database. In particular, Bazel can be instructed to only instrument certain files/directories for coverage; if these directories don't contain any Python files the coverage database will be empty. In that case, coverage lcov unconditionally fails with a NoDataError exception. This case is somewhat difficult to detect in advance.
Describe the solution you'd like
A command-line option to coverage lcov to ignore an empty database. When the option is given, coverage lcov would write an empty LCOV file and exit successfully.
Describe alternatives you've considered
- Somehow detect the case in advance: this seems quite difficult because the coverage driver script in rules_python would need to detect whether there are any Python source files in the to-be-covered directories, effectively duplicating the work of coverage.py
- Detect the case after the
coverage runcommand: Would require finding and parsing the.coveragedatabase - Ignoring the exit status of
coverage lcov: would suppress detection of any other errors
Additional context https://github.com/bazel-contrib/rules_python/issues/2762
I volunteer to work on this, if it makes sense to implement. Seems good for a first time contribution.
@nedbat what's your opinion?
This option seems a bit unusual. Would it be better to have an empty .coverage always produce an empty .lcov? That seems to be the most straightforward way to proceed. Or perhaps coverage run shouldn't write an empty .coverage file. What is it running? I don't know that we've encountered these kinds of scenarios before.
BTW: to find and parse the .coverage database you can use supported APIs:
from coverage import CoverageData
data = CoverageData(".coverage")
data.read()
if not data.measured_files():
print("No data!")
Would it be better to have an empty .coverage always produce an empty .lcov?
That would probably be the most consistent approach, yes. However, the current check for missing data is probably there for a reason, I guess to prevent user errors?
What is it running? I don't know that we've encountered these kinds of scenarios before.
The code that leads to this is here: https://github.com/bazel-contrib/rules_python/blob/1.6.3/python/private/python_bootstrap_template.txt#L428-L459 (this has been changed at HEAD in the meantime, see https://github.com/bazel-contrib/rules_python/blob/ec1df016325f1ac5a949aa7db90b056f558eb6c4/python/private/stage2_bootstrap_template.py#L305-L366). I think the empty database is generated if none of the source directories in sources contain any code that's actually executed as part of the run.