pw_presubmit: Path filtering; callable _Check
- Use re.search to filter paths instead of re.fullmatch. ^ and $ can be
used to match the whole string.
- Filter paths using Path.as_posix() so that they are the same across
Windows, macOS, and Linux.
- Make _Check objects callable. That makes it possible to reuse
functions with @filter_paths and apply different filters.
Change-Id: I66e020aabe66c3f3ff50f167f54b28e2949b276f
diff --git a/pw_presubmit/py/pw_presubmit/tools.py b/pw_presubmit/py/pw_presubmit/tools.py
index 95a9639..c4c9ee1 100644
--- a/pw_presubmit/py/pw_presubmit/tools.py
+++ b/pw_presubmit/py/pw_presubmit/tools.py
@@ -517,14 +517,15 @@
paths: Sequence[Path]) -> Dict['_Check', Sequence[Path]]:
checks_to_paths: Dict[_Check, Sequence[Path]] = {}
+ str_paths = [path.as_posix() for path in paths]
+
for filt, checks in filter_to_checks.items():
exclude = [re.compile(exp) for exp in filt.exclude]
filtered_paths = tuple(
- path for path in paths
- if any(str(path).endswith(end)
- for end in filt.endswith) and not any(
- exp.fullmatch(str(path)) for exp in exclude))
+ Path(path) for path in str_paths
+ if any(path.endswith(end) for end in filt.endswith) and not any(
+ exp.search(path) for exp in exclude))
for check in checks:
if filtered_paths or check.always_run:
@@ -674,6 +675,14 @@
return _Result.PASS
+ def __call__(self, ctx: PresubmitContext, *args, **kwargs):
+ """Calling a _Check calls its underlying function directly.
+
+ This makes it possible to call functions wrapped by @filter_paths. The
+ prior filters are ignored, so new filters may be applied.
+ """
+ return self._check(ctx, *args, **kwargs)
+
def _ensure_is_valid_presubmit_check_function(check: Callable) -> None:
"""Checks if a Callable can be used as a presubmit check."""
@@ -702,6 +711,11 @@
always_run: bool = False):
"""Decorator for filtering the paths list for a presubmit check function.
+ Path filters only apply when the function is used as a presubmit check.
+ Filters are ignored when the functions are called directly. This makes it
+ possible to reuse functions wrapped in @filter_paths in other presubmit
+ checks, potentially with different path filtering rules.
+
Args:
endswith: str or iterable of path endings to include
exclude: regular expressions of paths to exclude