Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 29 additions & 14 deletions scripts/codelensignore.py
Original file line number Diff line number Diff line change
Expand Up @@ -208,30 +208,45 @@
result = False
for is_neg, rx, anchored, dir_only in self._rules:
if dir_only:
# Match if rel == pat or rel.startswith(pat + '/')
# We achieve this by matching the pattern OR pattern + '/*'
# Use the regex against the path and any prefix path that
# ends at a separator.
# Simpler: check the rule against every prefix of rel.
matched = self._match_dir_prefix(rx, rel)
matched = self._match_dir_prefix(rx, rel, anchored)
else:
matched = bool(rx.match(rel))
if matched:
result = not is_neg
return result

@staticmethod
def _match_dir_prefix(rx: 're.Pattern', rel: str) -> bool:
"""True if *rel* OR any ancestor directory matches *rx*."""
# Check the full path first
def _match_dir_prefix(rx: 're.Pattern', rel: str, anchored: bool = True) -> bool:

Check failure on line 219 in scripts/codelensignore.py

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Refactor this function to reduce its Cognitive Complexity from 17 to the 15 allowed.

See more on https://sonarcloud.io/project/issues?id=Wolfvin_CodeLens&issues=AZ9frVevd-djrgqBbski&open=AZ9frVevd-djrgqBbski&pullRequest=285
"""True if *rel* is inside a directory matched by *rx*.

For an *anchored* pattern (``/target/``) only root-relative ancestor
directories count. For a *non-anchored* pattern (``target/`` — the
gitignore default) the directory may sit at ANY depth, so a whole path
segment matching the pattern is enough. Segment matching (not substring)
keeps ``build/`` from matching ``build-tools/`` (issue #271 / gitignore
backward-compat): ``src/target/debug/x`` is ignored by ``target/`` but
``build-tools/config`` is not ignored by ``build/``.
"""
# Check the full path first (handles patterns with wildcards/subpaths).
if rx.match(rel):
return True
# Then check every ancestor directory
parts = rel.split('/')
for i in range(1, len(parts)):
prefix = '/'.join(parts[:i])
if rx.match(prefix):
return True
if anchored:
# Root-anchored: only ancestor paths measured from the root.
for i in range(1, len(parts)):
if rx.match('/'.join(parts[:i])):
return True
else:
# Non-anchored: the pattern (single- or multi-segment) may sit at
# any depth → test every sub-path that both starts and ends on a
# segment boundary. This matches `target/` against `src/target/x`
# and `build/keep/` against `build/keep/x`, while whole-segment
# boundaries keep `build/` from matching `build-tools/`.
n = len(parts)
for i in range(n):
for j in range(i + 1, n + 1):
if rx.match('/'.join(parts[i:j])):
return True
return False


Expand Down
Loading