OLD | NEW |
(Empty) | |
| 1 """Reporter foundation for Coverage.""" |
| 2 |
| 3 import fnmatch, os |
| 4 from coverage.codeunit import code_unit_factory |
| 5 from coverage.files import prep_patterns |
| 6 from coverage.misc import CoverageException, NoSource, NotPython |
| 7 |
| 8 class Reporter(object): |
| 9 """A base class for all reporters.""" |
| 10 |
| 11 def __init__(self, coverage, config): |
| 12 """Create a reporter. |
| 13 |
| 14 `coverage` is the coverage instance. `config` is an instance of |
| 15 CoverageConfig, for controlling all sorts of behavior. |
| 16 |
| 17 """ |
| 18 self.coverage = coverage |
| 19 self.config = config |
| 20 |
| 21 # The code units to report on. Set by find_code_units. |
| 22 self.code_units = [] |
| 23 |
| 24 # The directory into which to place the report, used by some derived |
| 25 # classes. |
| 26 self.directory = None |
| 27 |
| 28 def find_code_units(self, morfs): |
| 29 """Find the code units we'll report on. |
| 30 |
| 31 `morfs` is a list of modules or filenames. |
| 32 |
| 33 """ |
| 34 morfs = morfs or self.coverage.data.measured_files() |
| 35 file_locator = self.coverage.file_locator |
| 36 self.code_units = code_unit_factory(morfs, file_locator) |
| 37 |
| 38 if self.config.include: |
| 39 patterns = prep_patterns(self.config.include) |
| 40 filtered = [] |
| 41 for cu in self.code_units: |
| 42 for pattern in patterns: |
| 43 if fnmatch.fnmatch(cu.filename, pattern): |
| 44 filtered.append(cu) |
| 45 break |
| 46 self.code_units = filtered |
| 47 |
| 48 if self.config.omit: |
| 49 patterns = prep_patterns(self.config.omit) |
| 50 filtered = [] |
| 51 for cu in self.code_units: |
| 52 for pattern in patterns: |
| 53 if fnmatch.fnmatch(cu.filename, pattern): |
| 54 break |
| 55 else: |
| 56 filtered.append(cu) |
| 57 self.code_units = filtered |
| 58 |
| 59 self.code_units.sort() |
| 60 |
| 61 def report_files(self, report_fn, morfs, directory=None): |
| 62 """Run a reporting function on a number of morfs. |
| 63 |
| 64 `report_fn` is called for each relative morf in `morfs`. It is called |
| 65 as:: |
| 66 |
| 67 report_fn(code_unit, analysis) |
| 68 |
| 69 where `code_unit` is the `CodeUnit` for the morf, and `analysis` is |
| 70 the `Analysis` for the morf. |
| 71 |
| 72 """ |
| 73 self.find_code_units(morfs) |
| 74 |
| 75 if not self.code_units: |
| 76 raise CoverageException("No data to report.") |
| 77 |
| 78 self.directory = directory |
| 79 if self.directory and not os.path.exists(self.directory): |
| 80 os.makedirs(self.directory) |
| 81 |
| 82 for cu in self.code_units: |
| 83 try: |
| 84 report_fn(cu, self.coverage._analyze(cu)) |
| 85 except NoSource: |
| 86 if not self.config.ignore_errors: |
| 87 raise |
| 88 except NotPython: |
| 89 # Only report errors for .py files, and only if we didn't |
| 90 # explicitly suppress those errors. |
| 91 if cu.should_be_python() and not self.config.ignore_errors: |
| 92 raise |
OLD | NEW |