mirror of
https://github.com/thegeeklab/ansible-later.git
synced 2024-11-26 23:00:36 +00:00
105 lines
3.6 KiB
Python
105 lines
3.6 KiB
Python
|
# Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0
|
||
|
# For details: https://bitbucket.org/ned/coveragepy/src/default/NOTICE.txt
|
||
|
|
||
|
"""Reporter foundation for coverage.py."""
|
||
|
|
||
|
import os
|
||
|
import warnings
|
||
|
|
||
|
from coverage.files import prep_patterns, FnmatchMatcher
|
||
|
from coverage.misc import CoverageException, NoSource, NotPython, isolate_module
|
||
|
|
||
|
os = isolate_module(os)
|
||
|
|
||
|
|
||
|
class Reporter(object):
|
||
|
"""A base class for all reporters."""
|
||
|
|
||
|
def __init__(self, coverage, config):
|
||
|
"""Create a reporter.
|
||
|
|
||
|
`coverage` is the coverage instance. `config` is an instance of
|
||
|
CoverageConfig, for controlling all sorts of behavior.
|
||
|
|
||
|
"""
|
||
|
self.coverage = coverage
|
||
|
self.config = config
|
||
|
|
||
|
# The directory into which to place the report, used by some derived
|
||
|
# classes.
|
||
|
self.directory = None
|
||
|
|
||
|
# Our method find_file_reporters used to set an attribute that other
|
||
|
# code could read. That's been refactored away, but some third parties
|
||
|
# were using that attribute. We'll continue to support it in a noisy
|
||
|
# way for now.
|
||
|
self._file_reporters = []
|
||
|
|
||
|
@property
|
||
|
def file_reporters(self):
|
||
|
"""Keep .file_reporters working for private-grabbing tools."""
|
||
|
warnings.warn(
|
||
|
"Report.file_reporters will no longer be available in Coverage.py 4.2",
|
||
|
DeprecationWarning,
|
||
|
)
|
||
|
return self._file_reporters
|
||
|
|
||
|
def find_file_reporters(self, morfs):
|
||
|
"""Find the FileReporters we'll report on.
|
||
|
|
||
|
`morfs` is a list of modules or file names.
|
||
|
|
||
|
Returns a list of FileReporters.
|
||
|
|
||
|
"""
|
||
|
reporters = self.coverage._get_file_reporters(morfs)
|
||
|
|
||
|
if self.config.report_include:
|
||
|
matcher = FnmatchMatcher(prep_patterns(self.config.report_include))
|
||
|
reporters = [fr for fr in reporters if matcher.match(fr.filename)]
|
||
|
|
||
|
if self.config.report_omit:
|
||
|
matcher = FnmatchMatcher(prep_patterns(self.config.report_omit))
|
||
|
reporters = [fr for fr in reporters if not matcher.match(fr.filename)]
|
||
|
|
||
|
self._file_reporters = sorted(reporters)
|
||
|
return self._file_reporters
|
||
|
|
||
|
def report_files(self, report_fn, morfs, directory=None):
|
||
|
"""Run a reporting function on a number of morfs.
|
||
|
|
||
|
`report_fn` is called for each relative morf in `morfs`. It is called
|
||
|
as::
|
||
|
|
||
|
report_fn(file_reporter, analysis)
|
||
|
|
||
|
where `file_reporter` is the `FileReporter` for the morf, and
|
||
|
`analysis` is the `Analysis` for the morf.
|
||
|
|
||
|
"""
|
||
|
file_reporters = self.find_file_reporters(morfs)
|
||
|
|
||
|
if not file_reporters:
|
||
|
raise CoverageException("No data to report.")
|
||
|
|
||
|
self.directory = directory
|
||
|
if self.directory and not os.path.exists(self.directory):
|
||
|
os.makedirs(self.directory)
|
||
|
|
||
|
for fr in file_reporters:
|
||
|
try:
|
||
|
report_fn(fr, self.coverage._analyze(fr))
|
||
|
except NoSource:
|
||
|
if not self.config.ignore_errors:
|
||
|
raise
|
||
|
except NotPython:
|
||
|
# Only report errors for .py files, and only if we didn't
|
||
|
# explicitly suppress those errors.
|
||
|
# NotPython is only raised by PythonFileReporter, which has a
|
||
|
# should_be_python() method.
|
||
|
if fr.should_be_python():
|
||
|
if self.config.ignore_errors:
|
||
|
self.coverage._warn("Could not parse Python file {0}".format(fr.filename))
|
||
|
else:
|
||
|
raise
|