From 1062d3c34c56401a89d5b4bc3205942d55bd57e0 Mon Sep 17 00:00:00 2001 From: Thomas Grainger Date: Tue, 1 Sep 2020 23:13:39 +0100 Subject: [PATCH] process path aliases in run --- coverage/control.py | 15 ++++++--------- coverage/files.py | 26 ++++++++++++++++++++++++-- coverage/inorout.py | 13 +++++++------ 3 files changed, 37 insertions(+), 17 deletions(-) diff --git a/coverage/control.py b/coverage/control.py index d60db2126..9637b0c27 100644 --- a/coverage/control.py +++ b/coverage/control.py @@ -678,15 +678,12 @@ def combine(self, data_paths=None, strict=False): self._post_init() self.get_data() - aliases = None - if self.config.paths: - aliases = PathAliases() - for paths in self.config.paths.values(): - result = paths[0] - for pattern in paths[1:]: - aliases.add(pattern, result) - - combine_parallel_data(self._data, aliases=aliases, data_paths=data_paths, strict=strict) + combine_parallel_data( + self._data, + aliases=PathAliases.configure(self.config), + data_paths=data_paths, + strict=strict, + ) def get_data(self): """Get the collected data. diff --git a/coverage/files.py b/coverage/files.py index 5c2ff1ace..43ce040bd 100644 --- a/coverage/files.py +++ b/coverage/files.py @@ -215,7 +215,8 @@ class TreeMatcher(object): somewhere in a subtree rooted at one of the directories. """ - def __init__(self, paths): + def __init__(self, paths, aliases=None): + self.aliases = aliases self.paths = list(paths) def __repr__(self): @@ -227,6 +228,9 @@ def info(self): def match(self, fpath): """Does `fpath` indicate a file in one of our trees?""" + if self.aliases is not None: + fpath = self.aliases.map(fpath) + for p in self.paths: if fpath.startswith(p): if fpath == p: @@ -268,7 +272,8 @@ def match(self, module_name): class FnmatchMatcher(object): """A matcher for files by file name pattern.""" - def __init__(self, pats): + def __init__(self, pats, aliases=None): + self.aliases = aliases self.pats = list(pats) self.re = fnmatches_to_regex(self.pats, case_insensitive=env.WINDOWS) @@ -281,6 +286,8 @@ def info(self): def match(self, fpath): """Does `fpath` match one of our file name patterns?""" + if self.aliases is not None: + fpath = self.aliases.map(fpath) return self.re.match(fpath) is not None @@ -408,6 +415,21 @@ def map(self, path): return path + @classmethod + def configure(cls, config): + paths = config.paths + if not paths: + return None + + aliases = PathAliases() + for paths in paths.values(): + result = paths[0] + for pattern in paths[1:]: + aliases.add(pattern, result) + return aliases + + + def find_python_files(dirname): """Yield all of the importable Python files in `dirname`, recursively. diff --git a/coverage/inorout.py b/coverage/inorout.py index ec5f2c1ac..3ee596bbd 100644 --- a/coverage/inorout.py +++ b/coverage/inorout.py @@ -17,7 +17,7 @@ from coverage.backward import code_object from coverage.disposition import FileDisposition, disposition_init from coverage.files import TreeMatcher, FnmatchMatcher, ModuleMatcher -from coverage.files import prep_patterns, find_python_files, canonical_filename +from coverage.files import prep_patterns, find_python_files, canonical_filename, PathAliases from coverage.misc import CoverageException from coverage.python import source_for_file, source_for_morf @@ -132,6 +132,7 @@ def __init__(self, warn, debug): def configure(self, config): """Apply the configuration to get ready for decision-time.""" + aliases = PathAliases.configure(config) for src in config.source or []: if os.path.isdir(src): self.source.append(canonical_filename(src)) @@ -186,7 +187,7 @@ def debug(msg): if self.source or self.source_pkgs: against = [] if self.source: - self.source_match = TreeMatcher(self.source) + self.source_match = TreeMatcher(self.source, aliases=aliases) against.append("trees {!r}".format(self.source_match)) if self.source_pkgs: self.source_pkgs_match = ModuleMatcher(self.source_pkgs) @@ -194,16 +195,16 @@ def debug(msg): debug("Source matching against " + " and ".join(against)) else: if self.cover_paths: - self.cover_match = TreeMatcher(self.cover_paths) + self.cover_match = TreeMatcher(self.cover_paths, aliases=aliases) debug("Coverage code matching: {!r}".format(self.cover_match)) if self.pylib_paths: - self.pylib_match = TreeMatcher(self.pylib_paths) + self.pylib_match = TreeMatcher(self.pylib_paths, aliases=aliases) debug("Python stdlib matching: {!r}".format(self.pylib_match)) if self.include: - self.include_match = FnmatchMatcher(self.include) + self.include_match = FnmatchMatcher(self.include, aliases=aliases) debug("Include matching: {!r}".format(self.include_match)) if self.omit: - self.omit_match = FnmatchMatcher(self.omit) + self.omit_match = FnmatchMatcher(self.omit, aliases=aliases) debug("Omit matching: {!r}".format(self.omit_match)) def should_trace(self, filename, frame=None):